Repository: ChristopheBougere/asl-validator
Pull request #134 (2023-05-01 04:40:07)

Bugfix/130 item batcher validation
I made a mess of the rebase on the old PR (https://github.com/ChristopheBougere/asl-validator/pull/131), so this is a clean implementation using the `path` property to specify nested items.


Patch:
diff --git a/src/schemas/map.json b/src/schemas/map.json
index 86ea086..f7a3965 100644
--- a/src/schemas/map.json
+++ b/src/schemas/map.json
@@ -114,26 +114,28 @@
     "ItemSelector": {
       "$ref": "paths.json#/definitions/asl_payload_template"
     },
-    "ItemBatcher":{
+    "ItemBatcher": {
       "type": "object",
-      "oneOf": [
-        {
-          "type": "object",
-          "properties": {
-            "MaxItemsPerBatch": {
-              "type": "number"
-            }
-          }
+      "properties": {
+        "MaxItemsPerBatch": {
+          "type": "number",
+          "minimum": 0
         },
-        {
-          "type": "object",
-          "properties": {
-            "MaxItemsPerBatchPath": {
-              "$ref": "paths.json#/definitions/asl_ref_path"
-            }
-          }
+        "MaxItemsPerBatchPath": {
+          "$ref": "paths.json#/definitions/asl_ref_path"
+        },
+        "MaxInputBytesPerBatch": {
+          "type": "number",
+          "minimum": 0,
+          "maximum": 262144
+        },
+        "MaxInputBytesPerBatchPath": {
+          "$ref": "paths.json#/definitions/asl_ref_path"
+        },
+        "BatchInput": {
+          "$ref": "paths.json#/definitions/asl_payload_template"
         }
-      ]
+      }
     },
     "ResultSelector": {
       "$ref": "paths.json#/definitions/asl_payload_template"
diff --git a/src/types.ts b/src/types.ts
index 212acbe..ca5626d 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -18,6 +18,7 @@ export enum StateMachineErrorCode {
   TaskHeartbeatError = 'TASK_HEARTBEAT',
   MapItemProcessorError = 'MAP_ITEM_PROCESSOR',
   MapItemSelectorError = 'MAP_ITEM_SELECTOR',
+  MapItemBatcherError = 'MAP_ITEM_BATCHER',
   MapToleratedFailureError = 'MAP_TOLERATED_FAILURE',
   MapMaxConcurrencyError = 'MAP_CONCURRENCY_ERROR',
   MapItemReaderMaxItemsError = 'MAP_ITEMREADER_MAXITEM'
diff --git a/src/validator.ts b/src/validator.ts
index 477745d..ce4449c 100644
--- a/src/validator.ts
+++ b/src/validator.ts
@@ -110,6 +110,20 @@ export = function validator(definition: StateMachine, opts?: ValidationOptions):
                     errorCode: StateMachineErrorCode.MapItemReaderMaxItemsError
                 })
             },
+            {
+                filter: IsMap,
+                checker: AtMostOne({
+                    props: ["MaxItemsPerBatch", "MaxItemsPerBatchPath"],
+                    path: "$.ItemBatcher",
+                    errorCode: StateMachineErrorCode.MapItemBatcherError})
+            },
+            {
+                filter: IsMap,
+                checker: AtMostOne({
+                    props: ["MaxInputBytesPerBatch", "MaxInputBytesPerBatchPath"],
+                    path: "$.ItemBatcher",
+                    errorCode: StateMachineErrorCode.MapItemBatcherError})
+            },
         ]))
     }
 


Test patch:
diff --git a/src/__tests__/definitions/invalid-map-item-batcher-dupe-subfields.json b/src/__tests__/definitions/invalid-map-item-batcher-dupe-subfields.json
new file mode 100644
index 0000000..646a3b9
--- /dev/null
+++ b/src/__tests__/definitions/invalid-map-item-batcher-dupe-subfields.json
@@ -0,0 +1,36 @@
+{
+  "Comment": "ItemBatcher can specify batchSize or path but not both",
+  "StartAt": "Map",
+  "States": {
+    "Map": {
+      "Type": "Map",
+      "ItemBatcher": {
+        "MaxItemsPerBatch": 2,
+        "MaxItemsPerBatchPath": "$.batchByes",
+        "MaxInputBytesPerBatch": 131072,
+        "MaxInputBytesPerBatchPath": "$.batchByes"
+      },
+      "ItemProcessor": {
+        "ProcessorConfig": {
+          "Mode": "DISTRIBUTED",
+          "ExecutionType": "EXPRESS"
+        },
+        "StartAt": "LambdaTask",
+        "States": {
+          "LambdaTask": {
+            "Type": "Task",
+            "Resource": "arn:aws:states:::lambda:invoke",
+            "OutputPath": "$.Payload",
+            "Parameters": {
+              "Payload.$": "$",
+              "FunctionName": "arn:aws:lambda:us-east-2:123456789012:function:processCSVData"
+            },
+            "End": true
+          }
+        }
+      },
+      "Label": "Map",
+      "End": true
+    }
+  }
+}
diff --git a/src/__tests__/definitions/valid-map-with-item-batcher.json b/src/__tests__/definitions/valid-map-with-item-batcher.json
new file mode 100644
index 0000000..2c0e1d5
--- /dev/null
+++ b/src/__tests__/definitions/valid-map-with-item-batcher.json
@@ -0,0 +1,37 @@
+{
+  "Comment": "ItemBatcher can specify batchSize or path but not both",
+  "StartAt": "Map",
+  "States": {
+    "Map": {
+      "Type": "Map",
+      "ItemBatcher": {
+        "MaxItemsPerBatch": 2,
+        "MaxInputBytesPerBatch": 131072,
+        "BatchInput": {
+          "inputKey": "inputValue"
+        }
+      },
+      "ItemProcessor": {
+        "ProcessorConfig": {
+          "Mode": "DISTRIBUTED",
+          "ExecutionType": "EXPRESS"
+        },
+        "StartAt": "LambdaTask",
+        "States": {
+          "LambdaTask": {
+            "Type": "Task",
+            "Resource": "arn:aws:states:::lambda:invoke",
+            "OutputPath": "$.Payload",
+            "Parameters": {
+              "Payload.$": "$",
+              "FunctionName": "arn:aws:lambda:us-east-2:123456789012:function:processCSVData"
+            },
+            "End": true
+          }
+        }
+      },
+      "Label": "Map",
+      "End": true
+    }
+  }
+}