diff --git a/aws-b2bi-capability/.rpdk-config b/aws-b2bi-capability/.rpdk-config index 55bc8a7..f6d89f5 100644 --- a/aws-b2bi-capability/.rpdk-config +++ b/aws-b2bi-capability/.rpdk-config @@ -26,5 +26,7 @@ "protocolVersion": "2.0.0" }, "logProcessorEnabled": "true", - "executableEntrypoint": "software.amazon.b2bi.capability.HandlerWrapperExecutable" + "executableEntrypoint": "software.amazon.b2bi.capability.HandlerWrapperExecutable", + "contractSettings": {}, + "canarySettings": {} } diff --git a/aws-b2bi-capability/aws-b2bi-capability.json b/aws-b2bi-capability/aws-b2bi-capability.json index b2e2c04..d4aad17 100644 --- a/aws-b2bi-capability/aws-b2bi-capability.json +++ b/aws-b2bi-capability/aws-b2bi-capability.json @@ -19,6 +19,13 @@ } ] }, + "CapabilityDirection": { + "type": "string", + "enum": [ + "INBOUND", + "OUTBOUND" + ] + }, "CapabilityType": { "type": "string", "enum": [ @@ -28,6 +35,9 @@ "EdiConfiguration": { "type": "object", "properties": { + "CapabilityDirection": { + "$ref": "#/definitions/CapabilityDirection" + }, "Type": { "$ref": "#/definitions/EdiType" }, @@ -322,7 +332,12 @@ "tagOnCreate": true, "tagProperty": "/properties/Tags", "tagUpdatable": true, - "taggable": true + "taggable": true, + "permissions": [ + "b2bi:ListTagsForResource", + "b2bi:TagResource", + "b2bi:UntagResource" + ] }, "additionalProperties": false } diff --git a/aws-b2bi-capability/docs/ediconfiguration.md b/aws-b2bi-capability/docs/ediconfiguration.md index 4432e42..9035d2e 100644 --- a/aws-b2bi-capability/docs/ediconfiguration.md +++ b/aws-b2bi-capability/docs/ediconfiguration.md @@ -8,6 +8,7 @@ To declare this entity in your AWS CloudFormation template, use the following sy
 {
+    "CapabilityDirection" : String,
     "Type" : EdiType,
     "InputLocation" : S3Location,
     "OutputLocation" : S3Location,
@@ -18,6 +19,7 @@ To declare this entity in your AWS CloudFormation template, use the following sy
 ### YAML
 
 
+CapabilityDirection: String
 Type: EdiType
 InputLocation: S3Location
 OutputLocation: S3Location
@@ -26,6 +28,16 @@ To declare this entity in your AWS CloudFormation template, use the following sy
 
 ## Properties
 
+#### CapabilityDirection
+
+_Required_: No
+
+_Type_: String
+
+_Allowed Values_: INBOUND | OUTBOUND
+
+_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
+
 #### Type
 
 _Required_: Yes
diff --git a/aws-b2bi-capability/pom.xml b/aws-b2bi-capability/pom.xml
index 83b5370..2ef1cf0 100644
--- a/aws-b2bi-capability/pom.xml
+++ b/aws-b2bi-capability/pom.xml
@@ -31,25 +31,25 @@
         
             software.amazon.awssdk
             b2bi
-            2.24.5
+            2.28.14
         
         
         
             software.amazon.awssdk
             sdk-core
-            2.24.5
+            2.28.14
         
         
         
             software.amazon.awssdk
             aws-core
-            2.24.5
+            2.28.14
         
         
         
             software.amazon.awssdk
             utils
-            2.24.5
+            2.28.14
         
         
         
diff --git a/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/ClientBuilder.kt b/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/ClientBuilder.kt
index 12cdaf3..b5aef76 100644
--- a/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/ClientBuilder.kt
+++ b/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/ClientBuilder.kt
@@ -7,4 +7,4 @@ object ClientBuilder {
     fun getClient(): B2BiClient = B2BiClient.builder()
         .httpClient(LambdaWrapper.HTTP_CLIENT)
         .build()
-}
\ No newline at end of file
+}
diff --git a/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/CreateHandler.kt b/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/CreateHandler.kt
index 4f43720..ab16419 100644
--- a/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/CreateHandler.kt
+++ b/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/CreateHandler.kt
@@ -63,4 +63,4 @@ class CreateHandler : BaseHandlerStd() {
     companion object {
         private const val OPERATION = "AWS-B2BI-Capability::Create"
     }
-}
\ No newline at end of file
+}
diff --git a/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/TagHelper.kt b/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/TagHelper.kt
index 43d92ac..f16cf66 100644
--- a/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/TagHelper.kt
+++ b/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/TagHelper.kt
@@ -40,6 +40,7 @@ object TagHelper {
     fun getPreviouslyAttachedTags(handlerRequest: ResourceHandlerRequest): Map {
         return getTags(
             handlerRequest.previousResourceTags,
+            handlerRequest.systemTags,
             convertToMap(handlerRequest.previousResourceState.tags)
         )
     }
@@ -59,6 +60,7 @@ object TagHelper {
     fun getNewDesiredTags(handlerRequest: ResourceHandlerRequest): Map {
         return getTags(
             handlerRequest.desiredResourceTags,
+            handlerRequest.systemTags,
             convertToMap(handlerRequest.desiredResourceState.tags)
         )
     }
@@ -106,14 +108,19 @@ object TagHelper {
         addedTags: Map,
         logger: Logger
     ): ProgressEvent {
-        return proxy.initiate(TAG_OPERATION, proxyClient, resourceModel, callbackContext)
-            .translateToServiceRequest { model -> Translator.translateToTagResourceRequest(model, addedTags) }
-            .makeServiceCall { request, client ->
-                val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::tagResource)
-                logger.log("Successfully tagged ${ResourceModel.TYPE_NAME} ${resourceModel.capabilityId}")
-                response
-            }
-            .progress()
+        return if (addedTags.isNotEmpty()) {
+            proxy.initiate(TAG_OPERATION, proxyClient, resourceModel, callbackContext)
+                .translateToServiceRequest { model -> Translator.translateToTagResourceRequest(model, addedTags) }
+                .makeServiceCall { request, client ->
+                    val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::tagResource)
+                    logger.log("Successfully tagged ${ResourceModel.TYPE_NAME} ${resourceModel.capabilityId}")
+                    response
+                }
+                .progress()
+        } else {
+
+            ProgressEvent.progress(resourceModel, callbackContext)
+        }
     }
 
     /**
@@ -129,14 +136,18 @@ object TagHelper {
         removedTags: Set,
         logger: Logger
     ): ProgressEvent {
-        return proxy.initiate(UNTAG_OPERATION, proxyClient, resourceModel, callbackContext)
-            .translateToServiceRequest { model -> Translator.translateToUntagResourceRequest(model, removedTags) }
-            .makeServiceCall { request, client ->
-                val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::untagResource)
-                logger.log("Successfully untagged ${ResourceModel.TYPE_NAME} ${resourceModel.capabilityId}")
-                response
-            }
-            .progress()
+        return if (removedTags.isNotEmpty()) {
+            proxy.initiate(UNTAG_OPERATION, proxyClient, resourceModel, callbackContext)
+                .translateToServiceRequest { model -> Translator.translateToUntagResourceRequest(model, removedTags) }
+                .makeServiceCall { request, client ->
+                    val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::untagResource)
+                    logger.log("Successfully untagged ${ResourceModel.TYPE_NAME} ${resourceModel.capabilityId}")
+                    response
+                }
+                .progress()
+        } else {
+            ProgressEvent.progress(resourceModel, callbackContext)
+        }
     }
 
     /**
@@ -217,4 +228,4 @@ object TagHelper {
     fun SdkTag.toResourceTag(): ResourceTag {
         return ResourceTag.builder().key(this.key()).value(this.value()).build()
     }
-}
\ No newline at end of file
+}
diff --git a/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/Translator.kt b/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/Translator.kt
index 55b40e9..26c3a1e 100644
--- a/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/Translator.kt
+++ b/aws-b2bi-capability/src/main/kotlin/software/amazon/b2bi/capability/Translator.kt
@@ -1,8 +1,5 @@
 package software.amazon.b2bi.capability
 
-import com.google.common.collect.Lists
-import software.amazon.awssdk.awscore.AwsRequest
-import software.amazon.awssdk.awscore.AwsResponse
 import software.amazon.awssdk.awscore.exception.AwsServiceException
 import software.amazon.awssdk.services.b2bi.model.AccessDeniedException
 import software.amazon.awssdk.services.b2bi.model.ConflictException
@@ -31,9 +28,6 @@ import software.amazon.cloudformation.exceptions.CfnServiceInternalErrorExceptio
 import software.amazon.cloudformation.exceptions.CfnServiceLimitExceededException
 import software.amazon.cloudformation.exceptions.CfnThrottlingException
 import java.time.Instant
-import java.util.*
-import java.util.stream.Collectors
-import java.util.stream.Stream
 import software.amazon.awssdk.services.b2bi.model.S3Location as SdkS3Location
 import software.amazon.b2bi.capability.S3Location as ResourceS3Location
 import software.amazon.awssdk.services.b2bi.model.CapabilityConfiguration as SdkCapabilityConfiguration
@@ -132,9 +126,7 @@ object Translator {
      */
     fun translateToListRequest(nextToken: String?): ListCapabilitiesRequest {
         return ListCapabilitiesRequest.builder()
-            .apply {
-                nextToken?.let { nextToken(it) }
-            }
+            .apply { nextToken?.let { nextToken(it) } }
             .build()
     }
 
@@ -200,53 +192,47 @@ object Translator {
         else -> CfnGeneralServiceException(this)
     }
 
-    fun ResourceS3Location.toSdkS3Location(): SdkS3Location {
-        return SdkS3Location.builder().bucketName(this.bucketName).key(this.key).build()
-    }
-
-    fun SdkS3Location.toResourceS3Location(): ResourceS3Location {
-        return ResourceS3Location.builder().bucketName(this.bucketName()).key(this.key()).build()
-    }
-
-    fun ResourceCapabilityConfiguration.toSdkCapabilityConfiguration(): SdkCapabilityConfiguration {
-        return SdkCapabilityConfiguration.builder().edi(this.edi.toSdkEdiConfiguration()).build()
-    }
+    fun ResourceCapabilityConfiguration.toSdkCapabilityConfiguration(): SdkCapabilityConfiguration =
+        SdkCapabilityConfiguration.builder().edi(this.edi.toSdkEdiConfiguration()).build()
 
     fun ResourceEdiConfiguration.toSdkEdiConfiguration(): SdkEdiConfiguration {
         return SdkEdiConfiguration.builder()
             .type(this.type.toSdkEdiType())
+            .capabilityDirection(this.capabilityDirection)
             .inputLocation(this.inputLocation.toSdkS3Location())
             .outputLocation(this.outputLocation.toSdkS3Location())
             .transformerId(this.transformerId)
             .build()
     }
 
-    fun ResourceEdiType.toSdkEdiType(): SdkEdiType {
-        return SdkEdiType.builder().x12Details(this.x12Details.toSdkX12Details()).build()
-    }
+    fun ResourceEdiType.toSdkEdiType(): SdkEdiType =
+        SdkEdiType.builder().x12Details(this.x12Details.toSdkX12Details()).build()
 
-    fun ResourceX12Details.toSdkX12Details(): SdkX12Details {
-        return SdkX12Details.builder().transactionSet(this.transactionSet).version(this.version).build()
-    }
+    fun ResourceX12Details.toSdkX12Details(): SdkX12Details =
+        SdkX12Details.builder().transactionSet(this.transactionSet).version(this.version).build()
 
-    fun SdkCapabilityConfiguration.toResourceCapabilityConfiguration(): ResourceCapabilityConfiguration {
-        return ResourceCapabilityConfiguration.builder().edi(this.edi().toResourceEdiConfiguration()).build()
-    }
+    fun ResourceS3Location.toSdkS3Location(): SdkS3Location =
+        SdkS3Location.builder().bucketName(this.bucketName).key(this.key).build()
+
+    fun SdkCapabilityConfiguration.toResourceCapabilityConfiguration(): ResourceCapabilityConfiguration =
+        ResourceCapabilityConfiguration.builder().edi(this.edi().toResourceEdiConfiguration()).build()
 
     fun SdkEdiConfiguration.toResourceEdiConfiguration(): ResourceEdiConfiguration {
         return ResourceEdiConfiguration.builder()
             .type(this.type().toResourceEdiType())
+            .capabilityDirection(this.capabilityDirectionAsString())
             .inputLocation(this.inputLocation().toResourceS3Location())
             .outputLocation(this.outputLocation().toResourceS3Location())
             .transformerId(this.transformerId())
             .build()
     }
 
-    fun SdkEdiType.toResourceEdiType(): ResourceEdiType {
-        return ResourceEdiType.builder().x12Details(this.x12Details().toResourceX12Details()).build()
-    }
+    fun SdkEdiType.toResourceEdiType(): ResourceEdiType =
+        ResourceEdiType.builder().x12Details(this.x12Details().toResourceX12Details()).build()
 
-    fun SdkX12Details.toResourceX12Details(): ResourceX12Details {
-        return ResourceX12Details.builder().transactionSet(this.transactionSetAsString()).version(this.versionAsString()).build()
-    }
+    fun SdkX12Details.toResourceX12Details(): ResourceX12Details =
+        ResourceX12Details.builder().transactionSet(this.transactionSetAsString()).version(this.versionAsString()).build()
+
+    fun SdkS3Location.toResourceS3Location(): ResourceS3Location =
+        ResourceS3Location.builder().bucketName(this.bucketName()).key(this.key()).build()
 }
diff --git a/aws-b2bi-partnership/.rpdk-config b/aws-b2bi-partnership/.rpdk-config
index 9fb4ff5..fe19093 100644
--- a/aws-b2bi-partnership/.rpdk-config
+++ b/aws-b2bi-partnership/.rpdk-config
@@ -26,5 +26,7 @@
         "protocolVersion": "2.0.0"
     },
     "logProcessorEnabled": "true",
-    "executableEntrypoint": "software.amazon.b2bi.partnership.HandlerWrapperExecutable"
+    "executableEntrypoint": "software.amazon.b2bi.partnership.HandlerWrapperExecutable",
+    "contractSettings": {},
+    "canarySettings": {}
 }
diff --git a/aws-b2bi-partnership/aws-b2bi-partnership.json b/aws-b2bi-partnership/aws-b2bi-partnership.json
index 8ed5e7c..1c07fba 100644
--- a/aws-b2bi-partnership/aws-b2bi-partnership.json
+++ b/aws-b2bi-partnership/aws-b2bi-partnership.json
@@ -2,6 +2,32 @@
   "typeName": "AWS::B2BI::Partnership",
   "description": "Definition of AWS::B2BI::Partnership Resource Type",
   "definitions": {
+    "CapabilityOptions": {
+      "type": "object",
+      "properties": {
+        "OutboundEdi": {
+          "$ref": "#/definitions/OutboundEdiOptions"
+        }
+      },
+      "additionalProperties": false
+    },
+    "OutboundEdiOptions": {
+      "oneOf": [
+        {
+          "type": "object",
+          "title": "X12",
+          "properties": {
+            "X12": {
+              "$ref": "#/definitions/X12Envelope"
+            }
+          },
+          "required": [
+            "X12"
+          ],
+          "additionalProperties": false
+        }
+      ]
+    },
     "Tag": {
       "type": "object",
       "properties": {
@@ -21,6 +47,128 @@
         "Value"
       ],
       "additionalProperties": false
+    },
+    "X12Delimiters": {
+      "type": "object",
+      "properties": {
+        "ComponentSeparator": {
+          "type": "string",
+          "maxLength": 1,
+          "minLength": 1,
+          "pattern": "^[!&'()*+,\\-./:;?=%@\\[\\]_{}|<>~^`\"]$"
+        },
+        "DataElementSeparator": {
+          "type": "string",
+          "maxLength": 1,
+          "minLength": 1,
+          "pattern": "^[!&'()*+,\\-./:;?=%@\\[\\]_{}|<>~^`\"]$"
+        },
+        "SegmentTerminator": {
+          "type": "string",
+          "maxLength": 1,
+          "minLength": 1,
+          "pattern": "^[!&'()*+,\\-./:;?=%@\\[\\]_{}|<>~^`\"]$"
+        }
+      },
+      "additionalProperties": false
+    },
+    "X12Envelope": {
+      "type": "object",
+      "properties": {
+        "Common": {
+          "$ref": "#/definitions/X12OutboundEdiHeaders"
+        }
+      },
+      "additionalProperties": false
+    },
+    "X12FunctionalGroupHeaders": {
+      "type": "object",
+      "properties": {
+        "ApplicationSenderCode": {
+          "type": "string",
+          "maxLength": 15,
+          "minLength": 2,
+          "pattern": "^[a-zA-Z0-9]*$"
+        },
+        "ApplicationReceiverCode": {
+          "type": "string",
+          "maxLength": 15,
+          "minLength": 2,
+          "pattern": "^[a-zA-Z0-9]*$"
+        },
+        "ResponsibleAgencyCode": {
+          "type": "string",
+          "maxLength": 2,
+          "minLength": 1,
+          "pattern": "^[a-zA-Z0-9]*$"
+        }
+      },
+      "additionalProperties": false
+    },
+    "X12InterchangeControlHeaders": {
+      "type": "object",
+      "properties": {
+        "SenderIdQualifier": {
+          "type": "string",
+          "maxLength": 2,
+          "minLength": 2,
+          "pattern": "^[a-zA-Z0-9]*$"
+        },
+        "SenderId": {
+          "type": "string",
+          "maxLength": 15,
+          "minLength": 15,
+          "pattern": "^[a-zA-Z0-9]*$"
+        },
+        "ReceiverIdQualifier": {
+          "type": "string",
+          "maxLength": 2,
+          "minLength": 2,
+          "pattern": "^[a-zA-Z0-9]*$"
+        },
+        "ReceiverId": {
+          "type": "string",
+          "maxLength": 15,
+          "minLength": 15,
+          "pattern": "^[a-zA-Z0-9]*$"
+        },
+        "RepetitionSeparator": {
+          "type": "string",
+          "maxLength": 1,
+          "minLength": 1
+        },
+        "AcknowledgmentRequestedCode": {
+          "type": "string",
+          "maxLength": 1,
+          "minLength": 1,
+          "pattern": "^[a-zA-Z0-9]*$"
+        },
+        "UsageIndicatorCode": {
+          "type": "string",
+          "maxLength": 1,
+          "minLength": 1,
+          "pattern": "^[a-zA-Z0-9]*$"
+        }
+      },
+      "additionalProperties": false
+    },
+    "X12OutboundEdiHeaders": {
+      "type": "object",
+      "properties": {
+        "InterchangeControlHeaders": {
+          "$ref": "#/definitions/X12InterchangeControlHeaders"
+        },
+        "FunctionalGroupHeaders": {
+          "$ref": "#/definitions/X12FunctionalGroupHeaders"
+        },
+        "Delimiters": {
+          "$ref": "#/definitions/X12Delimiters"
+        },
+        "ValidateEdi": {
+          "type": "boolean"
+        }
+      },
+      "additionalProperties": false
     }
   },
   "properties": {
@@ -33,6 +181,9 @@
         "pattern": "^[a-zA-Z0-9_-]+$"
       }
     },
+    "CapabilityOptions": {
+      "$ref": "#/definitions/CapabilityOptions"
+    },
     "CreatedAt": {
       "type": "string",
       "format": "date-time"
@@ -148,7 +299,12 @@
     "tagOnCreate": true,
     "tagProperty": "/properties/Tags",
     "tagUpdatable": true,
-    "taggable": true
+    "taggable": true,
+    "permissions": [
+      "b2bi:ListTagsForResource",
+      "b2bi:TagResource",
+      "b2bi:UntagResource"
+    ]
   },
   "additionalProperties": false
 }
diff --git a/aws-b2bi-partnership/docs/README.md b/aws-b2bi-partnership/docs/README.md
index 789cdc1..e9fa5d3 100644
--- a/aws-b2bi-partnership/docs/README.md
+++ b/aws-b2bi-partnership/docs/README.md
@@ -13,6 +13,7 @@ To declare this entity in your AWS CloudFormation template, use the following sy
     "Type" : "AWS::B2BI::Partnership",
     "Properties" : {
         "Capabilities" : [ String, ... ],
+        "CapabilityOptions" : CapabilityOptions,
         "Email" : String,
         "Name" : String,
         "Phone" : String,
@@ -29,6 +30,7 @@ Type: AWS::B2BI::Partnership
 Properties:
     Capabilities: 
       - String
+    CapabilityOptions: CapabilityOptions
     Email: String
     Name: String
     Phone: String
@@ -47,6 +49,14 @@ _Type_: List of String
 
 _Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
 
+#### CapabilityOptions
+
+_Required_: No
+
+_Type_: CapabilityOptions
+
+_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)
+
 #### Email
 
 _Required_: Yes
diff --git a/aws-b2bi-partnership/docs/capabilityoptions.md b/aws-b2bi-partnership/docs/capabilityoptions.md
new file mode 100644
index 0000000..82ae1d8
--- /dev/null
+++ b/aws-b2bi-partnership/docs/capabilityoptions.md
@@ -0,0 +1,30 @@
+# AWS::B2BI::Partnership CapabilityOptions
+
+## Syntax
+
+To declare this entity in your AWS CloudFormation template, use the following syntax:
+
+### JSON
+
+
+{
+    "OutboundEdi" : OutboundEdiOptions
+}
+
+ +### YAML + +
+OutboundEdi: OutboundEdiOptions
+
+ +## Properties + +#### OutboundEdi + +_Required_: No + +_Type_: OutboundEdiOptions + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-partnership/docs/outboundedioptions.md b/aws-b2bi-partnership/docs/outboundedioptions.md new file mode 100644 index 0000000..244788e --- /dev/null +++ b/aws-b2bi-partnership/docs/outboundedioptions.md @@ -0,0 +1,30 @@ +# AWS::B2BI::Partnership OutboundEdiOptions + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "X12" : X12Envelope
+}
+
+ +### YAML + +
+X12: X12Envelope
+
+ +## Properties + +#### X12 + +_Required_: Yes + +_Type_: X12Envelope + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-partnership/docs/x12delimiters.md b/aws-b2bi-partnership/docs/x12delimiters.md new file mode 100644 index 0000000..2c06bc0 --- /dev/null +++ b/aws-b2bi-partnership/docs/x12delimiters.md @@ -0,0 +1,68 @@ +# AWS::B2BI::Partnership X12Delimiters + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "ComponentSeparator" : String,
+    "DataElementSeparator" : String,
+    "SegmentTerminator" : String
+}
+
+ +### YAML + +
+ComponentSeparator: String
+DataElementSeparator: String
+SegmentTerminator: String
+
+ +## Properties + +#### ComponentSeparator + +_Required_: No + +_Type_: String + +_Minimum Length_: 1 + +_Maximum Length_: 1 + +_Pattern_: ^[!&'()*+,\-./:;?=%@\[\]_{}|<>~^`"]$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### DataElementSeparator + +_Required_: No + +_Type_: String + +_Minimum Length_: 1 + +_Maximum Length_: 1 + +_Pattern_: ^[!&'()*+,\-./:;?=%@\[\]_{}|<>~^`"]$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### SegmentTerminator + +_Required_: No + +_Type_: String + +_Minimum Length_: 1 + +_Maximum Length_: 1 + +_Pattern_: ^[!&'()*+,\-./:;?=%@\[\]_{}|<>~^`"]$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-partnership/docs/x12envelope.md b/aws-b2bi-partnership/docs/x12envelope.md new file mode 100644 index 0000000..a938bba --- /dev/null +++ b/aws-b2bi-partnership/docs/x12envelope.md @@ -0,0 +1,30 @@ +# AWS::B2BI::Partnership X12Envelope + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "Common" : X12OutboundEdiHeaders
+}
+
+ +### YAML + +
+Common: X12OutboundEdiHeaders
+
+ +## Properties + +#### Common + +_Required_: No + +_Type_: X12OutboundEdiHeaders + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-partnership/docs/x12functionalgroupheaders.md b/aws-b2bi-partnership/docs/x12functionalgroupheaders.md new file mode 100644 index 0000000..bbe9c2f --- /dev/null +++ b/aws-b2bi-partnership/docs/x12functionalgroupheaders.md @@ -0,0 +1,68 @@ +# AWS::B2BI::Partnership X12FunctionalGroupHeaders + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "ApplicationSenderCode" : String,
+    "ApplicationReceiverCode" : String,
+    "ResponsibleAgencyCode" : String
+}
+
+ +### YAML + +
+ApplicationSenderCode: String
+ApplicationReceiverCode: String
+ResponsibleAgencyCode: String
+
+ +## Properties + +#### ApplicationSenderCode + +_Required_: No + +_Type_: String + +_Minimum Length_: 2 + +_Maximum Length_: 15 + +_Pattern_: ^[a-zA-Z0-9]*$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### ApplicationReceiverCode + +_Required_: No + +_Type_: String + +_Minimum Length_: 2 + +_Maximum Length_: 15 + +_Pattern_: ^[a-zA-Z0-9]*$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### ResponsibleAgencyCode + +_Required_: No + +_Type_: String + +_Minimum Length_: 1 + +_Maximum Length_: 2 + +_Pattern_: ^[a-zA-Z0-9]*$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-partnership/docs/x12interchangecontrolheaders.md b/aws-b2bi-partnership/docs/x12interchangecontrolheaders.md new file mode 100644 index 0000000..892be83 --- /dev/null +++ b/aws-b2bi-partnership/docs/x12interchangecontrolheaders.md @@ -0,0 +1,130 @@ +# AWS::B2BI::Partnership X12InterchangeControlHeaders + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "SenderIdQualifier" : String,
+    "SenderId" : String,
+    "ReceiverIdQualifier" : String,
+    "ReceiverId" : String,
+    "RepetitionSeparator" : String,
+    "AcknowledgmentRequestedCode" : String,
+    "UsageIndicatorCode" : String
+}
+
+ +### YAML + +
+SenderIdQualifier: String
+SenderId: String
+ReceiverIdQualifier: String
+ReceiverId: String
+RepetitionSeparator: String
+AcknowledgmentRequestedCode: String
+UsageIndicatorCode: String
+
+ +## Properties + +#### SenderIdQualifier + +_Required_: No + +_Type_: String + +_Minimum Length_: 2 + +_Maximum Length_: 2 + +_Pattern_: ^[a-zA-Z0-9]*$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### SenderId + +_Required_: No + +_Type_: String + +_Minimum Length_: 15 + +_Maximum Length_: 15 + +_Pattern_: ^[a-zA-Z0-9]*$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### ReceiverIdQualifier + +_Required_: No + +_Type_: String + +_Minimum Length_: 2 + +_Maximum Length_: 2 + +_Pattern_: ^[a-zA-Z0-9]*$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### ReceiverId + +_Required_: No + +_Type_: String + +_Minimum Length_: 15 + +_Maximum Length_: 15 + +_Pattern_: ^[a-zA-Z0-9]*$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### RepetitionSeparator + +_Required_: No + +_Type_: String + +_Minimum Length_: 1 + +_Maximum Length_: 1 + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### AcknowledgmentRequestedCode + +_Required_: No + +_Type_: String + +_Minimum Length_: 1 + +_Maximum Length_: 1 + +_Pattern_: ^[a-zA-Z0-9]*$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### UsageIndicatorCode + +_Required_: No + +_Type_: String + +_Minimum Length_: 1 + +_Maximum Length_: 1 + +_Pattern_: ^[a-zA-Z0-9]*$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-partnership/docs/x12outboundediheaders.md b/aws-b2bi-partnership/docs/x12outboundediheaders.md new file mode 100644 index 0000000..101635b --- /dev/null +++ b/aws-b2bi-partnership/docs/x12outboundediheaders.md @@ -0,0 +1,60 @@ +# AWS::B2BI::Partnership X12OutboundEdiHeaders + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "InterchangeControlHeaders" : X12InterchangeControlHeaders,
+    "FunctionalGroupHeaders" : X12FunctionalGroupHeaders,
+    "Delimiters" : X12Delimiters,
+    "ValidateEdi" : Boolean
+}
+
+ +### YAML + +
+InterchangeControlHeaders: X12InterchangeControlHeaders
+FunctionalGroupHeaders: X12FunctionalGroupHeaders
+Delimiters: X12Delimiters
+ValidateEdi: Boolean
+
+ +## Properties + +#### InterchangeControlHeaders + +_Required_: No + +_Type_: X12InterchangeControlHeaders + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### FunctionalGroupHeaders + +_Required_: No + +_Type_: X12FunctionalGroupHeaders + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### Delimiters + +_Required_: No + +_Type_: X12Delimiters + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### ValidateEdi + +_Required_: No + +_Type_: Boolean + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-partnership/pom.xml b/aws-b2bi-partnership/pom.xml index faf3c12..b38a818 100644 --- a/aws-b2bi-partnership/pom.xml +++ b/aws-b2bi-partnership/pom.xml @@ -31,25 +31,25 @@ software.amazon.awssdk b2bi - 2.24.5 + 2.28.14 software.amazon.awssdk sdk-core - 2.24.5 + 2.28.14 software.amazon.awssdk aws-core - 2.24.5 + 2.28.14 software.amazon.awssdk utils - 2.24.5 + 2.28.14 diff --git a/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/ReadHandler.kt b/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/ReadHandler.kt index 4f7f640..f354870 100644 --- a/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/ReadHandler.kt +++ b/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/ReadHandler.kt @@ -62,6 +62,7 @@ class ReadHandler : BaseHandlerStd() { email = readResponseResourceModel.email phone = readResponseResourceModel.phone capabilities = readResponseResourceModel.capabilities + capabilityOptions = readResponseResourceModel.capabilityOptions tradingPartnerId = readResponseResourceModel.tradingPartnerId createdAt = readResponseResourceModel.createdAt modifiedAt = readResponseResourceModel.modifiedAt diff --git a/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/TagHelper.kt b/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/TagHelper.kt index 4378c8b..f24568e 100644 --- a/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/TagHelper.kt +++ b/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/TagHelper.kt @@ -40,6 +40,7 @@ object TagHelper { fun getPreviouslyAttachedTags(handlerRequest: ResourceHandlerRequest): Map { return getTags( handlerRequest.previousResourceTags, + handlerRequest.previousSystemTags, convertToMap(handlerRequest.previousResourceState.tags) ) } @@ -59,6 +60,7 @@ object TagHelper { fun getNewDesiredTags(handlerRequest: ResourceHandlerRequest): Map { return getTags( handlerRequest.desiredResourceTags, + handlerRequest.systemTags, convertToMap(handlerRequest.desiredResourceState.tags) ) } @@ -106,14 +108,18 @@ object TagHelper { addedTags: Map, logger: Logger ): ProgressEvent { - return proxy.initiate(TAG_OPERATION, proxyClient, resourceModel, callbackContext) - .translateToServiceRequest { model -> Translator.translateToTagResourceRequest(model, addedTags) } - .makeServiceCall { request, client -> - val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::tagResource) - logger.log("Successfully tagged ${ResourceModel.TYPE_NAME} ${resourceModel.partnershipId}") - response - } - .progress() + return if (addedTags.isNotEmpty()) { + proxy.initiate(TAG_OPERATION, proxyClient, resourceModel, callbackContext) + .translateToServiceRequest { model -> Translator.translateToTagResourceRequest(model, addedTags) } + .makeServiceCall { request, client -> + val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::tagResource) + logger.log("Successfully tagged ${ResourceModel.TYPE_NAME} ${resourceModel.partnershipId}") + response + } + .progress() + } else { + ProgressEvent.progress(resourceModel, callbackContext) + } } /** @@ -129,14 +135,18 @@ object TagHelper { removedTags: Set, logger: Logger ): ProgressEvent { - return proxy.initiate(UNTAG_OPERATION, proxyClient, resourceModel, callbackContext) - .translateToServiceRequest { model -> Translator.translateToUntagResourceRequest(model, removedTags) } - .makeServiceCall { request, client -> - val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::untagResource) - logger.log("Successfully untagged ${ResourceModel.TYPE_NAME} ${resourceModel.partnershipId}") - response - } - .progress() + return if (removedTags.isNotEmpty()) { + proxy.initiate(UNTAG_OPERATION, proxyClient, resourceModel, callbackContext) + .translateToServiceRequest { model -> Translator.translateToUntagResourceRequest(model, removedTags) } + .makeServiceCall { request, client -> + val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::untagResource) + logger.log("Successfully untagged ${ResourceModel.TYPE_NAME} ${resourceModel.partnershipId}") + response + } + .progress() + } else { + ProgressEvent.progress(resourceModel, callbackContext) + } } /** @@ -217,4 +227,4 @@ object TagHelper { fun SdkTag.toResourceTag(): ResourceTag { return ResourceTag.builder().key(this.key()).value(this.value()).build() } -} \ No newline at end of file +} diff --git a/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/Translator.kt b/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/Translator.kt index 7605c71..c78a058 100644 --- a/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/Translator.kt +++ b/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/Translator.kt @@ -1,19 +1,17 @@ package software.amazon.b2bi.partnership -import com.google.common.collect.Lists -import software.amazon.awssdk.awscore.AwsRequest -import software.amazon.awssdk.awscore.AwsResponse import software.amazon.awssdk.awscore.exception.AwsServiceException import software.amazon.awssdk.services.b2bi.model.AccessDeniedException +import software.amazon.awssdk.services.b2bi.model.CapabilityOptions as SdkCapabilityOptions import software.amazon.awssdk.services.b2bi.model.ConflictException import software.amazon.awssdk.services.b2bi.model.CreatePartnershipRequest -import software.amazon.awssdk.services.b2bi.model.DeleteCapabilityRequest import software.amazon.awssdk.services.b2bi.model.DeletePartnershipRequest import software.amazon.awssdk.services.b2bi.model.GetPartnershipRequest import software.amazon.awssdk.services.b2bi.model.GetPartnershipResponse import software.amazon.awssdk.services.b2bi.model.InternalServerException import software.amazon.awssdk.services.b2bi.model.ListPartnershipsRequest import software.amazon.awssdk.services.b2bi.model.ListPartnershipsResponse +import software.amazon.awssdk.services.b2bi.model.OutboundEdiOptions as SdkOutboundEdiOptions import software.amazon.awssdk.services.b2bi.model.ResourceNotFoundException import software.amazon.awssdk.services.b2bi.model.ServiceQuotaExceededException import software.amazon.awssdk.services.b2bi.model.TagResourceRequest @@ -21,7 +19,19 @@ import software.amazon.awssdk.services.b2bi.model.ThrottlingException import software.amazon.awssdk.services.b2bi.model.UntagResourceRequest import software.amazon.awssdk.services.b2bi.model.UpdatePartnershipRequest import software.amazon.awssdk.services.b2bi.model.ValidationException +import software.amazon.awssdk.services.b2bi.model.X12Delimiters as SdkX12Delimiters +import software.amazon.awssdk.services.b2bi.model.X12Envelope as SdkX12Envelope +import software.amazon.awssdk.services.b2bi.model.X12FunctionalGroupHeaders as SdkX12FunctionalGroupHeaders +import software.amazon.awssdk.services.b2bi.model.X12InterchangeControlHeaders as SdkX12InterchangeControlHeaders +import software.amazon.awssdk.services.b2bi.model.X12OutboundEdiHeaders as SdkX12OutboundEdiHeaders import software.amazon.b2bi.partnership.TagHelper.toSdkTag +import software.amazon.b2bi.partnership.CapabilityOptions as ResourceCapabilityOptions +import software.amazon.b2bi.partnership.OutboundEdiOptions as ResourceOutboundEdiOptions +import software.amazon.b2bi.partnership.X12Envelope as ResourceX12Envelope +import software.amazon.b2bi.partnership.X12OutboundEdiHeaders as ResourceX12OutboundEdiHeaders +import software.amazon.b2bi.partnership.X12InterchangeControlHeaders as ResourceX12InterchangeControlHeaders +import software.amazon.b2bi.partnership.X12FunctionalGroupHeaders as ResourceX12FunctionalGroupHeaders +import software.amazon.b2bi.partnership.X12Delimiters as ResourceX12Delimiters import software.amazon.cloudformation.exceptions.BaseHandlerException import software.amazon.cloudformation.exceptions.CfnAccessDeniedException import software.amazon.cloudformation.exceptions.CfnAlreadyExistsException @@ -33,8 +43,6 @@ import software.amazon.cloudformation.exceptions.CfnServiceLimitExceededExceptio import software.amazon.cloudformation.exceptions.CfnThrottlingException import java.time.Instant import java.util.* -import java.util.stream.Collectors -import java.util.stream.Stream /** * This class is a centralized placeholder for @@ -55,6 +63,7 @@ object Translator { .email(model.email) .phone(model.phone) .capabilities(model.capabilities) + .capabilityOptions(model.capabilityOptions?.translateToSdkCapabilityOptions()) .tags(model.tags.map { it.toSdkTag() }) .build() } @@ -85,6 +94,7 @@ object Translator { .email(response.email().emptyToNull()) .phone(response.phone().emptyToNull()) .capabilities(response.capabilities()) + .capabilityOptions(response.capabilityOptions()?.translateToResourceCapabilityOptions()) .tradingPartnerId(response.tradingPartnerId().emptyToNull()) .createdAt(response.createdAt().emptyToNull()) .modifiedAt(response.modifiedAt().emptyToNull()) @@ -116,6 +126,7 @@ object Translator { .partnershipId(model.partnershipId) .name(model.name) .capabilities(model.capabilities) + .capabilityOptions(model.capabilityOptions?.translateToSdkCapabilityOptions()) .build() } @@ -144,6 +155,7 @@ object Translator { .partnershipId(it.partnershipId()) .name(it.name()) .capabilities(it.capabilities()) + .capabilityOptions(it.capabilityOptions()?.translateToResourceCapabilityOptions()) .tradingPartnerId(it.tradingPartnerId()) .createdAt(it.createdAt().toString()) .modifiedAt(it.modifiedAt().toString()) @@ -177,6 +189,88 @@ object Translator { .build() } + fun ResourceCapabilityOptions.translateToSdkCapabilityOptions(): SdkCapabilityOptions { + val resourceInterchangeControlHeaders = this.outboundEdi?.x12?.common?.interchangeControlHeaders + val resourceFunctionalGroupHeaders = this.outboundEdi?.x12?.common?.functionalGroupHeaders + val resourceDelimiters = this.outboundEdi?.x12?.common?.delimiters + + return SdkCapabilityOptions.builder().outboundEdi( + SdkOutboundEdiOptions.builder().x12( + SdkX12Envelope.builder().common( + SdkX12OutboundEdiHeaders.builder() + .interchangeControlHeaders( + SdkX12InterchangeControlHeaders.builder() + .senderIdQualifier(resourceInterchangeControlHeaders?.senderIdQualifier) + .senderId(resourceInterchangeControlHeaders?.senderId) + .receiverIdQualifier(resourceInterchangeControlHeaders?.receiverIdQualifier) + .receiverId(resourceInterchangeControlHeaders?.receiverId) + .repetitionSeparator(resourceInterchangeControlHeaders?.repetitionSeparator) + .acknowledgmentRequestedCode(resourceInterchangeControlHeaders?.acknowledgmentRequestedCode) + .usageIndicatorCode(resourceInterchangeControlHeaders?.usageIndicatorCode) + .build() + ) + .functionalGroupHeaders( + SdkX12FunctionalGroupHeaders.builder() + .applicationSenderCode(resourceFunctionalGroupHeaders?.applicationSenderCode) + .applicationReceiverCode(resourceFunctionalGroupHeaders?.applicationReceiverCode) + .responsibleAgencyCode(resourceFunctionalGroupHeaders?.responsibleAgencyCode) + .build() + ) + .delimiters( + SdkX12Delimiters.builder() + .componentSeparator(resourceDelimiters?.componentSeparator) + .dataElementSeparator(resourceDelimiters?.dataElementSeparator) + .segmentTerminator(resourceDelimiters?.segmentTerminator) + .build() + ) + .validateEdi(this.outboundEdi?.x12?.common?.validateEdi) + .build() + ).build() + ).build() + ).build() + } + + fun SdkCapabilityOptions.translateToResourceCapabilityOptions(): ResourceCapabilityOptions { + val sdkInterchangeControlHeaders = this.outboundEdi()?.x12()?.common()?.interchangeControlHeaders() + val sdkFunctionalGroupHeaders = this.outboundEdi()?.x12()?.common()?.functionalGroupHeaders() + val sdkDelimiters = this.outboundEdi()?.x12()?.common()?.delimiters() + + return ResourceCapabilityOptions.builder().outboundEdi( + ResourceOutboundEdiOptions.builder().x12( + ResourceX12Envelope.builder().common( + ResourceX12OutboundEdiHeaders.builder() + .interchangeControlHeaders( + ResourceX12InterchangeControlHeaders.builder() + .senderIdQualifier(sdkInterchangeControlHeaders?.senderIdQualifier()) + .senderId(sdkInterchangeControlHeaders?.senderId()) + .receiverIdQualifier(sdkInterchangeControlHeaders?.receiverIdQualifier()) + .receiverId(sdkInterchangeControlHeaders?.receiverId()) + .repetitionSeparator(sdkInterchangeControlHeaders?.repetitionSeparator()) + .acknowledgmentRequestedCode(sdkInterchangeControlHeaders?.acknowledgmentRequestedCode()) + .usageIndicatorCode(sdkInterchangeControlHeaders?.usageIndicatorCode()) + .build() + ) + .functionalGroupHeaders( + ResourceX12FunctionalGroupHeaders.builder() + .applicationSenderCode(sdkFunctionalGroupHeaders?.applicationSenderCode()) + .applicationReceiverCode(sdkFunctionalGroupHeaders?.applicationReceiverCode()) + .responsibleAgencyCode(sdkFunctionalGroupHeaders?.responsibleAgencyCode()) + .build() + ) + .delimiters( + ResourceX12Delimiters.builder() + .componentSeparator(sdkDelimiters?.componentSeparator()) + .dataElementSeparator(sdkDelimiters?.dataElementSeparator()) + .segmentTerminator(sdkDelimiters?.segmentTerminator()) + .build() + ) + .validateEdi(this.outboundEdi()?.x12()?.common()?.validateEdi()) + .build() + ).build() + ).build() + ).build() + } + /** * Throws a CloudFormation exception for the corresponding B2BI exception * diff --git a/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/UpdateHandler.kt b/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/UpdateHandler.kt index 7d33f9d..ae6ca6e 100644 --- a/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/UpdateHandler.kt +++ b/aws-b2bi-partnership/src/main/kotlin/software/amazon/b2bi/partnership/UpdateHandler.kt @@ -15,6 +15,7 @@ import software.amazon.b2bi.partnership.TagHelper.shouldUpdateTags import software.amazon.b2bi.partnership.TagHelper.tagResource import software.amazon.b2bi.partnership.TagHelper.untagResource import software.amazon.b2bi.partnership.Translator.toCfnException +import software.amazon.b2bi.partnership.Translator.translateToResourceCapabilityOptions import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy import software.amazon.cloudformation.proxy.Logger import software.amazon.cloudformation.proxy.ProgressEvent @@ -63,6 +64,7 @@ class UpdateHandler : BaseHandlerStd() { email = response.email() phone = response.phone() capabilities = response.capabilities() + capabilityOptions = response.capabilityOptions()?.translateToResourceCapabilityOptions() tradingPartnerId = response.tradingPartnerId() createdAt = response.createdAt().toString() modifiedAt = response.modifiedAt().toString() diff --git a/aws-b2bi-partnership/src/test/kotlin/software/amazon/b2bi/partnership/TestData.kt b/aws-b2bi-partnership/src/test/kotlin/software/amazon/b2bi/partnership/TestData.kt index edd96cc..f97745d 100644 --- a/aws-b2bi-partnership/src/test/kotlin/software/amazon/b2bi/partnership/TestData.kt +++ b/aws-b2bi-partnership/src/test/kotlin/software/amazon/b2bi/partnership/TestData.kt @@ -6,7 +6,22 @@ import software.amazon.awssdk.services.b2bi.model.ListPartnershipsResponse import software.amazon.awssdk.services.b2bi.model.ListTagsForResourceResponse import software.amazon.awssdk.services.b2bi.model.PartnershipSummary import software.amazon.awssdk.services.b2bi.model.UpdatePartnershipResponse +import software.amazon.awssdk.services.b2bi.model.CapabilityOptions as SdkCapabilityOptions +import software.amazon.awssdk.services.b2bi.model.OutboundEdiOptions as SdkOutboundEdiOptions +import software.amazon.awssdk.services.b2bi.model.X12Delimiters as SdkX12Delimiters +import software.amazon.awssdk.services.b2bi.model.X12Envelope as SdkX12Envelope +import software.amazon.awssdk.services.b2bi.model.X12FunctionalGroupHeaders as SdkX12FunctionalGroupHeaders +import software.amazon.awssdk.services.b2bi.model.X12InterchangeControlHeaders as SdkX12InterchangeControlHeaders +import software.amazon.awssdk.services.b2bi.model.X12OutboundEdiHeaders as SdkX12OutboundEdiHeaders import software.amazon.b2bi.partnership.TagHelper.toSdkTag +import software.amazon.b2bi.partnership.CapabilityOptions as ResourceCapabilityOptions +import software.amazon.b2bi.partnership.OutboundEdiOptions as ResourceOutboundEdiOptions +import software.amazon.b2bi.partnership.X12Envelope as ResourceX12Envelope +import software.amazon.b2bi.partnership.X12OutboundEdiHeaders as ResourceX12OutboundEdiHeaders +import software.amazon.b2bi.partnership.X12InterchangeControlHeaders as ResourceX12InterchangeControlHeaders +import software.amazon.b2bi.partnership.X12FunctionalGroupHeaders as ResourceX12FunctionalGroupHeaders +import software.amazon.b2bi.partnership.X12Delimiters as ResourceX12Delimiters + import java.time.Instant const val TEST_NAME = "Test partnership name" @@ -17,6 +32,74 @@ const val TEST_PARTNERSHIP_PHONE = "2341234523" const val TEST_TRADING_PARTNER_ID = "tp-12345678901234567" const val TEST_PARTNERSHIP_ARN = "arn:aws:b2bi:us-east-1:123456789012:partnership/$TEST_PARTNERSHIP_ID" val TEST_PARTNERSHIP_LIST_CAPABILITIES = listOf("ca-12345678901234567") +val TEST_RESOURCE_PARTNERSHIP_CAPABILITY_OPTIONS = ResourceCapabilityOptions.builder().outboundEdi( + ResourceOutboundEdiOptions.builder().x12( + ResourceX12Envelope.builder().common( + ResourceX12OutboundEdiHeaders.builder() + .interchangeControlHeaders( + ResourceX12InterchangeControlHeaders.builder() + .senderIdQualifier("01") + .senderId("123456789012345") + .receiverIdQualifier("01") + .receiverId("098765432109876") + .repetitionSeparator("]") + .acknowledgmentRequestedCode("0") + .usageIndicatorCode("T") + .build() + ) + .functionalGroupHeaders( + ResourceX12FunctionalGroupHeaders.builder() + .applicationSenderCode("ASC") + .applicationReceiverCode("ASC") + .responsibleAgencyCode("X") + .build() + ) + .delimiters( + ResourceX12Delimiters.builder() + .componentSeparator(":") + .dataElementSeparator("*") + .segmentTerminator("~") + .build() + ) + .validateEdi(true) + .build() + ).build() + ).build() +).build() +val TEST_SDK_PARTNERSHIP_CAPABILITY_OPTIONS = SdkCapabilityOptions.builder().outboundEdi( + SdkOutboundEdiOptions.builder().x12( + SdkX12Envelope.builder().common( + SdkX12OutboundEdiHeaders.builder() + .interchangeControlHeaders( + SdkX12InterchangeControlHeaders.builder() + .senderIdQualifier("01") + .senderId("123456789012345") + .receiverIdQualifier("01") + .receiverId("098765432109876") + .repetitionSeparator("]") + .acknowledgmentRequestedCode("0") + .usageIndicatorCode("T") + .build() + ) + .functionalGroupHeaders( + SdkX12FunctionalGroupHeaders.builder() + .applicationSenderCode("ASC") + .applicationReceiverCode("ASC") + .responsibleAgencyCode("X") + .build() + ) + .delimiters( + SdkX12Delimiters.builder() + .componentSeparator(":") + .dataElementSeparator("*") + .segmentTerminator("~") + .build() + ) + .validateEdi(true) + .build() + ).build() + ).build() +).build() val TEST_INSTANT = Instant.now() @@ -42,6 +125,7 @@ val TEST_CREATE_PARTNERSHIP_REQUEST_RESOURCE_MODEL_WITH_ALL_FIELDS = TEST_CREATE_PARTNERSHIP_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_FIELDS.toBuilder() .phone(TEST_PARTNERSHIP_PHONE) .capabilities(TEST_PARTNERSHIP_LIST_CAPABILITIES) + .capabilityOptions(TEST_RESOURCE_PARTNERSHIP_CAPABILITY_OPTIONS) .tags(listOf(TEST_RESOURCE_TAG)) .build() @@ -59,6 +143,7 @@ val TEST_CREATE_PARTNERSHIP_RESPONSE_WITH_ALL_FIELDS = TEST_CREATE_PARTNERSHIP_RESPONSE_WITH_REQUIRED_FIELDS.toBuilder() .phone(TEST_PARTNERSHIP_PHONE) .capabilities(TEST_PARTNERSHIP_LIST_CAPABILITIES) + .capabilityOptions(TEST_SDK_PARTNERSHIP_CAPABILITY_OPTIONS) .tradingPartnerId(TEST_TRADING_PARTNER_ID) .build() @@ -73,6 +158,7 @@ val TEST_PARTNERSHIP_SUMMARY_WITH_ALL_FIELDS = PartnershipSummary.builder() .partnershipId(TEST_PARTNERSHIP_ID) .name(TEST_NAME) .capabilities(TEST_PARTNERSHIP_LIST_CAPABILITIES) + .capabilityOptions(TEST_SDK_PARTNERSHIP_CAPABILITY_OPTIONS) .tradingPartnerId(TEST_TRADING_PARTNER_ID) .createdAt(TEST_INSTANT) .modifiedAt(TEST_INSTANT) @@ -87,6 +173,7 @@ val TEST_LIST_PARTNERSHIPS_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceMod .partnershipId(TEST_PARTNERSHIP_ID) .name(TEST_NAME) .capabilities(TEST_PARTNERSHIP_LIST_CAPABILITIES) + .capabilityOptions(TEST_RESOURCE_PARTNERSHIP_CAPABILITY_OPTIONS) .tradingPartnerId(TEST_TRADING_PARTNER_ID) .createdAt(TEST_INSTANT.toString()) .modifiedAt(TEST_INSTANT.toString()) @@ -105,6 +192,7 @@ val TEST_GET_PARTNERSHIP_RESPONSE_WITH_ALL_FIELDS = GetPartnershipResponse.build .email(TEST_PARTNERSHIP_EMAIL) .phone(TEST_PARTNERSHIP_PHONE) .capabilities(TEST_PARTNERSHIP_LIST_CAPABILITIES) + .capabilityOptions(TEST_SDK_PARTNERSHIP_CAPABILITY_OPTIONS) .tradingPartnerId(TEST_TRADING_PARTNER_ID) .createdAt(TEST_INSTANT) .modifiedAt(TEST_INSTANT) @@ -118,6 +206,7 @@ val TEST_GET_PARTNERSHIP_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceModel .email(TEST_PARTNERSHIP_EMAIL) .phone(TEST_PARTNERSHIP_PHONE) .capabilities(TEST_PARTNERSHIP_LIST_CAPABILITIES) + .capabilityOptions(TEST_RESOURCE_PARTNERSHIP_CAPABILITY_OPTIONS) .tradingPartnerId(TEST_TRADING_PARTNER_ID) .tags(listOf(TEST_RESOURCE_TAG)) .createdAt(TEST_INSTANT.toString()) @@ -129,6 +218,7 @@ val TEST_UPDATE_PARTNERSHIP_REQUEST_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceMod .partnershipId(TEST_PARTNERSHIP_ID) .name(TEST_NAME) .capabilities(TEST_PARTNERSHIP_LIST_CAPABILITIES) + .capabilityOptions(TEST_RESOURCE_PARTNERSHIP_CAPABILITY_OPTIONS) .tags(listOf(TEST_RESOURCE_TAG)) .build() @@ -140,6 +230,7 @@ val TEST_UPDATE_PARTNERSHIP_RESPONSE_WITH_ALL_FIELDS = UpdatePartnershipResponse .email(TEST_PARTNERSHIP_EMAIL) .phone(TEST_PARTNERSHIP_PHONE) .capabilities(TEST_PARTNERSHIP_LIST_CAPABILITIES) + .capabilityOptions(TEST_SDK_PARTNERSHIP_CAPABILITY_OPTIONS) .tradingPartnerId(TEST_TRADING_PARTNER_ID) .createdAt(TEST_INSTANT) .modifiedAt(TEST_INSTANT) @@ -153,6 +244,7 @@ val TEST_UPDATE_PARTNERSHIP_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceMo .email(TEST_PARTNERSHIP_EMAIL) .phone(TEST_PARTNERSHIP_PHONE) .capabilities(TEST_PARTNERSHIP_LIST_CAPABILITIES) + .capabilityOptions(TEST_RESOURCE_PARTNERSHIP_CAPABILITY_OPTIONS) .tradingPartnerId(TEST_TRADING_PARTNER_ID) .createdAt(TEST_INSTANT.toString()) .modifiedAt(TEST_INSTANT.toString()) diff --git a/aws-b2bi-profile/.rpdk-config b/aws-b2bi-profile/.rpdk-config index 2daa0d5..d778ec1 100644 --- a/aws-b2bi-profile/.rpdk-config +++ b/aws-b2bi-profile/.rpdk-config @@ -26,5 +26,7 @@ "protocolVersion": "2.0.0" }, "logProcessorEnabled": "true", - "executableEntrypoint": "software.amazon.b2bi.profile.HandlerWrapperExecutable" + "executableEntrypoint": "software.amazon.b2bi.profile.HandlerWrapperExecutable", + "contractSettings": {}, + "canarySettings": {} } diff --git a/aws-b2bi-profile/aws-b2bi-profile.json b/aws-b2bi-profile/aws-b2bi-profile.json index a051f71..f27277e 100644 --- a/aws-b2bi-profile/aws-b2bi-profile.json +++ b/aws-b2bi-profile/aws-b2bi-profile.json @@ -155,7 +155,12 @@ "tagOnCreate": true, "tagProperty": "/properties/Tags", "tagUpdatable": true, - "taggable": true + "taggable": true, + "permissions": [ + "b2bi:ListTagsForResource", + "b2bi:TagResource", + "b2bi:UntagResource" + ] }, "additionalProperties": false } diff --git a/aws-b2bi-profile/pom.xml b/aws-b2bi-profile/pom.xml index d1499fe..c36f452 100644 --- a/aws-b2bi-profile/pom.xml +++ b/aws-b2bi-profile/pom.xml @@ -31,25 +31,25 @@ software.amazon.awssdk b2bi - 2.24.5 + 2.28.14 software.amazon.awssdk sdk-core - 2.24.5 + 2.28.14 software.amazon.awssdk aws-core - 2.24.5 + 2.28.14 software.amazon.awssdk utils - 2.24.5 + 2.28.14 diff --git a/aws-b2bi-profile/src/main/kotlin/software/amazon/b2bi/profile/TagHelper.kt b/aws-b2bi-profile/src/main/kotlin/software/amazon/b2bi/profile/TagHelper.kt index fdc0fa6..99cd8a2 100644 --- a/aws-b2bi-profile/src/main/kotlin/software/amazon/b2bi/profile/TagHelper.kt +++ b/aws-b2bi-profile/src/main/kotlin/software/amazon/b2bi/profile/TagHelper.kt @@ -40,6 +40,7 @@ object TagHelper { fun getPreviouslyAttachedTags(handlerRequest: ResourceHandlerRequest): Map { return getTags( handlerRequest.previousResourceTags, + handlerRequest.previousSystemTags, convertToMap(handlerRequest.previousResourceState.tags) ) } @@ -59,6 +60,7 @@ object TagHelper { fun getNewDesiredTags(handlerRequest: ResourceHandlerRequest): Map { return getTags( handlerRequest.desiredResourceTags, + handlerRequest.systemTags, convertToMap(handlerRequest.desiredResourceState.tags) ) } @@ -106,14 +108,18 @@ object TagHelper { addedTags: Map, logger: Logger ): ProgressEvent { - return proxy.initiate(TAG_OPERATION, proxyClient, resourceModel, callbackContext) - .translateToServiceRequest { model -> Translator.translateToTagResourceRequest(model, addedTags) } - .makeServiceCall { request, client -> - val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::tagResource) - logger.log("Successfully tagged ${ResourceModel.TYPE_NAME} ${resourceModel.profileId}") - response - } - .progress() + return if (addedTags.isNotEmpty()) { + proxy.initiate(TAG_OPERATION, proxyClient, resourceModel, callbackContext) + .translateToServiceRequest { model -> Translator.translateToTagResourceRequest(model, addedTags) } + .makeServiceCall { request, client -> + val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::tagResource) + logger.log("Successfully tagged ${ResourceModel.TYPE_NAME} ${resourceModel.profileId}") + response + } + .progress() + } else { + ProgressEvent.progress(resourceModel, callbackContext) + } } /** @@ -129,14 +135,18 @@ object TagHelper { removedTags: Set, logger: Logger ): ProgressEvent { - return proxy.initiate(UNTAG_OPERATION, proxyClient, resourceModel, callbackContext) - .translateToServiceRequest { model -> Translator.translateToUntagResourceRequest(model, removedTags) } - .makeServiceCall { request, client -> - val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::untagResource) - logger.log("Successfully untagged ${ResourceModel.TYPE_NAME} ${resourceModel.profileId}") - response - } - .progress() + return if (removedTags.isNotEmpty()) { + proxy.initiate(UNTAG_OPERATION, proxyClient, resourceModel, callbackContext) + .translateToServiceRequest { model -> Translator.translateToUntagResourceRequest(model, removedTags) } + .makeServiceCall { request, client -> + val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::untagResource) + logger.log("Successfully untagged ${ResourceModel.TYPE_NAME} ${resourceModel.profileId}") + response + } + .progress() + } else { + ProgressEvent.progress(resourceModel, callbackContext) + } } /** diff --git a/aws-b2bi-transformer/.rpdk-config b/aws-b2bi-transformer/.rpdk-config index 2e0fb23..06f114f 100644 --- a/aws-b2bi-transformer/.rpdk-config +++ b/aws-b2bi-transformer/.rpdk-config @@ -26,5 +26,7 @@ "protocolVersion": "2.0.0" }, "logProcessorEnabled": "true", - "executableEntrypoint": "software.amazon.b2bi.transformer.HandlerWrapperExecutable" + "executableEntrypoint": "software.amazon.b2bi.transformer.HandlerWrapperExecutable", + "contractSettings": {}, + "canarySettings": {} } diff --git a/aws-b2bi-transformer/aws-b2bi-transformer.json b/aws-b2bi-transformer/aws-b2bi-transformer.json index 2a0102a..3517b9c 100644 --- a/aws-b2bi-transformer/aws-b2bi-transformer.json +++ b/aws-b2bi-transformer/aws-b2bi-transformer.json @@ -23,9 +23,124 @@ "type": "string", "enum": [ "XML", - "JSON" + "JSON", + "NOT_USED" ] }, + "FormatOptions": { + "oneOf": [ + { + "type": "object", + "title": "X12", + "properties": { + "X12": { + "$ref": "#/definitions/X12Details" + } + }, + "required": [ + "X12" + ], + "additionalProperties": false + } + ] + }, + "FromFormat": { + "type": "string", + "enum": [ + "X12" + ] + }, + "InputConversion": { + "type": "object", + "properties": { + "FromFormat": { + "$ref": "#/definitions/FromFormat" + }, + "FormatOptions": { + "$ref": "#/definitions/FormatOptions" + } + }, + "required": [ + "FromFormat" + ], + "additionalProperties": false + }, + "Mapping": { + "type": "object", + "properties": { + "TemplateLanguage": { + "$ref": "#/definitions/MappingTemplateLanguage" + }, + "Template": { + "type": "string", + "maxLength": 350000, + "minLength": 0 + } + }, + "required": [ + "TemplateLanguage" + ], + "additionalProperties": false + }, + "MappingTemplateLanguage": { + "type": "string", + "enum": [ + "XSLT", + "JSONATA" + ] + }, + "OutputConversion": { + "type": "object", + "properties": { + "ToFormat": { + "$ref": "#/definitions/ToFormat" + }, + "FormatOptions": { + "$ref": "#/definitions/FormatOptions" + } + }, + "required": [ + "ToFormat" + ], + "additionalProperties": false + }, + "SampleDocumentKeys": { + "type": "object", + "properties": { + "Input": { + "type": "string", + "maxLength": 1024, + "minLength": 0 + }, + "Output": { + "type": "string", + "maxLength": 1024, + "minLength": 0 + } + }, + "additionalProperties": false + }, + "SampleDocuments": { + "type": "object", + "properties": { + "BucketName": { + "type": "string", + "maxLength": 63, + "minLength": 3 + }, + "Keys": { + "type": "array", + "items": { + "$ref": "#/definitions/SampleDocumentKeys" + } + } + }, + "required": [ + "BucketName", + "Keys" + ], + "additionalProperties": false + }, "Tag": { "type": "object", "properties": { @@ -46,6 +161,12 @@ ], "additionalProperties": false }, + "ToFormat": { + "type": "string", + "enum": [ + "X12" + ] + }, "TransformerStatus": { "type": "string", "enum": [ @@ -166,10 +287,17 @@ "FileFormat": { "$ref": "#/definitions/FileFormat" }, + "InputConversion": { + "$ref": "#/definitions/InputConversion" + }, + "Mapping": { + "$ref": "#/definitions/Mapping" + }, "MappingTemplate": { "type": "string", "maxLength": 350000, - "minLength": 0 + "minLength": 0, + "description": "This shape is deprecated: This is a legacy trait. Please use input-conversion or output-conversion." }, "ModifiedAt": { "type": "string", @@ -178,12 +306,20 @@ "Name": { "type": "string", "maxLength": 254, - "minLength": 1 + "minLength": 1, + "pattern": "^[a-zA-Z0-9_-]{1,512}$" + }, + "OutputConversion": { + "$ref": "#/definitions/OutputConversion" }, "SampleDocument": { "type": "string", "maxLength": 1024, - "minLength": 0 + "minLength": 0, + "description": "This shape is deprecated: This is a legacy trait. Please use input-conversion or output-conversion." + }, + "SampleDocuments": { + "$ref": "#/definitions/SampleDocuments" }, "Status": { "$ref": "#/definitions/TransformerStatus" @@ -209,9 +345,6 @@ } }, "required": [ - "EdiType", - "FileFormat", - "MappingTemplate", "Name", "Status" ], @@ -221,6 +354,12 @@ "/properties/TransformerArn", "/properties/TransformerId" ], + "deprecatedProperties": [ + "/properties/EdiType", + "/properties/FileFormat", + "/properties/MappingTemplate", + "/properties/SampleDocument" + ], "primaryIdentifier": [ "/properties/TransformerId" ], @@ -272,7 +411,12 @@ "tagOnCreate": true, "tagProperty": "/properties/Tags", "tagUpdatable": true, - "taggable": true + "taggable": true, + "permissions": [ + "b2bi:ListTagsForResource", + "b2bi:TagResource", + "b2bi:UntagResource" + ] }, "additionalProperties": false } diff --git a/aws-b2bi-transformer/docs/README.md b/aws-b2bi-transformer/docs/README.md index 9ff5425..ae51039 100644 --- a/aws-b2bi-transformer/docs/README.md +++ b/aws-b2bi-transformer/docs/README.md @@ -14,9 +14,13 @@ To declare this entity in your AWS CloudFormation template, use the following sy "Properties" : { "EdiType" : EdiType, "FileFormat" : String, + "InputConversion" : InputConversion, + "Mapping" : Mapping, "MappingTemplate" : String, "Name" : String, + "OutputConversion" : OutputConversion, "SampleDocument" : String, + "SampleDocuments" : SampleDocuments, "Status" : String, "Tags" : [ Tag, ... ], } @@ -30,9 +34,13 @@ Type: AWS::B2BI::Transformer Properties: EdiType: EdiType FileFormat: String + InputConversion: InputConversion + Mapping: Mapping MappingTemplate: String Name: String + OutputConversion: OutputConversion SampleDocument: String + SampleDocuments: SampleDocuments Status: String Tags: - Tag @@ -42,7 +50,7 @@ Properties: #### EdiType -_Required_: Yes +_Required_: No _Type_: EdiType @@ -50,17 +58,35 @@ _Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormati #### FileFormat -_Required_: Yes +_Required_: No _Type_: String -_Allowed Values_: XML | JSON +_Allowed Values_: XML | JSON | NOT_USED + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### InputConversion + +_Required_: No + +_Type_: InputConversion + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### Mapping + +_Required_: No + +_Type_: Mapping _Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) #### MappingTemplate -_Required_: Yes +This shape is deprecated: This is a legacy trait. Please use input-conversion or output-conversion. + +_Required_: No _Type_: String @@ -78,10 +104,22 @@ _Minimum Length_: 1 _Maximum Length_: 254 +_Pattern_: ^[a-zA-Z0-9_-]{1,512}$ + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### OutputConversion + +_Required_: No + +_Type_: OutputConversion + _Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) #### SampleDocument +This shape is deprecated: This is a legacy trait. Please use input-conversion or output-conversion. + _Required_: No _Type_: String @@ -90,6 +128,14 @@ _Maximum Length_: 1024 _Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) +#### SampleDocuments + +_Required_: No + +_Type_: SampleDocuments + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + #### Status _Required_: Yes diff --git a/aws-b2bi-transformer/docs/formatoptions.md b/aws-b2bi-transformer/docs/formatoptions.md new file mode 100644 index 0000000..278a47c --- /dev/null +++ b/aws-b2bi-transformer/docs/formatoptions.md @@ -0,0 +1,30 @@ +# AWS::B2BI::Transformer FormatOptions + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "X12" : X12Details
+}
+
+ +### YAML + +
+X12: X12Details
+
+ +## Properties + +#### X12 + +_Required_: Yes + +_Type_: X12Details + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-transformer/docs/inputconversion.md b/aws-b2bi-transformer/docs/inputconversion.md new file mode 100644 index 0000000..adb49d6 --- /dev/null +++ b/aws-b2bi-transformer/docs/inputconversion.md @@ -0,0 +1,42 @@ +# AWS::B2BI::Transformer InputConversion + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "FromFormat" : String,
+    "FormatOptions" : FormatOptions
+}
+
+ +### YAML + +
+FromFormat: String
+FormatOptions: FormatOptions
+
+ +## Properties + +#### FromFormat + +_Required_: Yes + +_Type_: String + +_Allowed Values_: X12 + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### FormatOptions + +_Required_: No + +_Type_: FormatOptions + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-transformer/docs/mapping.md b/aws-b2bi-transformer/docs/mapping.md new file mode 100644 index 0000000..6db5133 --- /dev/null +++ b/aws-b2bi-transformer/docs/mapping.md @@ -0,0 +1,44 @@ +# AWS::B2BI::Transformer Mapping + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "TemplateLanguage" : String,
+    "Template" : String
+}
+
+ +### YAML + +
+TemplateLanguage: String
+Template: String
+
+ +## Properties + +#### TemplateLanguage + +_Required_: Yes + +_Type_: String + +_Allowed Values_: XSLT | JSONATA + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### Template + +_Required_: No + +_Type_: String + +_Maximum Length_: 350000 + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-transformer/docs/outputconversion.md b/aws-b2bi-transformer/docs/outputconversion.md new file mode 100644 index 0000000..2be03a9 --- /dev/null +++ b/aws-b2bi-transformer/docs/outputconversion.md @@ -0,0 +1,42 @@ +# AWS::B2BI::Transformer OutputConversion + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "ToFormat" : String,
+    "FormatOptions" : FormatOptions
+}
+
+ +### YAML + +
+ToFormat: String
+FormatOptions: FormatOptions
+
+ +## Properties + +#### ToFormat + +_Required_: Yes + +_Type_: String + +_Allowed Values_: X12 + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### FormatOptions + +_Required_: No + +_Type_: FormatOptions + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-transformer/docs/sampledocumentkeys.md b/aws-b2bi-transformer/docs/sampledocumentkeys.md new file mode 100644 index 0000000..2507441 --- /dev/null +++ b/aws-b2bi-transformer/docs/sampledocumentkeys.md @@ -0,0 +1,44 @@ +# AWS::B2BI::Transformer SampleDocumentKeys + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "Input" : String,
+    "Output" : String
+}
+
+ +### YAML + +
+Input: String
+Output: String
+
+ +## Properties + +#### Input + +_Required_: No + +_Type_: String + +_Maximum Length_: 1024 + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### Output + +_Required_: No + +_Type_: String + +_Maximum Length_: 1024 + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-transformer/docs/sampledocuments.md b/aws-b2bi-transformer/docs/sampledocuments.md new file mode 100644 index 0000000..71f3dcd --- /dev/null +++ b/aws-b2bi-transformer/docs/sampledocuments.md @@ -0,0 +1,45 @@ +# AWS::B2BI::Transformer SampleDocuments + +## Syntax + +To declare this entity in your AWS CloudFormation template, use the following syntax: + +### JSON + +
+{
+    "BucketName" : String,
+    "Keys" : [ SampleDocumentKeys, ... ]
+}
+
+ +### YAML + +
+BucketName: String
+Keys: 
+      - SampleDocumentKeys
+
+ +## Properties + +#### BucketName + +_Required_: Yes + +_Type_: String + +_Minimum Length_: 3 + +_Maximum Length_: 63 + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + +#### Keys + +_Required_: Yes + +_Type_: List of SampleDocumentKeys + +_Update requires_: [No interruption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) + diff --git a/aws-b2bi-transformer/pom.xml b/aws-b2bi-transformer/pom.xml index 109bc68..1156627 100644 --- a/aws-b2bi-transformer/pom.xml +++ b/aws-b2bi-transformer/pom.xml @@ -31,25 +31,25 @@ software.amazon.awssdk b2bi - 2.24.5 + 2.28.14 software.amazon.awssdk sdk-core - 2.24.5 + 2.28.14 software.amazon.awssdk aws-core - 2.24.5 + 2.28.14 software.amazon.awssdk utils - 2.24.5 + 2.28.14 diff --git a/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/ReadHandler.kt b/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/ReadHandler.kt index 3d146b1..85e5530 100644 --- a/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/ReadHandler.kt +++ b/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/ReadHandler.kt @@ -1,12 +1,10 @@ package software.amazon.b2bi.transformer -import software.amazon.awssdk.awscore.AwsResponse import software.amazon.awssdk.awscore.exception.AwsServiceException import software.amazon.awssdk.services.b2bi.B2BiClient import software.amazon.awssdk.services.b2bi.model.GetTransformerRequest import software.amazon.awssdk.services.b2bi.model.GetTransformerResponse import software.amazon.b2bi.transformer.Translator.toCfnException -import software.amazon.cloudformation.exceptions.CfnGeneralServiceException import software.amazon.cloudformation.proxy.* class ReadHandler : BaseHandlerStd() { @@ -62,6 +60,10 @@ class ReadHandler : BaseHandlerStd() { status = readResponseResourceModel.status ediType = readResponseResourceModel.ediType sampleDocument = readResponseResourceModel.sampleDocument + inputConversion = readResponseResourceModel.inputConversion + outputConversion = readResponseResourceModel.outputConversion + mapping = readResponseResourceModel.mapping + sampleDocuments = readResponseResourceModel.sampleDocuments createdAt = readResponseResourceModel.createdAt modifiedAt = readResponseResourceModel.modifiedAt } diff --git a/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/TagHelper.kt b/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/TagHelper.kt index 5e8220f..c05eba8 100644 --- a/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/TagHelper.kt +++ b/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/TagHelper.kt @@ -40,6 +40,7 @@ object TagHelper { fun getPreviouslyAttachedTags(handlerRequest: ResourceHandlerRequest): Map { return getTags( handlerRequest.previousResourceTags, + handlerRequest.previousSystemTags, convertToMap(handlerRequest.previousResourceState.tags) ) } @@ -59,6 +60,7 @@ object TagHelper { fun getNewDesiredTags(handlerRequest: ResourceHandlerRequest): Map { return getTags( handlerRequest.desiredResourceTags, + handlerRequest.systemTags, convertToMap(handlerRequest.desiredResourceState.tags) ) } @@ -106,14 +108,18 @@ object TagHelper { addedTags: Map, logger: Logger ): ProgressEvent { - return proxy.initiate(TAG_OPERATION, proxyClient, resourceModel, callbackContext) - .translateToServiceRequest { model -> Translator.translateToTagResourceRequest(model, addedTags) } - .makeServiceCall { request, client -> - val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::tagResource) - logger.log("Successfully tagged ${ResourceModel.TYPE_NAME} ${resourceModel.transformerId}") - response - } - .progress() + return if (addedTags.isNotEmpty()) { + proxy.initiate(TAG_OPERATION, proxyClient, resourceModel, callbackContext) + .translateToServiceRequest { model -> Translator.translateToTagResourceRequest(model, addedTags) } + .makeServiceCall { request, client -> + val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::tagResource) + logger.log("Successfully tagged ${ResourceModel.TYPE_NAME} ${resourceModel.transformerId}") + response + } + .progress() + } else { + ProgressEvent.progress(resourceModel, callbackContext) + } } /** @@ -129,14 +135,18 @@ object TagHelper { removedTags: Set, logger: Logger ): ProgressEvent { - return proxy.initiate(UNTAG_OPERATION, proxyClient, resourceModel, callbackContext) - .translateToServiceRequest { model -> Translator.translateToUntagResourceRequest(model, removedTags) } - .makeServiceCall { request, client -> - val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::untagResource) - logger.log("Successfully untagged ${ResourceModel.TYPE_NAME} ${resourceModel.transformerId}") - response - } - .progress() + return if (removedTags.isNotEmpty()) { + proxy.initiate(UNTAG_OPERATION, proxyClient, resourceModel, callbackContext) + .translateToServiceRequest { model -> Translator.translateToUntagResourceRequest(model, removedTags) } + .makeServiceCall { request, client -> + val response = proxy.injectCredentialsAndInvokeV2(request, client.client()::untagResource) + logger.log("Successfully untagged ${ResourceModel.TYPE_NAME} ${resourceModel.transformerId}") + response + } + .progress() + } else { + ProgressEvent.progress(resourceModel, callbackContext) + } } /** diff --git a/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/Translator.kt b/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/Translator.kt index c210aa4..8951b21 100644 --- a/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/Translator.kt +++ b/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/Translator.kt @@ -31,8 +31,20 @@ import software.amazon.cloudformation.exceptions.CfnServiceLimitExceededExceptio import software.amazon.cloudformation.exceptions.CfnThrottlingException import java.time.Instant import software.amazon.awssdk.services.b2bi.model.EdiType as SdkEdi +import software.amazon.awssdk.services.b2bi.model.FormatOptions as SdkFormatOptions +import software.amazon.awssdk.services.b2bi.model.InputConversion as SdkInputConversion +import software.amazon.awssdk.services.b2bi.model.Mapping as SdkMapping +import software.amazon.awssdk.services.b2bi.model.OutputConversion as SdkOutputConversion +import software.amazon.awssdk.services.b2bi.model.SampleDocumentKeys as SdkSampleDocumentKeys +import software.amazon.awssdk.services.b2bi.model.SampleDocuments as SdkSampleDocuments import software.amazon.awssdk.services.b2bi.model.X12Details as SdkX12 import software.amazon.b2bi.transformer.EdiType as ResourceEdi +import software.amazon.b2bi.transformer.FormatOptions as ResourceFormatOptions +import software.amazon.b2bi.transformer.InputConversion as ResourceInputConversion +import software.amazon.b2bi.transformer.Mapping as ResourceMapping +import software.amazon.b2bi.transformer.OutputConversion as ResourceOutputConversion +import software.amazon.b2bi.transformer.SampleDocumentKeys as ResourceSampleDocumentKeys +import software.amazon.b2bi.transformer.SampleDocuments as ResourceSampleDocuments import software.amazon.b2bi.transformer.X12Details as ResourceX12 /** @@ -54,7 +66,11 @@ object Translator { .mappingTemplate(model.mappingTemplate) .sampleDocument(model.sampleDocument) .tags(model.tags.map { it.toSdkTag() }) - .ediType(model.ediType.translateToSdkEdi()) + .ediType(model.ediType?.translateToSdkEdi()) + .inputConversion(model.inputConversion?.translateToSdkInputConversion()) + .outputConversion(model.outputConversion?.translateToSdkOutputConversion()) + .mapping(model.mapping?.translateToSdkMapping()) + .sampleDocuments(model.sampleDocuments?.translateToSdkSampleDocuments()) .build() } @@ -79,10 +95,14 @@ object Translator { .transformerId(response.transformerId().emptyToNull()) .transformerArn(response.transformerArn().emptyToNull()) .name(response.name().emptyToNull()) - .fileFormat(response.fileFormat().emptyToNull()) - .mappingTemplate(response.mappingTemplate().emptyToNull()) - .sampleDocument(response.sampleDocument().emptyToNull()) + .fileFormat(response.fileFormat()?.emptyToNull()) + .mappingTemplate(response.mappingTemplate()?.emptyToNull()) + .sampleDocument(response.sampleDocument()?.emptyToNull()) .ediType(response.ediType()?.translateToResourceEdi()) + .mapping(response.mapping()?.translateToResourceMapping()) + .inputConversion(response.inputConversion()?.translateToResourceInputConversion()) + .outputConversion(response.outputConversion()?.translateToResourceOutputConversion()) + .sampleDocuments(response.sampleDocuments()?.translateToResourceSampleDocuments()) .status(response.status().emptyToNull()) .createdAt(response.createdAt().emptyToNull()) .modifiedAt(response.modifiedAt().emptyToNull()) @@ -91,11 +111,12 @@ object Translator { private fun String?.emptyToNull() = if (this.isNullOrEmpty()) null else this - private fun Instant?.emptyToNull() = if (this == null) null else this.toString() + // Contract tests expect the modifiedAt property to at least return an empty string, cannot be null + private fun Instant?.emptyToNull() = this?.toString() ?: "" - private fun FileFormat?.emptyToNull() = if (this == null) null else this.toString() + private fun FileFormat?.emptyToNull() = this?.toString() - private fun TransformerStatus?.emptyToNull() = if (this == null) null else this.toString() + private fun TransformerStatus?.emptyToNull() = this?.toString() /** * Request to delete a resource @@ -117,10 +138,14 @@ object Translator { return UpdateTransformerRequest.builder() .transformerId(model.transformerId) .name(model.name) - .ediType(model.ediType.translateToSdkEdi()) + .ediType(model.ediType?.translateToSdkEdi()) .fileFormat(model.fileFormat) .mappingTemplate(model.mappingTemplate) .sampleDocument(model.sampleDocument) + .inputConversion(model.inputConversion?.translateToSdkInputConversion()) + .outputConversion(model.outputConversion?.translateToSdkOutputConversion()) + .mapping(model.mapping?.translateToSdkMapping()) + .sampleDocuments(model.sampleDocuments?.translateToSdkSampleDocuments()) .status(model.status) .build() } @@ -151,6 +176,10 @@ object Translator { .fileFormat(it.fileFormatAsString()) .mappingTemplate(it.mappingTemplate()) .sampleDocument(it.sampleDocument()) + .inputConversion(it.inputConversion()?.translateToResourceInputConversion()) + .outputConversion(it.outputConversion()?.translateToResourceOutputConversion()) + .mapping(it.mapping()?.translateToResourceMapping()) + .sampleDocuments(it.sampleDocuments()?.translateToResourceSampleDocuments()) .status(it.statusAsString()) .createdAt(it.createdAt().toString()) .modifiedAt(if (it.modifiedAt() != null) it.modifiedAt().toString() else null) @@ -189,10 +218,48 @@ object Translator { } fun SdkEdi.translateToResourceEdi(): ResourceEdi { - val x12 : ResourceX12 = ResourceX12.builder().transactionSet(this.x12Details().transactionSetAsString()).version(this.x12Details().versionAsString()).build() + val x12 = ResourceX12.builder().transactionSet(this.x12Details().transactionSetAsString()).version(this.x12Details().versionAsString()).build() return ResourceEdi.builder().x12Details(x12).build() } + fun ResourceInputConversion.translateToSdkInputConversion(): SdkInputConversion { + val x12Details = SdkX12.builder().transactionSet(this.formatOptions.x12.transactionSet).version(this.formatOptions.x12.version).build() + return SdkInputConversion.builder().fromFormat(this.fromFormat).formatOptions(SdkFormatOptions.fromX12(x12Details)).build() + } + + fun SdkInputConversion.translateToResourceInputConversion(): ResourceInputConversion { + val x12 = ResourceX12.builder().transactionSet(this.formatOptions().x12().transactionSetAsString()).version(this.formatOptions().x12().versionAsString()).build() + return ResourceInputConversion.builder().fromFormat(this.fromFormatAsString()).formatOptions(ResourceFormatOptions.builder().x12(x12).build()).build() + } + + fun ResourceOutputConversion.translateToSdkOutputConversion(): SdkOutputConversion { + val x12Details = SdkX12.builder().transactionSet(this.formatOptions.x12.transactionSet).version(this.formatOptions.x12.version).build() + return SdkOutputConversion.builder().toFormat(this.toFormat).formatOptions(SdkFormatOptions.fromX12(x12Details)).build() + } + + fun SdkOutputConversion.translateToResourceOutputConversion(): ResourceOutputConversion { + val x12 = ResourceX12.builder().transactionSet(this.formatOptions().x12().transactionSetAsString()).version(this.formatOptions().x12().versionAsString()).build() + return ResourceOutputConversion.builder().toFormat(this.toFormatAsString()).formatOptions(ResourceFormatOptions.builder().x12(x12).build()).build() + } + + fun ResourceSampleDocuments.translateToSdkSampleDocuments(): SdkSampleDocuments { + val keys = SdkSampleDocumentKeys.builder().input(this.keys[0].input).output(this.keys[0].output).build() + return SdkSampleDocuments.builder().bucketName(this.bucketName).keys(keys).build() + } + + fun SdkSampleDocuments.translateToResourceSampleDocuments(): ResourceSampleDocuments { + val keys = ResourceSampleDocumentKeys.builder().input(this.keys().first().input()).output(this.keys().first().output()).build() + return ResourceSampleDocuments.builder().bucketName(this.bucketName()).keys(listOf(keys)).build() + } + + fun ResourceMapping.translateToSdkMapping(): SdkMapping { + return SdkMapping.builder().templateLanguage(this.templateLanguage).template(this.template).build() + } + + fun SdkMapping.translateToResourceMapping(): ResourceMapping { + return ResourceMapping.builder().templateLanguage(this.templateLanguageAsString()).template(this.template()).build() + } + fun AwsServiceException.toCfnException(): BaseHandlerException = when (this) { is AccessDeniedException -> CfnAccessDeniedException(this) is ConflictException -> CfnAlreadyExistsException(this) diff --git a/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/UpdateHandler.kt b/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/UpdateHandler.kt index f2c3767..374e624 100644 --- a/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/UpdateHandler.kt +++ b/aws-b2bi-transformer/src/main/kotlin/software/amazon/b2bi/transformer/UpdateHandler.kt @@ -14,6 +14,10 @@ import software.amazon.b2bi.transformer.TagHelper.tagResource import software.amazon.b2bi.transformer.TagHelper.untagResource import software.amazon.b2bi.transformer.Translator.toCfnException import software.amazon.b2bi.transformer.Translator.translateToResourceEdi +import software.amazon.b2bi.transformer.Translator.translateToResourceInputConversion +import software.amazon.b2bi.transformer.Translator.translateToResourceMapping +import software.amazon.b2bi.transformer.Translator.translateToResourceOutputConversion +import software.amazon.b2bi.transformer.Translator.translateToResourceSampleDocuments import software.amazon.cloudformation.proxy.AmazonWebServicesClientProxy import software.amazon.cloudformation.proxy.Logger import software.amazon.cloudformation.proxy.ProgressEvent @@ -59,14 +63,22 @@ class UpdateHandler : BaseHandlerStd() { } resourceModel.apply { transformerArn = response.transformerArn() - mappingTemplate = response.mappingTemplate() - fileFormat = response.fileFormat().toString() - ediType = response.ediType().translateToResourceEdi() - sampleDocument = response.sampleDocument() name = response.name() createdAt = response.createdAt().toString() status = response.status().toString() modifiedAt = response.modifiedAt().toString() + + // old fields + mappingTemplate = response.mappingTemplate() + fileFormat = response.fileFormatAsString() + ediType = response.ediType()?.translateToResourceEdi() + sampleDocument = response.sampleDocument() + + // new fields + inputConversion = response.inputConversion()?.translateToResourceInputConversion() + outputConversion = response.outputConversion()?.translateToResourceOutputConversion() + mapping = response.mapping()?.translateToResourceMapping() + sampleDocuments = response.sampleDocuments()?.translateToResourceSampleDocuments() } logger.log("Successfully updated ${ResourceModel.TYPE_NAME} ${resourceModel.transformerId}") return response diff --git a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/CreateHandlerTest.kt b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/CreateHandlerTest.kt index fc14002..da01a50 100644 --- a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/CreateHandlerTest.kt +++ b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/CreateHandlerTest.kt @@ -50,9 +50,7 @@ class CreateHandlerTest : AbstractTestBase() { unmockkAll() } - @ParameterizedTest - @MethodSource("createHandlerSuccessTestData") - fun handleRequest(testArgs: TestArgs) { + private fun handleRequest(testArgs: TestArgs) { every { b2BiClient.createTransformer(any()) } returns testArgs.apiResponse val request = ResourceHandlerRequest.builder() @@ -69,6 +67,18 @@ class CreateHandlerTest : AbstractTestBase() { assertThat(response.errorCode).isNull() } + @ParameterizedTest + @MethodSource("createHandlerSuccessLegacyTransformerTestData") + fun handleLegacyRequest(testArgs: TestArgs) = handleRequest(testArgs) + + @ParameterizedTest + @MethodSource("createHandlerSuccessInboundTransformerTestData") + fun handleInboundRequest(testArgs: TestArgs) = handleRequest(testArgs) + + @ParameterizedTest + @MethodSource("createHandlerSuccessOutboundTransformerTestData") + fun handleOutboundRequest(testArgs: TestArgs) = handleRequest(testArgs) + @Test fun handleRequest_throwsException() { every { @@ -76,7 +86,7 @@ class CreateHandlerTest : AbstractTestBase() { } throws AwsServiceException.builder().build() val request = ResourceHandlerRequest.builder() - .desiredResourceState(TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_FIELDS) + .desiredResourceState(TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS) .build() assertThatThrownBy { handler.handleRequest(request) } .isInstanceOf(CfnGeneralServiceException::class.java) @@ -97,22 +107,70 @@ class CreateHandlerTest : AbstractTestBase() { companion object { @JvmStatic - fun createHandlerSuccessTestData() = listOf( + fun createHandlerSuccessLegacyTransformerTestData() = listOf( + TestArgs( + testName = "Create transformer with all legacy fields.", + requestResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS, + apiResponse = TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_LEGACY_FIELDS, + expectedResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS.toBuilder() + .transformerId(TEST_TRANSFORMER_ID) + .transformerArn(TEST_TRANSFORMER_ARN) + .status(TEST_TRANSFORMER_STATUS) + .build() + ), + TestArgs( + testName = "Create transformer with only required legacy fields.", + requestResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_LEGACY_FIELDS, + apiResponse = TEST_CREATE_TRANSFORMER_RESPONSE_WITH_REQUIRED_LEGACY_FIELDS, + expectedResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_LEGACY_FIELDS.toBuilder() + .transformerId(TEST_TRANSFORMER_ID) + .transformerArn(TEST_TRANSFORMER_ARN) + .status(TEST_TRANSFORMER_STATUS) + .build() + ), + ) + + @JvmStatic + fun createHandlerSuccessInboundTransformerTestData() = listOf( + TestArgs( + testName = "Create transformer with all inbound fields.", + requestResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS, + apiResponse = TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_INBOUND_FIELDS, + expectedResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS.toBuilder() + .transformerId(TEST_TRANSFORMER_ID) + .transformerArn(TEST_TRANSFORMER_ARN) + .status(TEST_TRANSFORMER_STATUS) + .build() + ), + TestArgs( + testName = "Create transformer with only required inbound fields.", + requestResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_INBOUND_FIELDS, + apiResponse = TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_INBOUND_FIELDS, + expectedResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_INBOUND_FIELDS.toBuilder() + .transformerId(TEST_TRANSFORMER_ID) + .transformerArn(TEST_TRANSFORMER_ARN) + .status(TEST_TRANSFORMER_STATUS) + .build() + ), + ) + + @JvmStatic + fun createHandlerSuccessOutboundTransformerTestData() = listOf( TestArgs( - testName = "Create transformer with all fields.", - requestResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_FIELDS, - apiResponse = TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_FIELDS, - expectedResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_FIELDS.toBuilder() + testName = "Create transformer with all outbound fields.", + requestResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS, + apiResponse = TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_OUTBOUND_FIELDS, + expectedResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS.toBuilder() .transformerId(TEST_TRANSFORMER_ID) .transformerArn(TEST_TRANSFORMER_ARN) .status(TEST_TRANSFORMER_STATUS) .build() ), TestArgs( - testName = "Create transformer with only required fields.", - requestResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_FIELDS, - apiResponse = TEST_CREATE_TRANSFORMER_RESPONSE_WITH_REQUIRED_FIELDS, - expectedResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_FIELDS.toBuilder() + testName = "Create transformer with only required outbound fields.", + requestResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_OUTBOUND_FIELDS, + apiResponse = TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_OUTBOUND_FIELDS, + expectedResourceModel = TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_OUTBOUND_FIELDS.toBuilder() .transformerId(TEST_TRANSFORMER_ID) .transformerArn(TEST_TRANSFORMER_ARN) .status(TEST_TRANSFORMER_STATUS) diff --git a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/ListHandlerTest.kt b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/ListHandlerTest.kt index 601addf..b32b94b 100644 --- a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/ListHandlerTest.kt +++ b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/ListHandlerTest.kt @@ -38,9 +38,7 @@ class ListHandlerTest { unmockkAll() } - @ParameterizedTest - @MethodSource("listHandlerSuccessTestData") - fun handleRequest(testArgs: TestArgs) { + private fun handleRequest(testArgs: TestArgs) { every { proxy.injectCredentialsAndInvokeV2( any(), @@ -64,6 +62,18 @@ class ListHandlerTest { assertThat(response.errorCode).isNull() } + @ParameterizedTest + @MethodSource("listHandlerSuccessLegacyTransformerTestData") + fun handleLegacyRequest(testArgs: TestArgs) = handleRequest(testArgs) + + @ParameterizedTest + @MethodSource("listHandlerSuccessInboundTransformerTestData") + fun handleInboundRequest(testArgs: TestArgs) = handleRequest(testArgs) + + @ParameterizedTest + @MethodSource("listHandlerSuccessOutboundTransformerTestData") + fun handleOutboundRequest(testArgs: TestArgs) = handleRequest(testArgs) + private fun ListHandler.handleRequest( request: ResourceHandlerRequest ): ProgressEvent { @@ -79,12 +89,32 @@ class ListHandlerTest { companion object { @JvmStatic - fun listHandlerSuccessTestData() = listOf( + fun listHandlerSuccessLegacyTransformerTestData() = listOf( + TestArgs( + testName = "List legacy transformers with no nextToken and single existing profile returns one transformer.", + requestNextToken = null, + apiResponse = TEST_LIST_TRANSFORMERS_RESPONSE_WITH_ONE_TRANSFORMER_WITH_ALL_LEGACY_FIELDS, + expectedResourceModels = listOf(TEST_LIST_TRANSFORMERS_RESPONSE_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS) + ) + ) + + @JvmStatic + fun listHandlerSuccessInboundTransformerTestData() = listOf( + TestArgs( + testName = "List inbound transformers with no nextToken and single existing profile returns one transformer.", + requestNextToken = null, + apiResponse = TEST_LIST_TRANSFORMERS_RESPONSE_WITH_ONE_TRANSFORMER_WITH_ALL_INBOUND_FIELDS, + expectedResourceModels = listOf(TEST_LIST_TRANSFORMERS_RESPONSE_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS) + ) + ) + + @JvmStatic + fun listHandlerSuccessOutboundTransformerTestData() = listOf( TestArgs( - testName = "List transformers with no nextToken and single existing profile returns one transformer.", + testName = "List outbound transformers with no nextToken and single existing profile returns one transformer.", requestNextToken = null, - apiResponse = TEST_LIST_TRANSFORMERS_RESPONSE_WITH_ONE_TRANSFORMER_WITH_ALL_FIELDS, - expectedResourceModels = listOf(TEST_LIST_TRANSFORMERS_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS) + apiResponse = TEST_LIST_TRANSFORMERS_RESPONSE_WITH_ONE_TRANSFORMER_WITH_ALL_OUTBOUND_FIELDS, + expectedResourceModels = listOf(TEST_LIST_TRANSFORMERS_RESPONSE_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS) ) ) } diff --git a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/ReadHandlerTest.kt b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/ReadHandlerTest.kt index c2b8dec..95b8f09 100644 --- a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/ReadHandlerTest.kt +++ b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/ReadHandlerTest.kt @@ -52,9 +52,7 @@ class ReadHandlerTest : AbstractTestBase() { unmockkAll() } - @ParameterizedTest - @MethodSource("readHandlerSuccessTestData") - fun handleRequest(testArgs: TestArgs) { + private fun handleRequest(testArgs: TestArgs) { every { b2BiClient.getTransformer(any()) } returns testArgs.apiResponse every { b2BiClient.listTagsForResource(any()) } returns testArgs.apiTags @@ -72,6 +70,18 @@ class ReadHandlerTest : AbstractTestBase() { assertThat(response.errorCode).isNull() } + @ParameterizedTest + @MethodSource("readHandlerSuccessLegacyTransformerTestData") + fun handleLegacyRequest(testArgs: TestArgs) = handleRequest(testArgs) + + @ParameterizedTest + @MethodSource("readHandlerSuccessInboundTransformerTestData") + fun handleInboundRequest(testArgs: TestArgs) = handleRequest(testArgs) + + @ParameterizedTest + @MethodSource("readHandlerSuccessOutboundTransformerTestData") + fun handleOutboundRequest(testArgs: TestArgs) = handleRequest(testArgs) + @Test fun handleRequest_throwsException() { every { @@ -101,13 +111,35 @@ class ReadHandlerTest : AbstractTestBase() { companion object { @JvmStatic - fun readHandlerSuccessTestData() = listOf( + fun readHandlerSuccessLegacyTransformerTestData() = listOf( TestArgs( - testName = "Read transformer with all fields.", + testName = "Read transformer with all legacy fields.", requestResourceModel = TEST_GET_TRANSFORMER_REQUEST_RESOURCE_MODEL, - apiResponse = TEST_GET_TRANSFORMER_RESPONSE_WITH_ALL_FIELDS, + apiResponse = TEST_GET_TRANSFORMER_RESPONSE_WITH_ALL_LEGACY_FIELDS, + apiTags = TEST_LIST_TAGS_FOR_RESOURCE_RESPONSE, + expectedResourceModel = TEST_GET_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS + ) + ) + + @JvmStatic + fun readHandlerSuccessInboundTransformerTestData() = listOf( + TestArgs( + testName = "Read transformer with all inbound fields.", + requestResourceModel = TEST_GET_INBOUND_TRANSFORMER_REQUEST_RESOURCE_MODEL, + apiResponse = TEST_GET_TRANSFORMER_RESPONSE_WITH_ALL_INBOUND_FIELDS, + apiTags = TEST_LIST_TAGS_FOR_RESOURCE_RESPONSE, + expectedResourceModel = TEST_GET_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS + ) + ) + + @JvmStatic + fun readHandlerSuccessOutboundTransformerTestData() = listOf( + TestArgs( + testName = "Read transformer with all outbound fields.", + requestResourceModel = TEST_GET_OUTBOUND_TRANSFORMER_REQUEST_RESOURCE_MODEL, + apiResponse = TEST_GET_TRANSFORMER_RESPONSE_WITH_ALL_OUTBOUND_FIELDS, apiTags = TEST_LIST_TAGS_FOR_RESOURCE_RESPONSE, - expectedResourceModel = TEST_GET_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS + expectedResourceModel = TEST_GET_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS ) ) } diff --git a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/TestData.kt b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/TestData.kt index 43d41ed..fbd75e3 100644 --- a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/TestData.kt +++ b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/TestData.kt @@ -1,16 +1,18 @@ package software.amazon.b2bi.transformer import software.amazon.awssdk.services.b2bi.model.CreateTransformerResponse -import software.amazon.awssdk.services.b2bi.model.CreateTransformerRequest import software.amazon.awssdk.services.b2bi.model.GetTransformerResponse import software.amazon.awssdk.services.b2bi.model.ListTransformersResponse import software.amazon.awssdk.services.b2bi.model.ListTagsForResourceResponse -import software.amazon.awssdk.services.b2bi.model.Logging import software.amazon.awssdk.services.b2bi.model.TransformerStatus import software.amazon.awssdk.services.b2bi.model.TransformerSummary import software.amazon.awssdk.services.b2bi.model.UpdateTransformerResponse import software.amazon.b2bi.transformer.TagHelper.toSdkTag import software.amazon.b2bi.transformer.Translator.translateToSdkEdi +import software.amazon.b2bi.transformer.Translator.translateToSdkInputConversion +import software.amazon.b2bi.transformer.Translator.translateToSdkMapping +import software.amazon.b2bi.transformer.Translator.translateToSdkOutputConversion +import software.amazon.b2bi.transformer.Translator.translateToSdkSampleDocuments import java.time.Instant @@ -19,7 +21,7 @@ const val TEST_TRANSACTION_SET = "test transaction" const val TEST_VERSION = "test version" val TEST_X12: X12Details = X12Details.builder().transactionSet(TEST_TRANSACTION_SET).version(TEST_VERSION).build() -//required +//required legacy fields const val TEST_NAME = "Test transformer name" const val TEST_FILE_FORMAT = "JSON" const val TEST_MAPPING_TEMPLATE = "test mapping template" @@ -27,11 +29,42 @@ val TEST_TRANSFORMER_STATUS = TransformerStatus.INACTIVE.toString() val TEST_RESOURCE_EDI_TYPE: EdiType = EdiType.builder().x12Details(TEST_X12).build() val TEST_SDK_EDI_TYPE = TEST_RESOURCE_EDI_TYPE.translateToSdkEdi() const val TEST_TRANSFORMER_ID = "t-12345678901234567" - const val TEST_TRANSFORMER_ARN = "Test transformer ARN" const val TEST_SAMPLE_DOC = "test/path" val TEST_INSTANT = Instant.now() +// required new fields +const val TEST_MAPPING_LANGUAGE = "JSONATA" +const val TEST_X12_FORMAT = "X12" +const val TEST_BUCKET_NAME = "test-s3-bucket" +const val TEST_INPUT_SAMPLE_DOC = "input-doc" +const val TEST_OUTPUT_SAMPLE_DOC = "output-doc" +val TEST_X12_DETAILS = X12Details.builder().transactionSet(TEST_TRANSACTION_SET).version(TEST_VERSION).build() +val TEST_FORMAT_OPTIONS = FormatOptions.builder() + .x12(TEST_X12_DETAILS) + .build() +val TEST_SAMPLE_DOC_KEYS = SampleDocumentKeys.builder() + .input(TEST_INPUT_SAMPLE_DOC) + .output(TEST_OUTPUT_SAMPLE_DOC) + .build() +val TEST_INPUT_CONVERSION = InputConversion.builder() + .fromFormat(TEST_X12_FORMAT) + .formatOptions(TEST_FORMAT_OPTIONS) + .build() +val TEST_SDK_INPUT_CONVERSION = TEST_INPUT_CONVERSION.translateToSdkInputConversion() +val TEST_OUTPUT_CONVERSION = OutputConversion.builder() + .toFormat(TEST_X12_FORMAT) + .formatOptions(TEST_FORMAT_OPTIONS) + .build() +val TEST_SDK_OUTPUT_CONVERSION = TEST_OUTPUT_CONVERSION.translateToSdkOutputConversion() +val TEST_MAPPING = Mapping.builder().templateLanguage(TEST_MAPPING_LANGUAGE).template(TEST_MAPPING_TEMPLATE).build() +val TEST_SDK_MAPPING = TEST_MAPPING.translateToSdkMapping() +val TEST_SAMPLE_DOCUMENTS = SampleDocuments.builder() + .bucketName(TEST_BUCKET_NAME) + .keys(listOf(TEST_SAMPLE_DOC_KEYS)) + .build() +val TEST_SDK_SAMPLE_DOCUMENTS = TEST_SAMPLE_DOCUMENTS.translateToSdkSampleDocuments() + // Tags val TEST_RESOURCE_TAG = Tag.builder() .key("testKey") @@ -42,8 +75,9 @@ val TEST_LIST_TAGS_FOR_RESOURCE_RESPONSE = ListTagsForResourceResponse.builder() .tags(TEST_RESOURCE_TAG.toSdkTag()) .build() +// This test data is used to test transformers with legacy fields // Create -val TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_FIELDS = ResourceModel.builder() +val TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_LEGACY_FIELDS = ResourceModel.builder() .name(TEST_NAME) .tags(emptyList()) .fileFormat(TEST_FILE_FORMAT) @@ -55,13 +89,13 @@ val TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_FIELDS = Resour .modifiedAt(TEST_INSTANT.toString()) .build() -val TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_FIELDS = - TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_FIELDS.toBuilder() +val TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS = + TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_LEGACY_FIELDS.toBuilder() .sampleDocument(TEST_SAMPLE_DOC) .tags(listOf(TEST_RESOURCE_TAG)) .build() -val TEST_CREATE_TRANSFORMER_RESPONSE_WITH_REQUIRED_FIELDS = CreateTransformerResponse.builder() +val TEST_CREATE_TRANSFORMER_RESPONSE_WITH_REQUIRED_LEGACY_FIELDS = CreateTransformerResponse.builder() .transformerId(TEST_TRANSFORMER_ID) .name(TEST_NAME) .fileFormat(TEST_FILE_FORMAT) @@ -73,8 +107,8 @@ val TEST_CREATE_TRANSFORMER_RESPONSE_WITH_REQUIRED_FIELDS = CreateTransformerRes .transformerArn(TEST_TRANSFORMER_ARN) .build() -val TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_FIELDS = - TEST_CREATE_TRANSFORMER_RESPONSE_WITH_REQUIRED_FIELDS.toBuilder() +val TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_LEGACY_FIELDS = + TEST_CREATE_TRANSFORMER_RESPONSE_WITH_REQUIRED_LEGACY_FIELDS.toBuilder() .sampleDocument(TEST_SAMPLE_DOC) .build() @@ -84,7 +118,7 @@ val TEST_DELETE_TRANSFORMER_REQUEST_RESOURCE_MODEL = ResourceModel.builder() .build() // List -val TEST_TRANSFORMER_SUMMARY_WITH_ALL_FIELDS = TransformerSummary.builder() +val TEST_TRANSFORMER_SUMMARY_WITH_ALL_LEGACY_FIELDS = TransformerSummary.builder() .transformerId(TEST_TRANSFORMER_ID) .name(TEST_NAME) .fileFormat(TEST_FILE_FORMAT) @@ -96,11 +130,11 @@ val TEST_TRANSFORMER_SUMMARY_WITH_ALL_FIELDS = TransformerSummary.builder() .status(TEST_TRANSFORMER_STATUS) .build() -val TEST_LIST_TRANSFORMERS_RESPONSE_WITH_ONE_TRANSFORMER_WITH_ALL_FIELDS = ListTransformersResponse.builder() - .transformers(TEST_TRANSFORMER_SUMMARY_WITH_ALL_FIELDS) +val TEST_LIST_TRANSFORMERS_RESPONSE_WITH_ONE_TRANSFORMER_WITH_ALL_LEGACY_FIELDS = ListTransformersResponse.builder() + .transformers(TEST_TRANSFORMER_SUMMARY_WITH_ALL_LEGACY_FIELDS) .build() -val TEST_LIST_TRANSFORMERS_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceModel.builder() +val TEST_LIST_TRANSFORMERS_RESPONSE_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS = ResourceModel.builder() .transformerId(TEST_TRANSFORMER_ID) .name(TEST_NAME) .fileFormat(TEST_FILE_FORMAT) @@ -116,7 +150,7 @@ val TEST_GET_TRANSFORMER_REQUEST_RESOURCE_MODEL = ResourceModel.builder() .transformerId(TEST_TRANSFORMER_ID) .build() -val TEST_GET_TRANSFORMER_RESPONSE_WITH_ALL_FIELDS = GetTransformerResponse.builder() +val TEST_GET_TRANSFORMER_RESPONSE_WITH_ALL_LEGACY_FIELDS = GetTransformerResponse.builder() .transformerId(TEST_TRANSFORMER_ID) .transformerArn(TEST_TRANSFORMER_ARN) .name(TEST_NAME) @@ -129,7 +163,7 @@ val TEST_GET_TRANSFORMER_RESPONSE_WITH_ALL_FIELDS = GetTransformerResponse.build .status(TEST_TRANSFORMER_STATUS) .build() -val TEST_GET_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceModel.builder() +val TEST_GET_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS = ResourceModel.builder() .transformerId(TEST_TRANSFORMER_ID) .transformerArn(TEST_TRANSFORMER_ARN) .name(TEST_NAME) @@ -144,7 +178,7 @@ val TEST_GET_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceModel .build() // Update -val TEST_UPDATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceModel.builder() +val TEST_UPDATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS = ResourceModel.builder() .transformerId(TEST_TRANSFORMER_ID) .name(TEST_NAME) .ediType(TEST_RESOURCE_EDI_TYPE) @@ -154,7 +188,7 @@ val TEST_UPDATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceMod .status(TEST_TRANSFORMER_STATUS) .build() -val TEST_UPDATE_TRANSFORMER_RESPONSE_WITH_ALL_FIELDS = UpdateTransformerResponse.builder() +val TEST_UPDATE_TRANSFORMER_RESPONSE_WITH_ALL_LEGACY_FIELDS = UpdateTransformerResponse.builder() .transformerId(TEST_TRANSFORMER_ID) .name(TEST_NAME) .ediType(TEST_SDK_EDI_TYPE) @@ -167,7 +201,7 @@ val TEST_UPDATE_TRANSFORMER_RESPONSE_WITH_ALL_FIELDS = UpdateTransformerResponse .status(TEST_TRANSFORMER_STATUS) .build() -val TEST_UPDATE_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceModel.builder() +val TEST_UPDATE_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS = ResourceModel.builder() .transformerId(TEST_TRANSFORMER_ID) .name(TEST_NAME) .ediType(TEST_RESOURCE_EDI_TYPE) @@ -180,3 +214,242 @@ val TEST_UPDATE_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS = ResourceMo .status(TEST_TRANSFORMER_STATUS) .tags(emptyList()) .build() + +// This test data is used to test transformers with new fields +// Create +val TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_INBOUND_FIELDS = ResourceModel.builder() + .name(TEST_NAME) + .inputConversion(TEST_INPUT_CONVERSION) + .mapping(TEST_MAPPING) + .tags(emptyList()) + .status(TEST_TRANSFORMER_STATUS) + .tags(emptyList()) + .createdAt(TEST_INSTANT.toString()) + .modifiedAt(TEST_INSTANT.toString()) + .build() + +val TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS = + TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_INBOUND_FIELDS.toBuilder() + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .tags(listOf(TEST_RESOURCE_TAG)) + .build() + +val TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_INBOUND_FIELDS = CreateTransformerResponse.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .inputConversion(TEST_SDK_INPUT_CONVERSION) + .mapping(TEST_SDK_MAPPING) + .sampleDocuments(TEST_SDK_SAMPLE_DOCUMENTS) + .createdAt(TEST_INSTANT) + .status(TEST_TRANSFORMER_STATUS) + .transformerArn(TEST_TRANSFORMER_ARN) + .build() + +val TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_OUTBOUND_FIELDS = ResourceModel.builder() + .name(TEST_NAME) + .outputConversion(TEST_OUTPUT_CONVERSION) + .mapping(TEST_MAPPING) + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .tags(emptyList()) + .status(TEST_TRANSFORMER_STATUS) + .tags(emptyList()) + .createdAt(TEST_INSTANT.toString()) + .modifiedAt(TEST_INSTANT.toString()) + .build() + +val TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS = + TEST_CREATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_REQUIRED_OUTBOUND_FIELDS.toBuilder() + .tags(listOf(TEST_RESOURCE_TAG)) + .build() + +val TEST_CREATE_TRANSFORMER_RESPONSE_WITH_ALL_OUTBOUND_FIELDS = CreateTransformerResponse.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .outputConversion(TEST_SDK_OUTPUT_CONVERSION) + .mapping(TEST_SDK_MAPPING) + .sampleDocuments(TEST_SDK_SAMPLE_DOCUMENTS) + .createdAt(TEST_INSTANT) + .status(TEST_TRANSFORMER_STATUS) + .transformerArn(TEST_TRANSFORMER_ARN) + .build() + +// List +val TEST_TRANSFORMER_SUMMARY_WITH_ALL_INBOUND_FIELDS = TransformerSummary.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .inputConversion(TEST_SDK_INPUT_CONVERSION) + .mapping(TEST_SDK_MAPPING) + .sampleDocuments(TEST_SDK_SAMPLE_DOCUMENTS) + .status(TEST_TRANSFORMER_STATUS) + .createdAt(TEST_INSTANT) + .modifiedAt(TEST_INSTANT) + .build() + +val TEST_LIST_TRANSFORMERS_RESPONSE_WITH_ONE_TRANSFORMER_WITH_ALL_INBOUND_FIELDS = ListTransformersResponse.builder() + .transformers(TEST_TRANSFORMER_SUMMARY_WITH_ALL_INBOUND_FIELDS) + .build() + +val TEST_LIST_TRANSFORMERS_RESPONSE_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .inputConversion(TEST_INPUT_CONVERSION) + .mapping(TEST_MAPPING) + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .createdAt(TEST_INSTANT.toString()) + .modifiedAt(TEST_INSTANT.toString()) + .status(TEST_TRANSFORMER_STATUS) + .build() + +val TEST_TRANSFORMER_SUMMARY_WITH_ALL_OUTBOUND_FIELDS = TransformerSummary.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .outputConversion(TEST_SDK_OUTPUT_CONVERSION) + .mapping(TEST_SDK_MAPPING) + .sampleDocuments(TEST_SDK_SAMPLE_DOCUMENTS) + .status(TEST_TRANSFORMER_STATUS) + .createdAt(TEST_INSTANT) + .modifiedAt(TEST_INSTANT) + .build() + +val TEST_LIST_TRANSFORMERS_RESPONSE_WITH_ONE_TRANSFORMER_WITH_ALL_OUTBOUND_FIELDS = ListTransformersResponse.builder() + .transformers(TEST_TRANSFORMER_SUMMARY_WITH_ALL_OUTBOUND_FIELDS) + .build() + +val TEST_LIST_TRANSFORMERS_RESPONSE_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .outputConversion(TEST_OUTPUT_CONVERSION) + .mapping(TEST_MAPPING) + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .createdAt(TEST_INSTANT.toString()) + .modifiedAt(TEST_INSTANT.toString()) + .status(TEST_TRANSFORMER_STATUS) + .build() + +// READ +val TEST_GET_INBOUND_TRANSFORMER_REQUEST_RESOURCE_MODEL = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .build() + +val TEST_GET_OUTBOUND_TRANSFORMER_REQUEST_RESOURCE_MODEL = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .build() + +val TEST_GET_TRANSFORMER_RESPONSE_WITH_ALL_INBOUND_FIELDS = GetTransformerResponse.builder() + .transformerId(TEST_TRANSFORMER_ID) + .transformerArn(TEST_TRANSFORMER_ARN) + .name(TEST_NAME) + .inputConversion(TEST_SDK_INPUT_CONVERSION) + .mapping(TEST_SDK_MAPPING) + .sampleDocuments(TEST_SDK_SAMPLE_DOCUMENTS) + .createdAt(TEST_INSTANT) + .modifiedAt(TEST_INSTANT) + .status(TEST_TRANSFORMER_STATUS) + .build() + +val TEST_GET_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .transformerArn(TEST_TRANSFORMER_ARN) + .name(TEST_NAME) + .inputConversion(TEST_INPUT_CONVERSION) + .mapping(TEST_MAPPING) + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .tags(listOf(TEST_RESOURCE_TAG)) + .createdAt(TEST_INSTANT.toString()) + .modifiedAt(TEST_INSTANT.toString()) + .status(TEST_TRANSFORMER_STATUS) + .build() + +val TEST_GET_TRANSFORMER_RESPONSE_WITH_ALL_OUTBOUND_FIELDS = GetTransformerResponse.builder() + .transformerId(TEST_TRANSFORMER_ID) + .transformerArn(TEST_TRANSFORMER_ARN) + .name(TEST_NAME) + .outputConversion(TEST_SDK_OUTPUT_CONVERSION) + .mapping(TEST_SDK_MAPPING) + .sampleDocuments(TEST_SDK_SAMPLE_DOCUMENTS) + .createdAt(TEST_INSTANT) + .modifiedAt(TEST_INSTANT) + .status(TEST_TRANSFORMER_STATUS) + .build() + +val TEST_GET_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .transformerArn(TEST_TRANSFORMER_ARN) + .name(TEST_NAME) + .outputConversion(TEST_OUTPUT_CONVERSION) + .mapping(TEST_MAPPING) + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .tags(listOf(TEST_RESOURCE_TAG)) + .createdAt(TEST_INSTANT.toString()) + .modifiedAt(TEST_INSTANT.toString()) + .status(TEST_TRANSFORMER_STATUS) + .build() + +// Update +val TEST_UPDATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .inputConversion(TEST_INPUT_CONVERSION) + .mapping(TEST_MAPPING) + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .status(TEST_TRANSFORMER_STATUS) + .build() + +val TEST_UPDATE_TRANSFORMER_RESPONSE_WITH_ALL_INBOUND_FIELDS = UpdateTransformerResponse.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .inputConversion(TEST_SDK_INPUT_CONVERSION) + .mapping(TEST_SDK_MAPPING) + .sampleDocuments(TEST_SDK_SAMPLE_DOCUMENTS) + .createdAt(TEST_INSTANT) + .modifiedAt(TEST_INSTANT) + .transformerArn(TEST_TRANSFORMER_ARN) + .status(TEST_TRANSFORMER_STATUS) + .build() + +val TEST_UPDATE_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .inputConversion(TEST_INPUT_CONVERSION) + .mapping(TEST_MAPPING) + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .transformerArn(TEST_TRANSFORMER_ARN) + .modifiedAt(TEST_INSTANT.toString()) + .createdAt(TEST_INSTANT.toString()) + .status(TEST_TRANSFORMER_STATUS) + .tags(emptyList()) + .build() + +val TEST_UPDATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .outputConversion(TEST_OUTPUT_CONVERSION) + .mapping(TEST_MAPPING) + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .status(TEST_TRANSFORMER_STATUS) + .build() + +val TEST_UPDATE_TRANSFORMER_RESPONSE_WITH_ALL_OUTBOUND_FIELDS = UpdateTransformerResponse.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .outputConversion(TEST_SDK_OUTPUT_CONVERSION) + .mapping(TEST_SDK_MAPPING) + .sampleDocuments(TEST_SDK_SAMPLE_DOCUMENTS) + .createdAt(TEST_INSTANT) + .modifiedAt(TEST_INSTANT) + .transformerArn(TEST_TRANSFORMER_ARN) + .status(TEST_TRANSFORMER_STATUS) + .build() + +val TEST_UPDATE_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS = ResourceModel.builder() + .transformerId(TEST_TRANSFORMER_ID) + .name(TEST_NAME) + .outputConversion(TEST_OUTPUT_CONVERSION) + .mapping(TEST_MAPPING) + .sampleDocuments(TEST_SAMPLE_DOCUMENTS) + .transformerArn(TEST_TRANSFORMER_ARN) + .modifiedAt(TEST_INSTANT.toString()) + .createdAt(TEST_INSTANT.toString()) + .status(TEST_TRANSFORMER_STATUS) + .tags(emptyList()) + .build() diff --git a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/UpdateHandlerTest.kt b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/UpdateHandlerTest.kt index 6d9851d..2a1a9e2 100644 --- a/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/UpdateHandlerTest.kt +++ b/aws-b2bi-transformer/src/test/kotlin/software/amazon/b2bi/transformer/UpdateHandlerTest.kt @@ -46,9 +46,7 @@ class UpdateHandlerTest : AbstractTestBase() { unmockkAll() } - @ParameterizedTest - @MethodSource("updateHandlerSuccessTestData") - fun handleRequest(testArgs: TestArgs) { + private fun handleRequest(testArgs: TestArgs) { every { b2BiClient.updateTransformer(any()) } returns testArgs.apiResponse val request = ResourceHandlerRequest.builder() @@ -68,6 +66,18 @@ class UpdateHandlerTest : AbstractTestBase() { assertThat(response.errorCode).isNull() } + @ParameterizedTest + @MethodSource("updateHandlerSuccessLegacyTransformerTestData") + fun handleLegacyRequest(testArgs: TestArgs) = handleRequest(testArgs) + + @ParameterizedTest + @MethodSource("updateHandlerSuccessInboundTransformerTestData") + fun handleInboundRequest(testArgs: TestArgs) = handleRequest(testArgs) + + @ParameterizedTest + @MethodSource("updateHandlerSuccessOutboundTransformerTestData") + fun handleOutboundRequest(testArgs: TestArgs) = handleRequest(testArgs) + private fun UpdateHandler.handleRequest( request: ResourceHandlerRequest ): ProgressEvent { @@ -86,15 +96,41 @@ class UpdateHandlerTest : AbstractTestBase() { companion object { @JvmStatic - fun updateHandlerSuccessTestData() = listOf( + fun updateHandlerSuccessLegacyTransformerTestData() = listOf( + TestArgs( + testName = "Update transformer with all updatable legacy fields.", + requestDesiredResourceModel = TEST_UPDATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS, + requestPreviousResourceModel = ResourceModel(), + requestDesiredResourceTags = emptyMap(), + requestPreviousResourceTags = emptyMap(), + apiResponse = TEST_UPDATE_TRANSFORMER_RESPONSE_WITH_ALL_LEGACY_FIELDS, + expectedResourceModel = TEST_UPDATE_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_LEGACY_FIELDS + ) + ) + + @JvmStatic + fun updateHandlerSuccessInboundTransformerTestData() = listOf( + TestArgs( + testName = "Update transformer with all updatable inbound fields.", + requestDesiredResourceModel = TEST_UPDATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS, + requestPreviousResourceModel = ResourceModel(), + requestDesiredResourceTags = emptyMap(), + requestPreviousResourceTags = emptyMap(), + apiResponse = TEST_UPDATE_TRANSFORMER_RESPONSE_WITH_ALL_INBOUND_FIELDS, + expectedResourceModel = TEST_UPDATE_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_INBOUND_FIELDS + ) + ) + + @JvmStatic + fun updateHandlerSuccessOutboundTransformerTestData() = listOf( TestArgs( - testName = "Update transformer with all updatable fields.", - requestDesiredResourceModel = TEST_UPDATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_FIELDS, + testName = "Update transformer with all updatable outbound fields.", + requestDesiredResourceModel = TEST_UPDATE_TRANSFORMER_REQUEST_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS, requestPreviousResourceModel = ResourceModel(), requestDesiredResourceTags = emptyMap(), requestPreviousResourceTags = emptyMap(), - apiResponse = TEST_UPDATE_TRANSFORMER_RESPONSE_WITH_ALL_FIELDS, - expectedResourceModel = TEST_UPDATE_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_FIELDS + apiResponse = TEST_UPDATE_TRANSFORMER_RESPONSE_WITH_ALL_OUTBOUND_FIELDS, + expectedResourceModel = TEST_UPDATE_TRANSFORMER_RESPONSE_RESOURCE_MODEL_WITH_ALL_OUTBOUND_FIELDS ) ) }