From 4c1bb3bdaf66040e932070d52aea1f4163d4a27d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tayfun=20Y=C4=B1lmaz?= Date: Fri, 6 Feb 2026 09:29:23 +0300 Subject: [PATCH 1/4] update --- .../task-test/test-get-instance-data.json | 2 +- core/Tasks/task-test/test-subprocess.json | 5 +- .../account-opening-workflow.json | 2 +- .../src/TriggerGetInstanceTaskMapping.csx | 2 +- .../task-test/src/SubProcessMapping.csx | 4 +- .../task-test/task-test-workflow.json | 2 +- mockoon/migration-api.json | 294 +++++++++--------- 7 files changed, 156 insertions(+), 155 deletions(-) diff --git a/core/Tasks/task-test/test-get-instance-data.json b/core/Tasks/task-test/test-get-instance-data.json index d6e5be6..b9460f6 100644 --- a/core/Tasks/task-test/test-get-instance-data.json +++ b/core/Tasks/task-test/test-get-instance-data.json @@ -13,7 +13,7 @@ "attributes": { "type": "13", "config": { - "domain": "core", + "domain": "onboarding", "flow": "task-test-subflow", "extensions": [] } diff --git a/core/Tasks/task-test/test-subprocess.json b/core/Tasks/task-test/test-subprocess.json index d1de4cc..cc93e57 100644 --- a/core/Tasks/task-test/test-subprocess.json +++ b/core/Tasks/task-test/test-subprocess.json @@ -13,10 +13,11 @@ "attributes": { "type": "14", "config": { - "domain": "core", + "domain": "contract", "flow": "task-test-subflow", "version": "1.0.0", - "body": {} + "body": {}, + "validateSsl": false } } } diff --git a/core/Workflows/account-opening/account-opening-workflow.json b/core/Workflows/account-opening/account-opening-workflow.json index 386e89f..34bacc8 100644 --- a/core/Workflows/account-opening/account-opening-workflow.json +++ b/core/Workflows/account-opening/account-opening-workflow.json @@ -152,7 +152,7 @@ }, "mapping": { "location": "./src/TriggerGetInstanceTaskMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgU3lzdGVtLlRleHQuSnNvbjsKCnB1YmxpYyBjbGFzcyBUcmlnZ2VyR2V0SW5zdGFuY2VUYXNrTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgdHJpZ2dlclRhc2sgPSAodGFzayBhcyBHZXRJbnN0YW5jZURhdGFUYXNrKSE7CiAgICAgICAKICAgICAgICB0cmlnZ2VyVGFzay5TZXRJbnN0YW5jZShjb250ZXh0Lkluc3RhbmNlLkRhdGEub2xkSW5zdGFuY2VJZCk7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpCiAgICAgICAgewogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG9sZEluc3RhbmNlPWNvbnRleHQuQm9keSwKICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlCiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KfQoKcHVibGljIGNsYXNzIFJlcXVlc3RNb2RlbAp7CiAgICBwdWJsaWMgc3RyaW5nIGtleSB7IGdldDsgc2V0OyB9CiAgICBwdWJsaWMgZHluYW1pYyAgYXR0cmlidXRlcyB7IGdldDsgc2V0OyB9Cn0=" + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgU3lzdGVtLlRleHQuSnNvbjsKCnB1YmxpYyBjbGFzcyBUcmlnZ2VyR2V0SW5zdGFuY2VUYXNrTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgdHJpZ2dlclRhc2sgPSAodGFzayBhcyBHZXRJbnN0YW5jZURhdGFUYXNrKSE7CiAgICAgICAKICAgICAgICB0cmlnZ2VyVGFzay5TZXRJbnN0YW5jZShjb250ZXh0Lkluc3RhbmNlLkRhdGEub2xkSW5zdGFuY2VJZHMpOwogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKQogICAgICAgIHsKICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBvbGRJbnN0YW5jZT1jb250ZXh0LkJvZHksCiAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9Cn0KCnB1YmxpYyBjbGFzcyBSZXF1ZXN0TW9kZWwKewogICAgcHVibGljIHN0cmluZyBrZXkgeyBnZXQ7IHNldDsgfQogICAgcHVibGljIGR5bmFtaWMgIGF0dHJpYnV0ZXMgeyBnZXQ7IHNldDsgfQp9" } } ] diff --git a/core/Workflows/account-opening/src/TriggerGetInstanceTaskMapping.csx b/core/Workflows/account-opening/src/TriggerGetInstanceTaskMapping.csx index cefdfc3..962b3e4 100644 --- a/core/Workflows/account-opening/src/TriggerGetInstanceTaskMapping.csx +++ b/core/Workflows/account-opening/src/TriggerGetInstanceTaskMapping.csx @@ -8,7 +8,7 @@ public class TriggerGetInstanceTaskMapping : IMapping { var triggerTask = (task as GetInstanceDataTask)!; - triggerTask.SetInstance(context.Instance.Data.oldInstanceId); + triggerTask.SetInstance(context.Instance.Data.oldInstanceIds); return Task.FromResult(new ScriptResponse()); } diff --git a/core/Workflows/task-test/src/SubProcessMapping.csx b/core/Workflows/task-test/src/SubProcessMapping.csx index de4fcba..ddcd09e 100644 --- a/core/Workflows/task-test/src/SubProcessMapping.csx +++ b/core/Workflows/task-test/src/SubProcessMapping.csx @@ -20,8 +20,8 @@ public class SubProcessMapping : IMapping } // Configure subprocess - subProcessTask.SetDomain("core"); - subProcessTask.SetFlow("task-test-subflow"); + //subProcessTask.SetDomain("core"); + //subProcessTask.SetFlow("task-test-subflow"); subProcessTask.SetKey(context.Instance?.Key ?? Guid.NewGuid().ToString()); subProcessTask.SetTags(new[] { "task-test", "subprocess", "success" }); diff --git a/core/Workflows/task-test/task-test-workflow.json b/core/Workflows/task-test/task-test-workflow.json index d556ca8..4ef3b21 100644 --- a/core/Workflows/task-test/task-test-workflow.json +++ b/core/Workflows/task-test/task-test-workflow.json @@ -843,7 +843,7 @@ }, "mapping": { "location": "./src/SubProcessMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTdWJQcm9jZXNzIFRhc2sgTWFwcGluZyAtIFN0YXJ0cyBhIGZpcmUtYW5kLWZvcmdldCBzdWJwcm9jZXNzCi8vLyBUZXN0IGNhc2U6IFZlcmlmeSBzdWJwcm9jZXNzIGxhdW5jaGluZyAobm9uLWJsb2NraW5nKQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgU3ViUHJvY2Vzc01hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgc3ViUHJvY2Vzc1Rhc2sgPSB0YXNrIGFzIFN1YlByb2Nlc3NUYXNrOwogICAgICAgICAgICBpZiAoc3ViUHJvY2Vzc1Rhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIFN1YlByb2Nlc3NUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBzdWJwcm9jZXNzCiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldERvbWFpbigiY29yZSIpOwogICAgICAgICAgICBzdWJQcm9jZXNzVGFzay5TZXRGbG93KCJ0YXNrLXRlc3Qtc3ViZmxvdyIpOwogICAgICAgICAgICBzdWJQcm9jZXNzVGFzay5TZXRLZXkoY29udGV4dC5JbnN0YW5jZT8uS2V5ID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCkpOwogICAgICAgICAgICBzdWJQcm9jZXNzVGFzay5TZXRUYWdzKG5ld1tdIHsgInRhc2stdGVzdCIsICJzdWJwcm9jZXNzIiwgInN1Y2Nlc3MiIH0pOwoKICAgICAgICAgICAgLy8gUHJlcGFyZSBzdWJwcm9jZXNzIGRhdGEKICAgICAgICAgICAgdmFyIHN1YlByb2Nlc3NCb2R5ID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHBhcmVudEluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgIHBhcmVudFdvcmtmbG93SWQgPSBjb250ZXh0LldvcmtmbG93LktleSwKICAgICAgICAgICAgICAgIHRlc3RJZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRlc3RJZCA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgbGF1bmNoZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIGxhdW5jaGVkQnkgPSAidGFzay10ZXN0LXdvcmtmbG93IiwKICAgICAgICAgICAgICAgIGlzRmlyZUFuZEZvcmdldCA9IHRydWUsCiAgICAgICAgICAgICAgICBtZXNzYWdlID0gIlN1YlByb2Nlc3MgdGVzdCAtIGZpcmUtYW5kLWZvcmdldCBpbnN0YW5jZSIKICAgICAgICAgICAgfTsKICAgICAgICAgICAgc3ViUHJvY2Vzc1Rhc2suU2V0Qm9keShzdWJQcm9jZXNzQm9keSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzdWJwcm9jZXNzLWlucHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwoKICAgICAgICAgICAgaWYgKHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPT0gdHJ1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJzdWJwcm9jZXNzLXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YlByb2Nlc3NSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJQcm9jZXNzSW5zdGFuY2VJZCA9IHJlc3BvbnNlPy5kYXRhPy5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdW5jaGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJTdWJQcm9jZXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGUgPSAiRmlyZS1hbmQtZm9yZ2V0OiBQYXJlbnQgd29ya2Zsb3cgZG9lcyBub3Qgd2FpdCBmb3Igc3VicHJvY2VzcyBjb21wbGV0aW9uIgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgInN1YnByb2Nlc3MiLCAic3VjY2VzcyIsICJmaXJlLWFuZC1mb3JnZXQiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInN1YnByb2Nlc3MtZmFpbGVkIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWJQcm9jZXNzUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gcmVzcG9uc2U/LmVycm9yTWVzc2FnZSA/PyAiRmFpbGVkIHRvIGxhdW5jaCBzdWJwcm9jZXNzIiwKICAgICAgICAgICAgICAgICAgICAgICAgZmFpbGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIlN1YlByb2Nlc3MiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJ0YXNrLXRlc3QiLCAic3VicHJvY2VzcyIsICJmYWlsZWQiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInN1YnByb2Nlc3MtZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWJQcm9jZXNzUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiU3ViUHJvY2VzcyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTdWJQcm9jZXNzIFRhc2sgTWFwcGluZyAtIFN0YXJ0cyBhIGZpcmUtYW5kLWZvcmdldCBzdWJwcm9jZXNzCi8vLyBUZXN0IGNhc2U6IFZlcmlmeSBzdWJwcm9jZXNzIGxhdW5jaGluZyAobm9uLWJsb2NraW5nKQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgU3ViUHJvY2Vzc01hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgc3ViUHJvY2Vzc1Rhc2sgPSB0YXNrIGFzIFN1YlByb2Nlc3NUYXNrOwogICAgICAgICAgICBpZiAoc3ViUHJvY2Vzc1Rhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIFN1YlByb2Nlc3NUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBzdWJwcm9jZXNzCiAgICAgICAgICAgIC8vc3ViUHJvY2Vzc1Rhc2suU2V0RG9tYWluKCJjb3JlIik7CiAgICAgICAgICAgIC8vc3ViUHJvY2Vzc1Rhc2suU2V0RmxvdygidGFzay10ZXN0LXN1YmZsb3ciKTsKICAgICAgICAgICAgc3ViUHJvY2Vzc1Rhc2suU2V0S2V5KGNvbnRleHQuSW5zdGFuY2U/LktleSA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpKTsKICAgICAgICAgICAgc3ViUHJvY2Vzc1Rhc2suU2V0VGFncyhuZXdbXSB7ICJ0YXNrLXRlc3QiLCAic3VicHJvY2VzcyIsICJzdWNjZXNzIiB9KTsKCiAgICAgICAgICAgIC8vIFByZXBhcmUgc3VicHJvY2VzcyBkYXRhCiAgICAgICAgICAgIHZhciBzdWJQcm9jZXNzQm9keSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwYXJlbnRJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICBwYXJlbnRXb3JrZmxvd0lkID0gY29udGV4dC5Xb3JrZmxvdy5LZXksCiAgICAgICAgICAgICAgICB0ZXN0SWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50ZXN0SWQgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIGxhdW5jaGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICBsYXVuY2hlZEJ5ID0gInRhc2stdGVzdC13b3JrZmxvdyIsCiAgICAgICAgICAgICAgICBpc0ZpcmVBbmRGb3JnZXQgPSB0cnVlLAogICAgICAgICAgICAgICAgbWVzc2FnZSA9ICJTdWJQcm9jZXNzIHRlc3QgLSBmaXJlLWFuZC1mb3JnZXQgaW5zdGFuY2UiCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldEJvZHkoc3ViUHJvY2Vzc0JvZHkpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAic3VicHJvY2Vzcy1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgICAgIGlmIChyZXNwb25zZT8uaXNTdWNjZXNzID09IHRydWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAic3VicHJvY2Vzcy1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWJQcm9jZXNzUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViUHJvY2Vzc0luc3RhbmNlSWQgPSByZXNwb25zZT8uZGF0YT8uaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXVuY2hlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiU3ViUHJvY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlID0gIkZpcmUtYW5kLWZvcmdldDogUGFyZW50IHdvcmtmbG93IGRvZXMgbm90IHdhaXQgZm9yIHN1YnByb2Nlc3MgY29tcGxldGlvbiIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJzdWJwcm9jZXNzIiwgInN1Y2Nlc3MiLCAiZmlyZS1hbmQtZm9yZ2V0IiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzdWJwcm9jZXNzLWZhaWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3ViUHJvY2Vzc1Jlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IHJlc3BvbnNlPy5lcnJvck1lc3NhZ2UgPz8gIkZhaWxlZCB0byBsYXVuY2ggc3VicHJvY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZhaWxlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJTdWJQcm9jZXNzIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgInN1YnByb2Nlc3MiLCAiZmFpbGVkIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzdWJwcm9jZXNzLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3ViUHJvY2Vzc1Jlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIlN1YlByb2Nlc3MiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" } } ], diff --git a/mockoon/migration-api.json b/mockoon/migration-api.json index d164289..73eff30 100644 --- a/mockoon/migration-api.json +++ b/mockoon/migration-api.json @@ -1,5 +1,5 @@ { - "uuid": "cc2c7a20-cf65-4f34-bdeb-6bbd3e3f9525", + "uuid": "0814e199-9bdb-48b0-9128-4679e3c257b1", "lastMigration": 33, "name": "vNext - Sample Api Mock", "endpointPrefix": "", @@ -8,204 +8,204 @@ "hostname": "localhost", "folders": [ { - "uuid": "46fb060c-5347-41f5-809e-86e40337f2fa", + "uuid": "eceef4f3-226b-4d95-b385-451288693d58", "name": "ouath2", "children": [ { "type": "route", - "uuid": "8ba61c4a-f251-47ef-a4a6-92398c4d66ef" + "uuid": "a2478fee-19cd-4bb9-90bc-ba71d2212aed" }, { "type": "route", - "uuid": "41dbf3e6-de0a-460e-879b-614d59ff813f" + "uuid": "f0613120-c84b-4e6b-9105-e3c4821223b9" }, { "type": "route", - "uuid": "2c335800-21d9-4ea7-bad3-e5e6ae8af460" + "uuid": "245bc071-8c44-4764-a1fb-ebaecd939dfd" }, { "type": "route", - "uuid": "95eecaa5-c860-4be1-87b7-22c96833e35e" + "uuid": "08f6d62d-e6e0-46a5-a892-4a92bc1fc9db" }, { "type": "route", - "uuid": "8bf14db4-9693-4511-8a8c-c4129661c76b" + "uuid": "a435af01-7c28-4efb-96e5-73057296a5e3" }, { "type": "route", - "uuid": "8d1c1536-9e82-4cb1-9349-79852ef6131b" + "uuid": "07100aa8-2f4f-4b2e-8378-c75d3bd8199d" }, { "type": "route", - "uuid": "aac5c06b-6c01-4fda-a241-ebfdbf4c5045" + "uuid": "bbc31e7e-8753-4e84-97c6-2d27ed877a66" }, { "type": "route", - "uuid": "ca026001-69e8-41c9-9dfc-2c59a4f7021d" + "uuid": "08ade138-cd5e-4e3d-a9eb-19db04a486df" }, { "type": "route", - "uuid": "956b0537-fa8f-4169-bf00-fbd7f43b4d4d" + "uuid": "b35d7102-3adb-474c-858f-32e244b8f837" }, { "type": "route", - "uuid": "6f09aa19-7f4e-41f5-a60e-45ec17077c22" + "uuid": "403d5665-e412-49a0-92fa-18905719f595" } ] }, { - "uuid": "b3a79260-52ee-40db-b9f5-057764d77ceb", + "uuid": "01866f78-cc06-4173-b027-0f105cc589e1", "name": "payment", "children": [ { "type": "route", - "uuid": "0400d70c-1c06-417b-976f-9067fdde9e37" + "uuid": "02b3b785-c9af-4a4b-aa2c-6cd418b0efe5" }, { "type": "route", - "uuid": "6fcdb524-386e-463a-982f-ad2cf770b258" + "uuid": "0eb4b63a-2427-4ada-9ac7-af529eed675a" }, { "type": "route", - "uuid": "373fb5aa-4591-443e-a08d-bcf6e01f36b3" + "uuid": "06982e3f-70d6-47b3-8a2b-4912123ce302" }, { "type": "route", - "uuid": "11d5f117-fe6c-45c4-ae1b-cae4e6514801" + "uuid": "c5fb9466-1a2c-4344-8e2b-60462c358658" }, { "type": "route", - "uuid": "510a89ef-42e4-4b00-b92b-ee182658f57e" + "uuid": "0df2b206-93a6-449b-bd44-826440e30b79" }, { "type": "route", - "uuid": "0f592f33-c8a9-490b-8c3c-12f3193d9eb3" + "uuid": "35e96b9c-5af3-4b31-97b1-da948cea8142" }, { "type": "route", - "uuid": "7a54e9b9-abfc-4574-b274-ccfb8ec53f15" + "uuid": "28438e54-1302-4aec-8cde-c5b81fcea084" }, { "type": "route", - "uuid": "207ece34-36e7-4926-b96b-d0564f6f24ed" + "uuid": "ebbd66c6-e6dc-4ca5-8ad1-3ad6c379e7d5" }, { "type": "route", - "uuid": "26d4f313-c36c-408b-b532-67f51fe0d118" + "uuid": "a4a1879f-b2c6-4387-926a-c12a4c677b60" } ] }, { - "uuid": "4b345806-3c85-4752-98bd-15b973301107", + "uuid": "b720fd06-ecfd-423b-b9f8-1f043cd03f14", "name": "account-opening", "children": [ { "type": "route", - "uuid": "7579d9f9-d6ab-487b-b22c-9a04b7e3498d" + "uuid": "f9e7549f-4247-4873-bab2-762068985673" }, { "type": "route", - "uuid": "33139996-5a0a-4514-b461-adb9d8c42e0c" + "uuid": "cf9264ea-b900-4076-a9c4-b35bdc35c942" } ] }, { - "uuid": "0c0c687a-810a-434f-affc-a23e45a90dfc", + "uuid": "e4aa74c7-15b5-41d5-9c2b-fd4efc30da49", "name": "contract", "children": [ { "type": "route", - "uuid": "5e07a4b9-bb6d-4983-91ca-c310ff06bb11" + "uuid": "ae0e765d-c39b-45a7-8eb8-4fc992177c18" }, { "type": "route", - "uuid": "0fe9d51a-a402-45ec-955c-dca673b35b3b" + "uuid": "a154307e-112d-4ba8-972a-e8d1254d0cda" } ] }, { - "uuid": "fb3934f2-4587-470e-a75c-054eb7f4b45d", + "uuid": "b4988da1-6b57-4783-8a36-79e9fd497ec9", "name": "task-test", "children": [ { "type": "route", - "uuid": "73691013-0ade-4d97-8dba-98848fb35e76" + "uuid": "116204aa-7cfc-4722-bfbf-e47849bf7615" }, { "type": "route", - "uuid": "d767c310-4aa8-451c-b736-2f76728c7037" + "uuid": "280c208d-cd51-4843-ac10-9ffe63191140" }, { "type": "route", - "uuid": "75c69f59-d442-44ce-bc38-65efabeb2ee3" + "uuid": "a56487a3-7288-4931-a33d-ba518745b642" }, { "type": "route", - "uuid": "30ce347c-8b04-44e4-8d50-da46d7ab04c7" + "uuid": "d7de7b48-ece3-4d22-be22-03099c742c64" } ] }, { - "uuid": "ad23cdc9-2552-4503-bead-579cff0ec274", + "uuid": "898985c3-5c97-46f6-84db-82b651eb070a", "name": "notification", "children": [ { "type": "route", - "uuid": "52f44c97-9b96-4d7e-8f6a-63457637d466" + "uuid": "7434390e-a030-4a22-bafc-c81e22580100" } ] }, { - "uuid": "eb01a2c3-d4e5-4f67-8901-2345abcdef01", + "uuid": "e28601d8-d4e7-42ef-ab04-0abaf99de45e", "name": "error-boundary", "children": [ { "type": "route", - "uuid": "eb01a2c3-0001-4f67-8901-2345abcdef01" + "uuid": "343bb629-13a2-453a-911e-175e9f497cd7" }, { "type": "route", - "uuid": "eb01a2c3-0002-4f67-8901-2345abcdef02" + "uuid": "1c4fdf32-e7f3-4ac0-adbe-bb22e4f7d894" }, { "type": "route", - "uuid": "eb01a2c3-0003-4f67-8901-2345abcdef03" + "uuid": "315ac914-3203-4286-b47c-127152f17839" }, { "type": "route", - "uuid": "eb01a2c3-0004-4f67-8901-2345abcdef04" + "uuid": "5227d151-33bb-487e-9419-7a2fcdca45cd" }, { "type": "route", - "uuid": "eb01a2c3-0005-4f67-8901-2345abcdef05" + "uuid": "e4975b46-d6e9-4e79-b30c-c91b45ce270e" } ] }, { - "uuid": "eb6d81ee-d6f6-434e-b825-c2f838480945", + "uuid": "93e1285c-17d1-4cd7-9d46-7b93c8021709", "name": "discovery", "children": [ { "type": "route", - "uuid": "d417072e-9a13-49ff-9a4e-8ef223c1fae6" + "uuid": "18f05afb-8eca-488f-b17f-89ccc29b1277" }, { "type": "route", - "uuid": "8fad1195-a086-405e-97ce-2979d66133d9" + "uuid": "4f0c29fe-110b-421b-90c2-065a61be8229" } ] } ], "routes": [ { - "uuid": "5a05d227-3eb2-4253-8b26-20b6a95b66ae", + "uuid": "33dc9cb7-3f22-42d7-8f68-7e718467141f", "type": "http", "documentation": "Health check endpoint", "method": "get", "endpoint": "health", "responses": [ { - "uuid": "2a89fdb6-4edc-4911-865a-eae2cf5c5b60", + "uuid": "10e2c981-8401-4118-9947-9de763647010", "body": "{\n \"status\": \"ok\",\n \"timestamp\": \"{{now}}\",\n \"service\": \"migration-api\",\n \"version\": \"1.0.0\"\n}", "latency": 0, "statusCode": 200, @@ -234,14 +234,14 @@ "streamingInterval": 0 }, { - "uuid": "8ba61c4a-f251-47ef-a4a6-92398c4d66ef", + "uuid": "a2478fee-19cd-4bb9-90bc-ba71d2212aed", "type": "http", "documentation": "OAuth2 Client validation - İstemci doğrulama", "method": "post", "endpoint": "api/oauth2/client/validate", "responses": [ { - "uuid": "818941e1-e6e0-4c1b-acc0-73c5eab77e84", + "uuid": "31c7f619-8b35-4f34-89ae-c9fa1b2456e9", "body": "{\n \"success\": true,\n \"clientId\": \"{{body 'client_id'}}\",\n \"grantTypes\": [\"client_credentials\", \"password\", \"authorization_code\"],\n \"redirectUris\": [\"http://localhost:3000/callback\"],\n \"scopes\": [\"api\", \"read\", \"write\"],\n \"isActive\": true\n}", "latency": 100, "statusCode": 200, @@ -273,7 +273,7 @@ "callbacks": [] }, { - "uuid": "9e2a036a-a8b4-4f45-bc3d-91693f57e322", + "uuid": "90106171-a97d-4d81-a929-2e1611b5135d", "body": "{\n \"success\": false,\n \"error\": \"Geçersiz client credentials\",\n \"errorCode\": \"invalid_client\"\n}", "latency": 50, "statusCode": 401, @@ -310,14 +310,14 @@ "streamingInterval": 0 }, { - "uuid": "41dbf3e6-de0a-460e-879b-614d59ff813f", + "uuid": "f0613120-c84b-4e6b-9105-e3c4821223b9", "type": "http", "documentation": "OAuth2 User credentials validation - Kullanıcı kimlik bilgileri doğrulama", "method": "post", "endpoint": "api/oauth2/user/authenticate", "responses": [ { - "uuid": "219ffca1-bd0d-4a93-abbf-033b90943857", + "uuid": "825c21d1-b62f-4ffa-b3cd-d45279f66cb5", "body": "{\n \"success\": true,\n \"userId\": \"{{faker 'string.uuid'}}\",\n \"username\": \"{{body 'username'}}\",\n \"email\": \"{{body 'username'}}@example.com\",\n \"roles\": [\"user\"],\n \"mfaRequired\": true\n}", "latency": 150, "statusCode": 200, @@ -356,7 +356,7 @@ "callbacks": [] }, { - "uuid": "c6e20796-a6f8-4e89-937c-54fd85b4438f", + "uuid": "31f408db-7647-494b-999d-8a2431c07839", "body": "{\n \"success\": false,\n \"error\": \"Geçersiz kullanıcı adı veya şifre\",\n \"errorCode\": \"invalid_credentials\"\n}", "latency": 100, "statusCode": 401, @@ -385,14 +385,14 @@ "streamingInterval": 0 }, { - "uuid": "8bf14db4-9693-4511-8a8c-c4129661c76b", + "uuid": "a435af01-7c28-4efb-96e5-73057296a5e3", "type": "http", "documentation": "OAuth2 Authorization code validation - Authorization code doğrulama", "method": "post", "endpoint": "api/oauth2/user/validate-authorization-code", "responses": [ { - "uuid": "27016b3c-e3ea-4f53-9979-762844e6067f", + "uuid": "222b2a8a-5516-41ef-beff-73c896c1df71", "body": "{\n \"success\": true,\n \"code\": \"{{body 'code'}}\",\n \"clientId\": \"{{body 'client_id'}}\",\n \"userId\": \"{{faker 'string.uuid'}}\",\n \"redirectUri\": \"{{body 'redirect_uri'}}\",\n \"codeChallenge\": \"{{body 'code_challenge'}}\",\n \"codeChallengeMethod\": \"{{body 'code_challenge_method'}}\",\n \"isValid\": true,\n \"expiresAt\": \"{{dateTimeAdd (now) 10 'minutes'}}\"\n}", "latency": 100, "statusCode": 200, @@ -421,14 +421,14 @@ "streamingInterval": 0 }, { - "uuid": "2c335800-21d9-4ea7-bad3-e5e6ae8af460", + "uuid": "245bc071-8c44-4764-a1fb-ebaecd939dfd", "type": "http", "documentation": "Device registration check - Cihaz kayıt durumu kontrolü", "method": "get", "endpoint": "api/oauth2/devices/check", "responses": [ { - "uuid": "2df2b0fe-6114-406a-8536-cc7e8a34ffb7", + "uuid": "a4675a02-beb7-49fd-b8a9-4cd6dd727ee6", "body": "{\n \"isRegistered\": true,\n \"deviceId\": \"{{header 'X-Device-Id'}}\",\n \"deviceName\": \"iPhone 15 Pro\",\n \"deviceType\": \"mobile\",\n \"supportsPush\": true,\n \"registeredAt\": \"2024-09-10T01:48:20.501Z\",\n \"lastSeenAt\": \"{{now}}\"\n}", "latency": 80, "statusCode": 200, @@ -460,7 +460,7 @@ "callbacks": [] }, { - "uuid": "e3c46ef5-4156-49d0-8ff9-a554b5e501d5", + "uuid": "c662164e-172c-444b-a93b-75eb486ae0f7", "body": "{\n \"isRegistered\": false,\n \"deviceId\": \"{{header 'X-Device-Id'}}\",\n \"supportsPush\": false,\n \"requiresRegistration\": true\n}", "latency": 60, "statusCode": 200, @@ -497,14 +497,14 @@ "streamingInterval": 0 }, { - "uuid": "95eecaa5-c860-4be1-87b7-22c96833e35e", + "uuid": "08f6d62d-e6e0-46a5-a892-4a92bc1fc9db", "type": "http", "documentation": "Send push notification for MFA - MFA için push bildirimi gönder", "method": "post", "endpoint": "api/oauth2/push/send", "responses": [ { - "uuid": "0f3b22cd-5e87-4c72-9346-188fa9d9120d", + "uuid": "715415ba-b603-4db8-902f-e954020b640d", "body": "{\n \"success\": true,\n \"notificationId\": \"push_{{faker 'string.uuid'}}\",\n \"deviceId\": \"{{body 'deviceId'}}\",\n \"userId\": \"{{body 'userId'}}\",\n \"message\": \"Giriş onayı gerekli\",\n \"sentAt\": \"{{now}}\",\n \"expiresAt\": \"{{dateTimeAdd (now) 5 'minutes'}}\",\n \"status\": \"sent\"\n}", "latency": 200, "statusCode": 200, @@ -533,14 +533,14 @@ "streamingInterval": 0 }, { - "uuid": "8d1c1536-9e82-4cb1-9349-79852ef6131b", + "uuid": "07100aa8-2f4f-4b2e-8378-c75d3bd8199d", "type": "http", "documentation": "Check push notification response - Push bildirimi yanıtını kontrol et", "method": "post", "endpoint": "api/oauth2/push/status", "responses": [ { - "uuid": "0ab9012d-e65e-428b-a643-a045ab203693", + "uuid": "c11d91fa-bdfc-4392-8758-fbdf025d1a39", "body": "{\n \"notificationId\": \"{{body 'notificationId'}}\",\n \"status\": \"approved\",\n \"respondedAt\": \"{{now}}\",\n \"deviceId\": \"{{body 'deviceId'}}\",\n \"action\": \"approve\",\n \"success\": true\n}", "latency": 100, "statusCode": 200, @@ -572,7 +572,7 @@ "callbacks": [] }, { - "uuid": "51e7f58b-e90b-4cfb-847b-1875d8156fb2", + "uuid": "9321d160-f9aa-4457-ae78-d11c9f814f10", "body": "{\n \"notificationId\": \"{{body 'notificationId'}}\",\n \"status\": \"denied\",\n \"respondedAt\": \"{{now}}\",\n \"deviceId\": \"{{body 'deviceId'}}\",\n \"action\": \"deny\",\n \"success\": false,\n \"reason\": \"User denied the request\"\n}", "latency": 80, "statusCode": 200, @@ -609,14 +609,14 @@ "streamingInterval": 0 }, { - "uuid": "aac5c06b-6c01-4fda-a241-ebfdbf4c5045", + "uuid": "bbc31e7e-8753-4e84-97c6-2d27ed877a66", "type": "http", "documentation": "Send OTP notification - OTP bildirimi gönder (SMS/Email)", "method": "post", "endpoint": "api/oauth2/otp/send", "responses": [ { - "uuid": "113f9d3f-32d8-491a-9c29-56db03240f0f", + "uuid": "a1ef6b5d-e65b-4280-a47d-29c106c5e47d", "body": "{\n \"success\": true,\n \"otpId\": \"otp_{{faker 'string.uuid'}}\",\n \"userId\": \"{{body 'userId'}}\",\n \"method\": \"{{body 'method'}}\",\n \"target\": \"{{body 'target'}}\",\n \"maskedTarget\": \"***@***.com\",\n \"sentAt\": \"{{now}}\",\n \"expiresAt\": \"{{dateTimeAdd (now) 5 'minutes'}}\",\n \"length\": 6\n}", "latency": 250, "statusCode": 200, @@ -645,14 +645,14 @@ "streamingInterval": 0 }, { - "uuid": "ca026001-69e8-41c9-9dfc-2c59a4f7021d", + "uuid": "08ade138-cd5e-4e3d-a9eb-19db04a486df", "type": "http", "documentation": "Verify OTP code - OTP kodu doğrula", "method": "post", "endpoint": "api/oauth2/otp/verify", "responses": [ { - "uuid": "df8f0537-450f-4491-b825-e7d6dd39d0cc", + "uuid": "6492edce-ff30-4cd6-b3f3-27441464996f", "body": "{\n \"success\": true,\n \"otpId\": \"{{body 'otpId'}}\",\n \"code\": \"{{body 'code'}}\",\n \"isValid\": true,\n \"verifiedAt\": \"{{now}}\",\n \"remainingAttempts\": 2\n}", "latency": 100, "statusCode": 200, @@ -684,7 +684,7 @@ "callbacks": [] }, { - "uuid": "16f286db-7997-4b14-a987-1c639ee2c9f5", + "uuid": "1772d12e-4d42-409d-97cd-a85821c1cc17", "body": "{\n \"success\": false,\n \"otpId\": \"{{body 'otpId'}}\",\n \"code\": \"{{body 'code'}}\",\n \"isValid\": false,\n \"error\": \"Geçersiz OTP kodu\",\n \"remainingAttempts\": 1\n}", "latency": 80, "statusCode": 400, @@ -713,14 +713,14 @@ "streamingInterval": 0 }, { - "uuid": "956b0537-fa8f-4169-bf00-fbd7f43b4d4d", + "uuid": "b35d7102-3adb-474c-858f-32e244b8f837", "type": "http", "documentation": "Register device for MFA - MFA için cihaz kaydet", "method": "post", "endpoint": "api/oauth2/devices/register", "responses": [ { - "uuid": "650d204a-51aa-4662-9e9a-06664ad7b059", + "uuid": "0c587644-967c-45e4-be17-d049d7673a0f", "body": "{\n \"success\": true,\n \"deviceId\": \"{{faker 'string.uuid'}}\",\n \"userId\": \"{{body 'userId'}}\",\n \"deviceName\": \"{{body 'deviceName'}}\",\n \"deviceType\": \"{{body 'deviceType'}}\",\n \"supportsPush\": true,\n \"registeredAt\": \"{{now}}\",\n \"token\": \"device_{{faker 'string.alphanumeric' 32}}\"\n}", "latency": 150, "statusCode": 201, @@ -749,14 +749,14 @@ "streamingInterval": 0 }, { - "uuid": "6f09aa19-7f4e-41f5-a60e-45ec17077c22", + "uuid": "403d5665-e412-49a0-92fa-18905719f595", "type": "http", "documentation": "Generate OAuth2 tokens - OAuth2 token'ları oluştur", "method": "post", "endpoint": "api/oauth2/tokens/generate", "responses": [ { - "uuid": "c4a04178-0461-45ac-a6b0-238608a93fd4", + "uuid": "80deddfb-c1c2-4513-bd47-458ad0a276ac", "body": "{\n \"access_token\": \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.{{faker 'string.alphanumeric' 50}}\",\n \"refresh_token\": \"rt_{{faker 'string.alphanumeric' 32}}\",\n \"token_type\": \"Bearer\",\n \"expires_in\": 3600,\n \"scope\": \"{{body 'scope'}}\",\n \"client_id\": \"{{body 'clientId'}}\",\n \"user_id\": \"{{body 'userId'}}\",\n \"device_id\": \"{{body 'deviceId'}}\",\n \"issued_at\": \"{{now}}\",\n \"expires_at\": \"{{dateTimeAdd (now) 1 'hours'}}\"\n}", "latency": 120, "statusCode": 200, @@ -785,14 +785,14 @@ "streamingInterval": 0 }, { - "uuid": "0400d70c-1c06-417b-976f-9067fdde9e37", + "uuid": "02b3b785-c9af-4a4b-aa2c-6cd418b0efe5", "type": "http", "documentation": "Save Payment Configuration - Ödeme yapılandırmasını kaydet", "method": "post", "endpoint": "api/payments/schedules", "responses": [ { - "uuid": "e884dba5-3969-4a04-8ecd-0d0e5fb0927d", + "uuid": "2f7a335d-9110-4be7-95ad-6a60a129bf66", "body": "{\n \"success\": true,\n \"scheduleId\": \"{{faker 'string.uuid'}}\",\n \"userId\": \"{{body 'userId'}}\",\n \"amount\": {{body 'amount'}},\n \"currency\": \"{{body 'currency'}}\",\n \"frequency\": \"{{body 'frequency'}}\",\n \"startDate\": \"{{body 'startDate'}}\",\n \"endDate\": \"{{body 'endDate'}}\",\n \"paymentMethodId\": \"{{body 'paymentMethodId'}}\",\n \"description\": \"{{body 'description'}}\",\n \"recipientId\": \"{{body 'recipientId'}}\",\n \"isAutoRetry\": {{body 'isAutoRetry'}},\n \"maxRetries\": {{body 'maxRetries'}},\n \"status\": \"inactive\",\n \"nextPaymentDate\": \"{{dateTimeAdd (now) 1 'days'}}\",\n \"createdAt\": \"{{now}}\",\n \"maxPayments\": 4\n}", "latency": 200, "statusCode": 201, @@ -816,7 +816,7 @@ "callbacks": [] }, { - "uuid": "dd9e529a-6371-493a-a703-9891bd1efb7c", + "uuid": "25aa9a22-bc7d-4900-9f61-2ebd8e570d68", "body": "{\n \"success\": false,\n \"error\": \"Geçersiz ödeme yapılandırması\",\n \"errorCode\": \"invalid_payment_config\",\n \"details\": \"Eksik veya geçersiz parametreler\"\n}", "latency": 100, "statusCode": 400, @@ -853,14 +853,14 @@ "streamingInterval": 0 }, { - "uuid": "6fcdb524-386e-463a-982f-ad2cf770b258", + "uuid": "0eb4b63a-2427-4ada-9ac7-af529eed675a", "type": "http", "documentation": "Process Payment - Ödeme işle", "method": "post", "endpoint": "api/payments/process", "responses": [ { - "uuid": "011b7be9-5d5e-4de5-92f1-3567cf7ee69f", + "uuid": "8db05c61-f267-4a9d-b8ee-eea1a9abcc3b", "body": "{\n \"success\": true,\n \"transactionId\": \"txn_{{faker 'string.uuid'}}\",\n \"scheduleId\": \"{{body 'scheduleId'}}\",\n \"amount\": {{body 'amount'}},\n \"currency\": \"{{body 'currency'}}\",\n \"paymentMethod\": \"card\",\n \"processedAt\": \"{{now}}\",\n \"fees\": {\n \"amount\": {{faker 'number.float' 0.5 5.0 2}},\n \"currency\": \"{{body 'currency'}}\"\n },\n \"status\": \"completed\"\n}", "latency": 1500, "statusCode": 200, @@ -892,7 +892,7 @@ "callbacks": [] }, { - "uuid": "53781cfd-a6f1-4378-be6f-872ab89f8b73", + "uuid": "dca2e98e-c04d-404f-b910-9c513940796a", "body": "{\n \"success\": false,\n \"error\": \"Yetersiz bakiye\",\n \"errorCode\": \"insufficient_funds\",\n \"amount\": {{body 'amount'}},\n \"availableBalance\": {{faker 'number.float' 0 100 2}}\n}", "latency": 800, "statusCode": 402, @@ -924,7 +924,7 @@ "callbacks": [] }, { - "uuid": "99a674ff-c9bd-4786-bda6-186bdfd5d078", + "uuid": "571f2962-ac2d-4681-938b-eb39741a8cd8", "body": "{\n \"success\": false,\n \"error\": \"Ödeme işleme hatası\",\n \"errorCode\": \"payment_processing_error\",\n \"description\": \"Ödeme sağlayıcısı geçici olarak kullanılamıyor\"\n}", "latency": 5000, "statusCode": 503, @@ -953,14 +953,14 @@ "streamingInterval": 0 }, { - "uuid": "373fb5aa-4591-443e-a08d-bcf6e01f36b3", + "uuid": "06982e3f-70d6-47b3-8a2b-4912123ce302", "type": "http", "documentation": "Activate Payment Schedule - Ödeme planını aktifleştir", "method": "patch", "endpoint": "api/payments/schedules/:scheduleId/activate", "responses": [ { - "uuid": "688a2e3c-b375-4115-8099-9ce8a7a0188e", + "uuid": "3a4eab4b-9ea7-477f-804b-b3fd9328bca6", "body": "{\n \"success\": true,\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\",\n \"status\": \"active\",\n \"activatedAt\": \"{{now}}\",\n \"nextPaymentDate\": \"{{dateTimeAdd (now) 1 'days'}}\",\n \"isActive\": true\n}", "latency": 300, "statusCode": 200, @@ -984,7 +984,7 @@ "callbacks": [] }, { - "uuid": "a077bdd7-9b8d-44d2-904a-e7f4e2550cc6", + "uuid": "ceab4a53-8a05-4760-b02d-cdc1e06f376f", "body": "{\n \"success\": false,\n \"error\": \"Ödeme planı bulunamadı\",\n \"errorCode\": \"schedule_not_found\",\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\"\n}", "latency": 100, "statusCode": 404, @@ -1021,14 +1021,14 @@ "streamingInterval": 0 }, { - "uuid": "11d5f117-fe6c-45c4-ae1b-cae4e6514801", + "uuid": "c5fb9466-1a2c-4344-8e2b-60462c358658", "type": "http", "documentation": "Deactivate Payment Schedule - Ödeme planını deaktifleştir", "method": "patch", "endpoint": "api/payments/schedules/:scheduleId/deactivate", "responses": [ { - "uuid": "e0d0ab89-aafa-47d3-b08c-46f56caf0ccd", + "uuid": "b648f482-34c3-4ff6-a430-b26f0d9bcd77", "body": "{\n \"success\": true,\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\",\n \"status\": \"deactive\",\n \"deactivatedAt\": \"{{now}}\",\n \"reason\": \"{{body 'reason'}}\",\n \"isActive\": false\n}", "latency": 200, "statusCode": 200, @@ -1057,14 +1057,14 @@ "streamingInterval": 0 }, { - "uuid": "510a89ef-42e4-4b00-b92b-ee182658f57e", + "uuid": "0df2b206-93a6-449b-bd44-826440e30b79", "type": "http", "documentation": "Archive Payment Record - Ödeme kaydını arşivle", "method": "post", "endpoint": "api/payments/schedules/:scheduleId/archive", "responses": [ { - "uuid": "3de0ad5d-7435-403f-ac36-bc8a37e49dfd", + "uuid": "2e7a5516-4304-4c93-8e3c-34f4b9ed05f8", "body": "{\n \"success\": true,\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\",\n \"status\": \"archived\",\n \"archivedAt\": \"{{now}}\",\n \"completionReason\": \"{{body 'completionReason'}}\",\n \"finalPaymentCount\": {{body 'finalPaymentCount'}}\n}", "latency": 150, "statusCode": 200, @@ -1093,14 +1093,14 @@ "streamingInterval": 0 }, { - "uuid": "0f592f33-c8a9-490b-8c3c-12f3193d9eb3", + "uuid": "35e96b9c-5af3-4b31-97b1-da948cea8142", "type": "http", "documentation": "Increment Retry Counter - Yeniden deneme sayacını artır", "method": "patch", "endpoint": "api/payments/schedules/:scheduleId/retry", "responses": [ { - "uuid": "e29a1679-70fa-4683-a2c4-cedf6bf8ad98", + "uuid": "0634953a-076b-4f58-9237-d652abb25f09", "body": "{\n \"success\": true,\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\",\n \"retryCount\": {{body 'retryCount'}},\n \"retryAt\": \"{{body 'retryAt'}}\",\n \"maxRetries\": 3,\n \"retriesRemaining\": {{subtract 3 (body 'retryCount')}}\n}", "latency": 100, "statusCode": 200, @@ -1129,14 +1129,14 @@ "streamingInterval": 0 }, { - "uuid": "7a54e9b9-abfc-4574-b274-ccfb8ec53f15", + "uuid": "28438e54-1302-4aec-8cde-c5b81fcea084", "type": "http", "documentation": "Send Payment Notification Sms - Sms Bilgilendirme", "method": "post", "endpoint": "api/payments/notify/sms", "responses": [ { - "uuid": "c8cb9051-5141-4d59-be65-54409f532adb", + "uuid": "1cbd8b2e-368b-4e41-b3ca-b46fa3ec724a", "body": "{\n \"success\": true,\n \"sendedAt\": \"{{now}}\"\n}", "latency": 200, "statusCode": 201, @@ -1160,7 +1160,7 @@ "callbacks": [] }, { - "uuid": "75c96004-c78a-4790-a7f3-928c533b57b0", + "uuid": "ba619503-bb6f-404f-9450-e68089961e48", "body": "{\n \"success\": false,\n \"error\": \"Geçersiz ödeme yapılandırması\",\n \"errorCode\": \"invalid_payment_config\",\n \"details\": \"Eksik veya geçersiz parametreler\"\n}", "latency": 100, "statusCode": 400, @@ -1197,14 +1197,14 @@ "streamingInterval": 0 }, { - "uuid": "207ece34-36e7-4926-b96b-d0564f6f24ed", + "uuid": "ebbd66c6-e6dc-4ca5-8ad1-3ad6c379e7d5", "type": "http", "documentation": "Send Payment Notification Push - Mobile Bilgilendirme", "method": "post", "endpoint": "api/payments/notify/push", "responses": [ { - "uuid": "634f50b5-8c31-41d4-ade6-6f1ee8a7536a", + "uuid": "b24a7512-c03b-4c23-b2f3-3338953cb87c", "body": "{\n \"success\": true,\n \"sendedAt\": \"{{now}}\"\n}", "latency": 200, "statusCode": 201, @@ -1228,7 +1228,7 @@ "callbacks": [] }, { - "uuid": "258a1313-08c6-45f4-89dd-9c3c57393510", + "uuid": "5c9cf8d8-edf8-4fde-afa9-aa53d17291f6", "body": "{\n \"success\": false,\n \"error\": \"Geçersiz ödeme yapılandırması\",\n \"errorCode\": \"invalid_payment_config\",\n \"details\": \"Eksik veya geçersiz parametreler\"\n}", "latency": 100, "statusCode": 400, @@ -1265,14 +1265,14 @@ "streamingInterval": 0 }, { - "uuid": "26d4f313-c36c-408b-b532-67f51fe0d118", + "uuid": "a4a1879f-b2c6-4387-926a-c12a4c677b60", "type": "http", "documentation": "Get User Info - Kullanıcı Bilgisini Getir", "method": "get", "endpoint": "api/payments/users/:userId", "responses": [ { - "uuid": "042dae89-63bc-423e-8505-f2825df4245d", + "uuid": "849e834c-c753-4122-bbe9-74e38a33b8b1", "body": "{\n \"name\": \"John\",\n \"surname\": \"Smith\",\n \"email\": \"john.smith@example.com\",\n \"phoneNumber\": \"905452424847\",\n \"registeredDevices\": [{\n \"deviceId\": \"{{faker 'string.uuid'}}\",\n \"deviceInfo\": \"Ios 18\",\n \"active\": true\n }],\n \"language\": \"tr-TR\"\n}", "latency": 200, "statusCode": 200, @@ -1301,14 +1301,14 @@ "streamingInterval": 0 }, { - "uuid": "7579d9f9-d6ab-487b-b22c-9a04b7e3498d", + "uuid": "f9e7549f-4247-4873-bab2-762068985673", "type": "http", "documentation": "Validates account opening against bank policies", "method": "post", "endpoint": "api/banking/policies/validate-account-opening", "responses": [ { - "uuid": "5b154c2e-31e6-42be-8238-8623488b9f11", + "uuid": "5a48a42f-5adb-4f25-b52e-3473b3827bc8", "body": "{\n \"validationId\": \"{{faker 'string.uuid'}}\",\n \"complianceChecks\": {\n \"kycCompliant\": true,\n \"amlCompliant\": true,\n \"sanctionsCheck\": true,\n \"riskAssessment\": \"low\"\n },\n \"accountLimits\": {\n \"dailyTransactionLimit\": 50000,\n \"monthlyTransactionLimit\": 500000,\n \"minimumBalance\": 0,\n \"maximumBalance\": 1000000\n },\n \"additionalRequirements\": [],\n \"approvedBy\": \"system\",\n \"approvalLevel\": \"automated\",\n \"policyVersion\": \"1.0.0\",\n \"validationScore\": {{faker 'number.int' min=85 max=100}}\n}", "latency": 0, "statusCode": 200, @@ -1340,7 +1340,7 @@ "callbacks": [] }, { - "uuid": "bb862b01-f62e-437a-9e8d-c7cf2a38d0d3", + "uuid": "3d8c58a4-7d77-4f2c-b38b-3645cd80a674", "body": "{\n \"validationId\": \"{{faker 'string.uuid'}}\",\n \"error\": {\n \"message\": \"Policy validation failed\",\n \"code\": \"policy_violation\",\n \"description\": \"Account opening request does not meet policy requirements\"\n },\n \"failedChecks\": [\n \"risk_assessment\"\n ],\n \"recommendations\": [\n \"Please review your account information\",\n \"Contact customer support for assistance\"\n ],\n \"canRetry\": true,\n \"retryAfter\": 300\n}", "latency": 0, "statusCode": 403, @@ -1369,14 +1369,14 @@ "streamingInterval": 0 }, { - "uuid": "33139996-5a0a-4514-b461-adb9d8c42e0c", + "uuid": "cf9264ea-b900-4076-a9c4-b35bdc35c942", "type": "http", "documentation": "Creates a new bank account in core banking system", "method": "post", "endpoint": "api/banking/accounts/create", "responses": [ { - "uuid": "308fd823-ef23-4833-95be-0d5c520a1dea", + "uuid": "8e2147df-ffbd-42b9-a0cc-46fecb6a488f", "body": "{\n \"accountId\": \"{{faker 'string.uuid'}}\",\n \"accountNumber\": \"{{faker 'finance.accountNumber'}}\",\n \"iban\": \"TR{{faker 'string.numeric' 24}}\",\n \"accountType\": \"demand-deposit\",\n \"currency\": \"{{body 'currency'}}\",\n \"branchCode\": \"{{body 'branchCode'}}\",\n \"status\": \"active\",\n \"isActive\": true,\n \"currentBalance\": {{body 'initialDeposit' 0}},\n \"availableBalance\": {{body 'initialDeposit' 0}},\n \"limits\": {\n \"dailyTransactionLimit\": 50000,\n \"monthlyTransactionLimit\": 500000,\n \"minimumBalance\": 0,\n \"maximumBalance\": 1000000\n },\n \"debitCardRequested\": false,\n \"onlineBankingEnabled\": true,\n \"mobileBankingEnabled\": true,\n \"creationReference\": \"{{faker 'string.uuid'}}\",\n \"coreBankingId\": \"CB{{faker 'string.numeric' 10}}\",\n \"services\": [\n \"online-banking\",\n \"mobile-banking\",\n \"sms-banking\"\n ]\n}", "latency": 0, "statusCode": 201, @@ -1408,7 +1408,7 @@ "callbacks": [] }, { - "uuid": "6b220657-625b-43ef-8bac-80a265d9c3ba", + "uuid": "83326ab5-0084-4b4a-84fb-969f43c0e8c9", "body": "{\n \"error\": {\n \"message\": \"Account creation failed\",\n \"code\": \"validation_error\",\n \"description\": \"Account data validation failed\"\n },\n \"failureReason\": \"invalid_account_name\",\n \"failureCategory\": \"validation_error\",\n \"canRetry\": true,\n \"retryAfter\": 300,\n \"maxRetries\": 3,\n \"recommendations\": [\n \"Please check your account information and try again\",\n \"Account name must be between 1-50 characters\"\n ],\n \"supportReference\": \"{{faker 'string.uuid'}}\"\n}", "latency": 0, "statusCode": 422, @@ -1437,14 +1437,14 @@ "streamingInterval": 0 }, { - "uuid": "5e07a4b9-bb6d-4983-91ca-c310ff06bb11", + "uuid": "ae0e765d-c39b-45a7-8eb8-4fc992177c18", "type": "http", "documentation": "", "method": "post", "endpoint": "api/contract/get-documents", "responses": [ { - "uuid": "12a6bb9b-5e3f-4393-8fce-f66b76f6c370", + "uuid": "cfb4904f-d56e-4dc7-999e-ab48bcd066dd", "body": "{\n \"statusCode\": 200,\n \"data\": {\n \"groupCode\": \"{{body 'groupCode'}}\",\n \"contracts\": [\n {\n \"contractId\": \"{{faker 'string.uuid'}}\",\n \"contractType\": \"account-opening\",\n \"contractName\": \"Hesap Açılış Sözleşmesi\",\n \"templateId\": \"TPL-ACCOUNT-001\",\n \"contractData\": {\n \"accountType\": \"demand-deposit\",\n \"currency\": \"TRY\"\n }\n },\n {\n \"contractId\": \"{{faker 'string.uuid'}}\",\n \"contractType\": \"terms-conditions\",\n \"contractName\": \"Genel Hüküm ve Koşullar\",\n \"templateId\": \"TPL-TERMS-001\",\n \"contractData\": {\n \"version\": \"2.0\"\n }\n },\n {\n \"contractId\": \"{{faker 'string.uuid'}}\",\n \"contractType\": \"kvkk\",\n \"contractName\": \"KVKK Aydınlatma Metni\",\n \"templateId\": \"TPL-KVKK-001\",\n \"contractData\": {\n \"consentDate\": \"{{now 'yyyy-MM-dd'}}\"\n }\n }\n ],\n \"totalContracts\": 3,\n \"retrievedAt\": \"{{now}}\"\n }\n}", "latency": 0, "statusCode": 200, @@ -1468,7 +1468,7 @@ "callbacks": [] }, { - "uuid": "b816189d-1b14-4475-b5e3-770cdfd88a5a", + "uuid": "6d59acc7-3ab8-4f81-a9fb-b1b84e2f3d86", "body": "{\n \"statusCode\": 404,\n \"data\": {\n \"error\": {\n \"message\": \"Contract group not found\",\n \"code\": \"group_not_found\",\n \"description\": \"The specified contract group code does not exist\"\n }\n }\n}", "latency": 0, "statusCode": 404, @@ -1497,14 +1497,14 @@ "streamingInterval": 0 }, { - "uuid": "0fe9d51a-a402-45ec-955c-dca673b35b3b", + "uuid": "a154307e-112d-4ba8-972a-e8d1254d0cda", "type": "http", "documentation": "", "method": "post", "endpoint": "api/contract/render-document", "responses": [ { - "uuid": "d7ee8c1b-f0a0-49df-86a9-5b4421305c80", + "uuid": "674dd2b3-df43-4a22-957b-14db70b95656", "body": "{\n \"statusCode\": 200,\n \"data\": {\n \"documentId\": \"{{faker 'string.uuid'}}\",\n \"documentUrl\": \"https://cdn.example.com/contracts/{{faker 'string.alphanumeric' 32}}.pdf\",\n \"documentSize\": {{faker 'number.int' min=50000 max=500000}},\n \"pageCount\": {{faker 'number.int' min=1 max=10}},\n \"checksum\": \"{{faker 'string.alphanumeric' 64}}\",\n \"expiresAt\": \"{{faker 'date.future'}}\",\n \"renderedAt\": \"{{now}}\",\n \"format\": \"pdf\",\n \"templateVersion\": \"1.0.0\"\n }\n}", "latency": 0, "statusCode": 200, @@ -1528,7 +1528,7 @@ "callbacks": [] }, { - "uuid": "5d073833-c477-4dc1-9a2d-bb48d947f8e5", + "uuid": "69af2566-542e-4859-93b7-34b408924232", "body": "{\n \"statusCode\": 500,\n \"data\": {\n \"error\": {\n \"message\": \"Document rendering failed\",\n \"code\": \"render_failed\",\n \"description\": \"Unable to render the contract document\"\n }\n }\n}", "latency": 0, "statusCode": 500, @@ -1557,14 +1557,14 @@ "streamingInterval": 0 }, { - "uuid": "30ce347c-8b04-44e4-8d50-da46d7ab04c7", + "uuid": "d7de7b48-ece3-4d22-be22-03099c742c64", "type": "http", "documentation": "Task Test HTTP Endpoint - Test for HttpTask type", "method": "post", "endpoint": "api/task-test/http-endpoint", "responses": [ { - "uuid": "e9361ff0-f4c6-46a1-94de-1960c8e55cb3", + "uuid": "6a78c8ca-8522-4806-b366-6401885c8817", "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"taskType\": \"HttpTask\",\n \"message\": \"HTTP task test successful\",\n \"receivedData\": {{body}},\n \"processedAt\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n },\n \"metadata\": {\n \"endpoint\": \"api/task-test/http-endpoint\",\n \"method\": \"POST\",\n \"responseTime\": {{faker 'number.int' min=50 max=200}}\n }\n}", "latency": 500, "statusCode": 200, @@ -1592,7 +1592,7 @@ "callbacks": [] }, { - "uuid": "6ad55341-fb41-466e-ab2b-2c87b19f4364", + "uuid": "48844960-4754-47d1-b90e-0d3d4478ccf0", "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", "latency": 200, "statusCode": 500, @@ -1629,14 +1629,14 @@ "streamingInterval": 0 }, { - "uuid": "73691013-0ade-4d97-8dba-98848fb35e76", + "uuid": "116204aa-7cfc-4722-bfbf-e47849bf7615", "type": "http", "documentation": "Task Test Consume Endpoint - Test for PubSub type", "method": "post", "endpoint": "api/task-test/consume", "responses": [ { - "uuid": "3da94bc4-8996-4852-9f9d-c051a050ff5d", + "uuid": "ca697a7f-050a-4cab-ab78-8f15a1e1225b", "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"taskType\": \"DaprPubsub\",\n \"message\": \"HTTP task test successful\",\n \"receivedData\": {{body}},\n \"processedAt\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n },\n \"metadata\": {\n \"endpoint\": \"api/task-test/consume\",\n \"method\": \"POST\",\n \"responseTime\": {{faker 'number.int' min=50 max=200}}\n }\n}", "latency": 0, "statusCode": 200, @@ -1664,7 +1664,7 @@ "callbacks": [] }, { - "uuid": "485b5259-27df-4ce8-80f5-a3b76afc054c", + "uuid": "923377a8-e8fb-42e4-b742-a496e3d110b6", "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", "latency": 0, "statusCode": 500, @@ -1693,14 +1693,14 @@ "streamingInterval": 0 }, { - "uuid": "d767c310-4aa8-451c-b736-2f76728c7037", + "uuid": "280c208d-cd51-4843-ac10-9ffe63191140", "type": "http", "documentation": "Task Test HTTP Endpoint - Test for DaprService type", "method": "post", "endpoint": "api/task-test/dapr-endpoint", "responses": [ { - "uuid": "24f42129-e879-49de-84b2-65825a45018d", + "uuid": "f2d3194a-db97-409c-a7f6-3bf8d3f2bea7", "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"taskType\": \"DaprService\",\n \"message\": \"HTTP task test successful\",\n \"receivedData\": {{body}},\n \"processedAt\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n },\n \"metadata\": {\n \"endpoint\": \"api/task-test/dapr-endpoint\",\n \"method\": \"POST\",\n \"responseTime\": {{faker 'number.int' min=50 max=200}}\n }\n}", "latency": 0, "statusCode": 200, @@ -1728,7 +1728,7 @@ "callbacks": [] }, { - "uuid": "1ba077d4-6d3e-4209-af3c-b7d5734a3e90", + "uuid": "666e268f-a726-4dc9-97f9-b400b2c0ed57", "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", "latency": 0, "statusCode": 500, @@ -1757,14 +1757,14 @@ "streamingInterval": 0 }, { - "uuid": "75c69f59-d442-44ce-bc38-65efabeb2ee3", + "uuid": "a56487a3-7288-4931-a33d-ba518745b642", "type": "http", "documentation": "Task Test HTTP Endpoint - Test for HttpTask type", "method": "post", "endpoint": "api/task-test/list-items", "responses": [ { - "uuid": "163ea29b-0661-463d-a116-a57758be033e", + "uuid": "ac9d4ded-465e-4bbb-bfcd-c29e92b26328", "body": "[\n {\n \"id\": \"{{faker 'string.uuid'}}\",\n \"name\": \"item_{{faker 'string.alphanumeric' 10}}\",\n \"isActive\": true\n },\n {\n \"id\": \"{{faker 'string.uuid'}}\",\n \"name\": \"item_{{faker 'string.alphanumeric' 10}}\",\n \"isActive\": true\n },\n {\n \"id\": \"{{faker 'string.uuid'}}\",\n \"name\": \"item_{{faker 'string.alphanumeric' 10}}\",\n \"isActive\": true\n },\n {\n \"id\": \"{{faker 'string.uuid'}}\",\n \"name\": \"item_{{faker 'string.alphanumeric' 10}}\",\n \"isActive\": true\n }\n]", "latency": 0, "statusCode": 200, @@ -1792,7 +1792,7 @@ "callbacks": [] }, { - "uuid": "afdc2ca6-ceb3-40ee-a7b9-c91a3697aa25", + "uuid": "3dbdfc91-716b-44ba-8956-0f6f412847bc", "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", "latency": 0, "statusCode": 500, @@ -1821,14 +1821,14 @@ "streamingInterval": 0 }, { - "uuid": "52f44c97-9b96-4d7e-8f6a-63457637d466", + "uuid": "7434390e-a030-4a22-bafc-c81e22580100", "type": "http", "documentation": "Task Test HTTP Endpoint - Test for NotificationTask type", "method": "post", "endpoint": "api/notification/send", "responses": [ { - "uuid": "01c4b612-de94-44a9-992c-34f9e1c70821", + "uuid": "dc8b218b-8d43-4465-9e3b-38c0d52782cd", "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"taskType\": \"NotificationTask\",\n \"message\": \"HTTP task test successful\",\n \"receivedData\": {{body}},\n \"processedAt\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n },\n \"metadata\": {\n \"endpoint\": \"api/notification/send\",\n \"method\": \"POST\",\n \"responseTime\": {{faker 'number.int' min=50 max=200}}\n }\n}", "latency": 0, "statusCode": 200, @@ -1852,7 +1852,7 @@ "callbacks": [] }, { - "uuid": "6a6a1054-a070-4cce-99d6-2631a898c43a", + "uuid": "5bf29053-f5f2-4359-bbd9-85b853934a88", "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", "latency": 0, "statusCode": 500, @@ -1881,14 +1881,14 @@ "streamingInterval": 0 }, { - "uuid": "eb01a2c3-0001-4f67-8901-2345abcdef01", + "uuid": "343bb629-13a2-453a-911e-175e9f497cd7", "type": "http", "documentation": "ErrorBoundary Test - Simulate 503 Service Unavailable for Retry testing", "method": "post", "endpoint": "api/error-boundary/simulate-503", "responses": [ { - "uuid": "3a2db3d9-f08b-4978-a645-681fe94ba529", + "uuid": "28f418fb-d189-4a80-b04e-0ab90f31b300", "body": "{\n \"statusCode\": 503,\n \"success\": false,\n \"error\": {\n \"code\": \"SERVICE_UNAVAILABLE\",\n \"message\": \"Service temporarily unavailable\",\n \"description\": \"The service is currently undergoing maintenance or is overloaded\",\n \"retryAfter\": 5\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", "latency": 500, "statusCode": 503, @@ -1921,14 +1921,14 @@ "streamingInterval": 0 }, { - "uuid": "eb01a2c3-0002-4f67-8901-2345abcdef02", + "uuid": "1c4fdf32-e7f3-4ac0-adbe-bb22e4f7d894", "type": "http", "documentation": "ErrorBoundary Test - Simulate 500 Internal Server Error for Abort testing", "method": "post", "endpoint": "api/error-boundary/simulate-500", "responses": [ { - "uuid": "c5864a01-4ae8-45c8-b99e-c658c442e177", + "uuid": "ec79ccf6-4abc-460d-8fff-347f39fabc6e", "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_SERVER_ERROR\",\n \"message\": \"An unexpected error occurred\",\n \"description\": \"Critical system failure - operation cannot be completed\",\n \"errorType\": \"HttpRequestException\"\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", "latency": 200, "statusCode": 500, @@ -1957,14 +1957,14 @@ "streamingInterval": 0 }, { - "uuid": "eb01a2c3-0003-4f67-8901-2345abcdef03", + "uuid": "315ac914-3203-4286-b47c-127152f17839", "type": "http", "documentation": "ErrorBoundary Test - Simulate 400 Bad Request for Ignore testing", "method": "post", "endpoint": "api/error-boundary/simulate-400", "responses": [ { - "uuid": "6df197a0-25a2-4740-8288-850e70204d12", + "uuid": "8711b76c-ce2a-48bc-abc9-8a171f8d25da", "body": "{\n \"statusCode\": 400,\n \"success\": false,\n \"error\": {\n \"code\": \"BAD_REQUEST\",\n \"message\": \"Invalid request parameters\",\n \"description\": \"The request contains invalid or missing parameters\",\n \"validationErrors\": [\n {\n \"field\": \"testField\",\n \"message\": \"Field is required\"\n }\n ]\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", "latency": 100, "statusCode": 400, @@ -1993,14 +1993,14 @@ "streamingInterval": 0 }, { - "uuid": "eb01a2c3-0004-4f67-8901-2345abcdef04", + "uuid": "5227d151-33bb-487e-9419-7a2fcdca45cd", "type": "http", "documentation": "ErrorBoundary Test - Simulate timeout with delayed response", "method": "post", "endpoint": "api/error-boundary/simulate-timeout", "responses": [ { - "uuid": "0fa74f43-09bd-4c80-b9f3-aa581b25fd9e", + "uuid": "bfa529d3-8b52-4529-ab89-dd141bd3303f", "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"message\": \"This response is intentionally delayed to trigger timeout\",\n \"delayedBy\": \"30 seconds\"\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", "latency": 30000, "statusCode": 200, @@ -2029,14 +2029,14 @@ "streamingInterval": 0 }, { - "uuid": "eb01a2c3-0005-4f67-8901-2345abcdef05", + "uuid": "e4975b46-d6e9-4e79-b30c-c91b45ce270e", "type": "http", "documentation": "ErrorBoundary Test - Successful response for happy path testing", "method": "post", "endpoint": "api/error-boundary/simulate-success", "responses": [ { - "uuid": "5a01fa25-1f85-48fd-a016-13cc1b78cb22", + "uuid": "2ad9a371-c101-4069-bba2-262aeb52043b", "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"message\": \"Operation completed successfully\",\n \"result\": {\n \"operationId\": \"{{faker 'string.uuid'}}\",\n \"status\": \"completed\",\n \"processedAt\": \"{{now}}\"\n }\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", "latency": 200, "statusCode": 200, @@ -2065,14 +2065,14 @@ "streamingInterval": 0 }, { - "uuid": "d417072e-9a13-49ff-9a4e-8ef223c1fae6", + "uuid": "18f05afb-8eca-488f-b17f-89ccc29b1277", "type": "http", "documentation": "Domain Resolver", "method": "get", "endpoint": "api/v1/discovery/workflows/domain/instances/:domain/functions/data", "responses": [ { - "uuid": "7198d479-8589-4487-a458-d9454d94f398", + "uuid": "ded6baeb-bd9b-42b0-8e63-89c979d350e0", "body": "{{setVar 'eTag' (faker 'string.alphanumeric' 32)}}\n\n{{#if (eq (urlParam 'domain') 'core')}}\n {{setVar 'port' 4201}}\n{{else}}\n {{setVar 'port' (faker 'number.int' min=4200 max=5000)}}\n{{/if}}\n\n{\n \"data\": {\n \"eTag\": \"\\\"{{@eTag}}\\\"\",\n \"appId\": \"vnext-{{urlParam 'domain'}}.test-vnext-{{urlParam 'domain'}}\",\n \"baseUrl\": \"http://localhost:{{@port}}\",\n \"healthUrl\": \"https://localhost:{{@port}}/health\",\n \"domainName\": \"{{urlParam 'domain'}}\"\n },\n \"etag\": \"\\\"{{@eTag}}\\\"\",\n \"extensions\": {}\n}\n ", "latency": 0, "statusCode": 200, @@ -2100,7 +2100,7 @@ "callbacks": [] }, { - "uuid": "bf780c37-a1db-438a-a73d-b14967243c6f", + "uuid": "119464c2-bcae-439b-a10b-c64124471ed1", "body": "{}", "latency": 0, "statusCode": 404, @@ -2124,7 +2124,7 @@ "callbacks": [] }, { - "uuid": "67e4407e-b6cf-4a0b-a8d3-60addf435143", + "uuid": "041d2ef4-6a8f-4c9e-8951-bf54f827381d", "body": "{}", "latency": 0, "statusCode": 304, @@ -2161,14 +2161,14 @@ "streamingInterval": 0 }, { - "uuid": "8fad1195-a086-405e-97ce-2979d66133d9", + "uuid": "4f0c29fe-110b-421b-90c2-065a61be8229", "type": "http", "documentation": "Domain Registration", "method": "post", "endpoint": "api/v1/discovery/workflows/domain-registration/instances/start", "responses": [ { - "uuid": "a75c2b51-b7fa-43ef-b7d5-bc1a51d9c5d6", + "uuid": "7f6de031-b3bc-4d40-91e9-2290474a7946", "body": "{\n \"id\": \"{{faker 'string.uuid'}}\",\n \"status\": \"C\"\n}", "latency": 0, "statusCode": 200, @@ -2200,39 +2200,39 @@ "rootChildren": [ { "type": "route", - "uuid": "5a05d227-3eb2-4253-8b26-20b6a95b66ae" + "uuid": "33dc9cb7-3f22-42d7-8f68-7e718467141f" }, { "type": "folder", - "uuid": "46fb060c-5347-41f5-809e-86e40337f2fa" + "uuid": "eceef4f3-226b-4d95-b385-451288693d58" }, { "type": "folder", - "uuid": "b3a79260-52ee-40db-b9f5-057764d77ceb" + "uuid": "01866f78-cc06-4173-b027-0f105cc589e1" }, { "type": "folder", - "uuid": "4b345806-3c85-4752-98bd-15b973301107" + "uuid": "b720fd06-ecfd-423b-b9f8-1f043cd03f14" }, { "type": "folder", - "uuid": "0c0c687a-810a-434f-affc-a23e45a90dfc" + "uuid": "e4aa74c7-15b5-41d5-9c2b-fd4efc30da49" }, { "type": "folder", - "uuid": "eb01a2c3-d4e5-4f67-8901-2345abcdef01" + "uuid": "e28601d8-d4e7-42ef-ab04-0abaf99de45e" }, { "type": "folder", - "uuid": "fb3934f2-4587-470e-a75c-054eb7f4b45d" + "uuid": "b4988da1-6b57-4783-8a36-79e9fd497ec9" }, { "type": "folder", - "uuid": "ad23cdc9-2552-4503-bead-579cff0ec274" + "uuid": "898985c3-5c97-46f6-84db-82b651eb070a" }, { "type": "folder", - "uuid": "eb6d81ee-d6f6-434e-b825-c2f838480945" + "uuid": "93e1285c-17d1-4cd7-9d46-7b93c8021709" } ], "proxyMode": false, From f73d575dfd6893838b08c2e403752107b5ad242a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tayfun=20Y=C4=B1lmaz?= Date: Tue, 7 Apr 2026 09:56:32 +0300 Subject: [PATCH 2/4] test flow --- .../payments/function-get-user-info.json | 2 +- .../account-type-selection-view.json | 69 ++++++++- .../account-opening-workflow.diagram.json | 28 ++-- .../account-opening-workflow.json | 76 +++++++++- .../src/InitialTransMapping.csx | 1 + .../src/TriggerGetInstanceTaskMapping.csx | 3 +- .../contract/contract-approval-workflow.json | 1 + .../contract/contract-document-subflow.json | 1 + .../oauth/authorization-code-subflow.json | 1 + .../oauth/oauth-authentication-workflow.json | 1 + core/Workflows/oauth/otp-mfa-subflow.json | 1 + core/Workflows/oauth/password-subflow.json | 1 + .../oauth/push-notification-mfa-subflow.json | 1 + .../payment-notification-subflow.json | 1 + core/Workflows/payments/payment-process.json | 1 + .../payments/scheduled-payments-workflow.json | 1 + .../subflow-test/subflow-view-test-child.json | 139 +++++++++++++++++- .../subflow-view-test-grandchild.json | 25 ++++ .../subflow-view-test-parent.json | 138 ++++++++++++++++- .../subflow-test/subflow-view-test.http | 34 ++++- .../error-boundary-test-workflow.json | 45 ++---- .../src/ErrorBoundaryRetryMapping.csx | 2 +- .../task-test/task-test-subflow.json | 1 + .../task-test/task-test-workflow.json | 1 + package-lock.json | 10 +- package.json | 4 +- validate.js | 24 +-- vnext.config.json | 2 +- 28 files changed, 535 insertions(+), 79 deletions(-) diff --git a/core/Functions/payments/function-get-user-info.json b/core/Functions/payments/function-get-user-info.json index 0d59fde..d3be39e 100644 --- a/core/Functions/payments/function-get-user-info.json +++ b/core/Functions/payments/function-get-user-info.json @@ -26,6 +26,6 @@ "location": "./src/GetUserInfoMapping.csx", "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIEdldFVzZXJJbmZvTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwoKICAgICAgICAgICAgdmFyIHVzZXJJZCA9IGNvbnRleHQuQm9keT8udXNlcklkOwoKICAgICAgICAgICAgLy8gVXBkYXRlIFVSTCB3aXRoIHVzZXJJZAogICAgICAgICAgICBodHRwVGFzay5TZXRVcmwoaHR0cFRhc2suVXJsLlJlcGxhY2UoInt1c2VySWR9IiwgdXNlcklkPy5Ub1N0cmluZygpID8/ICIiKSk7CgogICAgICAgICAgICAvLyBTZXQgSGVhZGVycwogICAgICAgICAgICB2YXIgaGVhZGVycyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi9qc29uIiwKICAgICAgICAgICAgICAgIFsiQWNjZXB0Il0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgICAgICBbIlgtUmVxdWVzdC1JZCJdID0gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaHR0cFRhc2suU2V0SGVhZGVycyhoZWFkZXJzKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInVzZXItaW5mby1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMDsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9IGNvbnRleHQuQm9keT8uZGF0YTsKCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDwgMzAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInVzZXItaW5mby1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB1c2VyID0gcmVzcG9uc2VEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBwaG9uZU51bWJlciA9IHJlc3BvbnNlRGF0YT8ucGhvbmVOdW1iZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIGhhc1JlZ2lzdGVyZWREZXZpY2VzID0gKChvYmplY3RbXSlyZXNwb25zZURhdGE/LnJlZ2lzdGVyZWREZXZpY2VzKS5MZW5ndGggPiAwLAogICAgICAgICAgICAgICAgICAgICAgICBsYW5ndWFnZSA9IHJlc3BvbnNlRGF0YT8ubGFuZ3VhZ2UgPz8gInRyLVRSIgogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInVzZXJzIiwgImxvb2t1cCIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJ1c2VyLWluZm8tZmFpbHVyZSIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRmFpbGVkIHRvIGdldCB1c2VyIGluZm9ybWF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gInVzZXJfaW5mb19mYWlsZWQiLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gc3RhdHVzQ29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgaGFzUmVnaXN0ZXJlZERldmljZXMgPSBmYWxzZQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInVzZXJzIiwgImxvb2t1cCIsICJmYWlsdXJlIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJ1c2VyLWluZm8tZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJJbnRlcm5hbCBwcm9jZXNzaW5nIGVycm9yIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckNvZGUgPSAicHJvY2Vzc2luZ19lcnJvciIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JEZXNjcmlwdGlvbiA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgaGFzUmVnaXN0ZXJlZERldmljZXMgPSBmYWxzZQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJ1c2VycyIsICJsb29rdXAiLCAiZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0K" } - } + }, } } \ No newline at end of file diff --git a/core/Views/account-opening/account-type-selection-view.json b/core/Views/account-opening/account-type-selection-view.json index 0088828..ad374cf 100644 --- a/core/Views/account-opening/account-type-selection-view.json +++ b/core/Views/account-opening/account-type-selection-view.json @@ -23,6 +23,71 @@ } ], "display": "full-page", - "content": "{\"type\":\"form\",\"title\":{\"en-US\":\"Choose Your Account Type\",\"tr-TR\":\"Hesap Türünüzü Seçin\"},\"description\":{\"en-US\":\"Select the type of account that best suits your needs.\",\"tr-TR\":\"İhtiyaçlarınıza en uygun hesap türünü seçin.\"},\"fields\":[{\"key\":\"accountType\",\"type\":\"radio-group\",\"label\":{\"en-US\":\"Account Type\",\"tr-TR\":\"Hesap Türü\"},\"required\":true,\"options\":[{\"value\":\"demand-deposit\",\"label\":{\"en-US\":\"Demand Deposit Account\",\"tr-TR\":\"Vadesiz Mevduat Hesabı\"},\"description\":{\"en-US\":\"Access your money anytime with no minimum balance requirement\",\"tr-TR\":\"Minimum bakiye şartı olmadan paranıza istediğiniz zaman erişin\"},\"icon\":\"credit-card\"},{\"value\":\"savings\",\"label\":{\"en-US\":\"Savings Account\",\"tr-TR\":\"Tasarruf Hesabı\"},\"description\":{\"en-US\":\"Earn interest on your deposits with competitive rates\",\"tr-TR\":\"Rekabetçi oranlarla mevduatınızdan faiz kazanın\"},\"icon\":\"piggy-bank\",\"disabled\":true,\"disabledReason\":{\"en-US\":\"Coming soon\",\"tr-TR\":\"Yakında\"}}]}],\"buttons\":[{\"key\":\"select-demand-deposit\",\"label\":{\"en-US\":\"Continue\",\"tr-TR\":\"Devam Et\"},\"style\":\"primary\",\"action\":\"submit\",\"transition\":\"select-demand-deposit\",\"requiresValidForm\":true}]}" + "content": { + "type": "form", + "title": { + "en-US": "Choose Your Account Type", + "tr-TR": "Hesap Türünüzü Seçin" + }, + "description": { + "en-US": "Select the type of account that best suits your needs.", + "tr-TR": "İhtiyaçlarınıza en uygun hesap türünü seçin." + }, + "fields": [ + { + "key": "accountType", + "type": "radio-group", + "label": { + "en-US": "Account Type", + "tr-TR": "Hesap Türü" + }, + "required": true, + "options": [ + { + "value": "demand-deposit", + "label": { + "en-US": "Demand Deposit Account", + "tr-TR": "Vadesiz Mevduat Hesabı" + }, + "description": { + "en-US": "Access your money anytime with no minimum balance requirement", + "tr-TR": "Minimum bakiye şartı olmadan paranıza istediğiniz zaman erişin" + }, + "icon": "credit-card" + }, + { + "value": "savings", + "label": { + "en-US": "Savings Account", + "tr-TR": "Tasarruf Hesabı" + }, + "description": { + "en-US": "Earn interest on your deposits with competitive rates", + "tr-TR": "Rekabetçi oranlarla mevduatınızdan faiz kazanın" + }, + "icon": "piggy-bank", + "disabled": true, + "disabledReason": { + "en-US": "Coming soon", + "tr-TR": "Yakında" + } + } + ] + } + ], + "buttons": [ + { + "key": "select-demand-deposit", + "label": { + "en-US": "Continue", + "tr-TR": "Devam Et" + }, + "style": "primary", + "action": "submit", + "transition": "select-demand-deposit", + "requiresValidForm": true + } + ] + } } -} +} \ No newline at end of file diff --git a/core/Workflows/account-opening/.meta/account-opening-workflow.diagram.json b/core/Workflows/account-opening/.meta/account-opening-workflow.diagram.json index 7ad6d7f..474d930 100644 --- a/core/Workflows/account-opening/.meta/account-opening-workflow.diagram.json +++ b/core/Workflows/account-opening/.meta/account-opening-workflow.diagram.json @@ -1,36 +1,36 @@ { "nodePos": { "account-type-selection": { - "x": 556, - "y": 480.5 + "x": 1040, + "y": 560 }, "account-details-input": { - "x": 1080, - "y": 400 + "x": 1240, + "y": 980 }, "account-confirmation": { - "x": 1565, - "y": 400 + "x": 721, + "y": 1556 }, "policy-validation": { - "x": 331, - "y": 240 + "x": 660, + "y": 600 }, "account-creation": { - "x": 780, - "y": 200 + "x": 278, + "y": 954 }, "account-opening-success": { - "x": 1220, - "y": 200 + "x": 153, + "y": 1400 }, "cancelled": { "x": 100, "y": 100 }, "__start__": { - "x": 130, - "y": 480.5 + "x": 840, + "y": 100 } } } \ No newline at end of file diff --git a/core/Workflows/account-opening/account-opening-workflow.json b/core/Workflows/account-opening/account-opening-workflow.json index 34bacc8..9b687d7 100644 --- a/core/Workflows/account-opening/account-opening-workflow.json +++ b/core/Workflows/account-opening/account-opening-workflow.json @@ -1,6 +1,7 @@ { "key": "account-opening", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ @@ -23,9 +24,28 @@ "label": "Dijital Bankacılık Hesap Açılışı İş Akışı" } ], - "functions": [], + "functions": [ + { + "key": "multi-task-function-test", + "domain": "core", + "flow": "sys-functions", + "version": "1.0.0" + } + ], "features": [], "extensions": [], + "schema": { + "key": "account-opening-master", + "version": "1.0.0", + "domain": "core", + "flow": "sys-schemas" + }, + "queryRoles": [ + { + "role": "morph-idm.viewer", + "grant": "allow" + } + ], "cancel": { "key": "cancel-account-opening", "target": "cancelled", @@ -73,7 +93,7 @@ ], "mapping": { "location": "./src/InitialTransMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uRHluYW1pYzsKdXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIEluaXRpYWxUcmFuc01hcHBpbmcgOiBJVHJhbnNpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8ZHluYW1pYz4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgZHluYW1pYyBvdXRwdXQgPSBuZXcgRXhwYW5kb09iamVjdCgpOwogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgb3V0cHV0LmluaXRpYWwgPSBuZXcgewogICAgICAgICAgICAgICAgc2Vzc2lvbiA9IGNvbnRleHQuQm9keS5zZXNzaW9uLAogICAgICAgICAgICAgICAgcmVxdWVzdElkID0gY29udGV4dC5IZWFkZXJzP1sieC1yZXF1ZXN0LWlkIl0gPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgfTsKICAgICAgICAKCiAgICAgICAgICAgIHJldHVybiBvdXRwdXQ7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gb3V0cHV0OwogICAgICAgIH0KICAgIH0KfQo=" + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uRHluYW1pYzsKdXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIEluaXRpYWxUcmFuc01hcHBpbmcgOiBJVHJhbnNpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8ZHluYW1pYz4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgZHluYW1pYyBvdXRwdXQgPSBuZXcgRXhwYW5kb09iamVjdCgpOwogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgb3V0cHV0LmluaXRpYWwgPSBuZXcgewogICAgICAgICAgICAgICAgc2Vzc2lvbiA9IGNvbnRleHQuQm9keS5zZXNzaW9uLAogICAgICAgICAgICAgICAgcmVxdWVzdElkID0gY29udGV4dC5IZWFkZXJzP1sieC1yZXF1ZXN0LWlkIl0gPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIGN1c3RvbWVyID0gY29udGV4dC5Cb2R5LmN1c3RvbWVyCiAgICAgICAgICAgIH07CiAgICAgICAgCgogICAgICAgICAgICByZXR1cm4gb3V0cHV0OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG91dHB1dDsKICAgICAgICB9CiAgICB9Cn0K" } }, "states": [ @@ -113,6 +133,16 @@ "target": "account-details-input", "triggerType": 0, "versionStrategy": "Minor", + "roles": [ + { + "role": "morph-idm.initiator", + "grant": "allow" + }, + { + "role": "$userBehalfOf.$.context.Instance.Data.initial.customer.ownerUserId", + "grant": "allow" + } + ], "labels": [ { "language": "en-US", @@ -152,7 +182,7 @@ }, "mapping": { "location": "./src/TriggerGetInstanceTaskMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgU3lzdGVtLlRleHQuSnNvbjsKCnB1YmxpYyBjbGFzcyBUcmlnZ2VyR2V0SW5zdGFuY2VUYXNrTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgdHJpZ2dlclRhc2sgPSAodGFzayBhcyBHZXRJbnN0YW5jZURhdGFUYXNrKSE7CiAgICAgICAKICAgICAgICB0cmlnZ2VyVGFzay5TZXRJbnN0YW5jZShjb250ZXh0Lkluc3RhbmNlLkRhdGEub2xkSW5zdGFuY2VJZHMpOwogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKQogICAgICAgIHsKICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBvbGRJbnN0YW5jZT1jb250ZXh0LkJvZHksCiAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZQogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9Cn0KCnB1YmxpYyBjbGFzcyBSZXF1ZXN0TW9kZWwKewogICAgcHVibGljIHN0cmluZyBrZXkgeyBnZXQ7IHNldDsgfQogICAgcHVibGljIGR5bmFtaWMgIGF0dHJpYnV0ZXMgeyBnZXQ7IHNldDsgfQp9" + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgU3lzdGVtLlRleHQuSnNvbjsKCnB1YmxpYyBjbGFzcyBUcmlnZ2VyR2V0SW5zdGFuY2VUYXNrTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgdHJpZ2dlclRhc2sgPSAodGFzayBhcyBHZXRJbnN0YW5jZURhdGFUYXNrKSE7CiAgICAgICAKICAgICAgICB0cmlnZ2VyVGFzay5TZXRJbnN0YW5jZShjb250ZXh0Lkluc3RhbmNlLktleSk7CiAgICAgICAgCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpCiAgICAgICAgewogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG9sZEluc3RhbmNlPWNvbnRleHQuQm9keSwKICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlCiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KfQoKcHVibGljIGNsYXNzIFJlcXVlc3RNb2RlbAp7CiAgICBwdWJsaWMgc3RyaW5nIGtleSB7IGdldDsgc2V0OyB9CiAgICBwdWJsaWMgZHluYW1pYyAgYXR0cmlidXRlcyB7IGdldDsgc2V0OyB9Cn0=" } } ] @@ -229,6 +259,16 @@ "extensions": [] }, "subFlow": null, + "queryRoles": [ + { + "role": "morph-idm.maker", + "grant": "allow" + }, + { + "role": "morph-idm.viewer", + "grant": "deny" + } + ], "onEntries": [], "onExits": [], "transitions": [ @@ -237,6 +277,16 @@ "target": "account-confirmation", "triggerType": 0, "versionStrategy": "Minor", + "roles": [ + { + "role": "$PreviousUser", + "grant": "deny" + }, + { + "role": "morph-idm.initiator", + "grant": "allow" + } + ], "labels": [ { "language": "en-US", @@ -284,6 +334,16 @@ "label": "Hesap Onayı" } ], + "queryRoles": [ + { + "role": "$InstanceStarter", + "grant": "allow" + }, + { + "role": "$PreviousUser", + "grant": "deny" + } + ], "view": { "view": { "key": "account-confirmation-view", @@ -303,6 +363,16 @@ "target": "policy-validation", "triggerType": 0, "versionStrategy": "Minor", + "roles": [ + { + "role": "morph-idm.maker", + "grant": "allow" + }, + { + "role": "morph-idm.initiator", + "grant": "allow" + } + ], "labels": [ { "language": "en-US", diff --git a/core/Workflows/account-opening/src/InitialTransMapping.csx b/core/Workflows/account-opening/src/InitialTransMapping.csx index 709e0c0..5a45cb5 100644 --- a/core/Workflows/account-opening/src/InitialTransMapping.csx +++ b/core/Workflows/account-opening/src/InitialTransMapping.csx @@ -14,6 +14,7 @@ public class InitialTransMapping : ITransitionMapping output.initial = new { session = context.Body.session, requestId = context.Headers?["x-request-id"] ?? Guid.NewGuid().ToString(), + customer = context.Body.customer }; diff --git a/core/Workflows/account-opening/src/TriggerGetInstanceTaskMapping.csx b/core/Workflows/account-opening/src/TriggerGetInstanceTaskMapping.csx index 962b3e4..5f81b72 100644 --- a/core/Workflows/account-opening/src/TriggerGetInstanceTaskMapping.csx +++ b/core/Workflows/account-opening/src/TriggerGetInstanceTaskMapping.csx @@ -8,7 +8,8 @@ public class TriggerGetInstanceTaskMapping : IMapping { var triggerTask = (task as GetInstanceDataTask)!; - triggerTask.SetInstance(context.Instance.Data.oldInstanceIds); + triggerTask.SetInstance(context.Instance.Key); + return Task.FromResult(new ScriptResponse()); } diff --git a/core/Workflows/contract/contract-approval-workflow.json b/core/Workflows/contract/contract-approval-workflow.json index 48d2585..2702ae6 100644 --- a/core/Workflows/contract/contract-approval-workflow.json +++ b/core/Workflows/contract/contract-approval-workflow.json @@ -1,6 +1,7 @@ { "key": "contract-approval-workflow", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/contract/contract-document-subflow.json b/core/Workflows/contract/contract-document-subflow.json index df14cec..85270b1 100644 --- a/core/Workflows/contract/contract-document-subflow.json +++ b/core/Workflows/contract/contract-document-subflow.json @@ -1,6 +1,7 @@ { "key": "contract-document-subflow", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/oauth/authorization-code-subflow.json b/core/Workflows/oauth/authorization-code-subflow.json index ef2b1d8..d1b0e22 100644 --- a/core/Workflows/oauth/authorization-code-subflow.json +++ b/core/Workflows/oauth/authorization-code-subflow.json @@ -1,6 +1,7 @@ { "key": "authorization-code-subflow", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/oauth/oauth-authentication-workflow.json b/core/Workflows/oauth/oauth-authentication-workflow.json index 50f5a7d..46486db 100644 --- a/core/Workflows/oauth/oauth-authentication-workflow.json +++ b/core/Workflows/oauth/oauth-authentication-workflow.json @@ -1,6 +1,7 @@ { "key": "oauth-authentication", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/oauth/otp-mfa-subflow.json b/core/Workflows/oauth/otp-mfa-subflow.json index f5f1e5a..6271bcc 100644 --- a/core/Workflows/oauth/otp-mfa-subflow.json +++ b/core/Workflows/oauth/otp-mfa-subflow.json @@ -1,6 +1,7 @@ { "key": "otp-mfa-subflow", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/oauth/password-subflow.json b/core/Workflows/oauth/password-subflow.json index 4ec4fe5..8ddbef4 100644 --- a/core/Workflows/oauth/password-subflow.json +++ b/core/Workflows/oauth/password-subflow.json @@ -1,6 +1,7 @@ { "key": "password-subflow", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/oauth/push-notification-mfa-subflow.json b/core/Workflows/oauth/push-notification-mfa-subflow.json index 7916618..31a346b 100644 --- a/core/Workflows/oauth/push-notification-mfa-subflow.json +++ b/core/Workflows/oauth/push-notification-mfa-subflow.json @@ -1,6 +1,7 @@ { "key": "push-notification-mfa-subflow", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/payments/payment-notification-subflow.json b/core/Workflows/payments/payment-notification-subflow.json index 8c583ff..921c06e 100644 --- a/core/Workflows/payments/payment-notification-subflow.json +++ b/core/Workflows/payments/payment-notification-subflow.json @@ -1,6 +1,7 @@ { "key": "payment-notification-subflow", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/payments/payment-process.json b/core/Workflows/payments/payment-process.json index 411c091..1e518e6 100644 --- a/core/Workflows/payments/payment-process.json +++ b/core/Workflows/payments/payment-process.json @@ -1,6 +1,7 @@ { "key": "payment-process", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/payments/scheduled-payments-workflow.json b/core/Workflows/payments/scheduled-payments-workflow.json index e43b8ef..3ca0133 100644 --- a/core/Workflows/payments/scheduled-payments-workflow.json +++ b/core/Workflows/payments/scheduled-payments-workflow.json @@ -1,6 +1,7 @@ { "key": "scheduled-payments", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/subflow-test/subflow-view-test-child.json b/core/Workflows/subflow-test/subflow-view-test-child.json index ca4c419..790b4db 100644 --- a/core/Workflows/subflow-test/subflow-view-test-child.json +++ b/core/Workflows/subflow-test/subflow-view-test-child.json @@ -1,6 +1,7 @@ { "key": "subflow-view-test-child", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ @@ -13,7 +14,15 @@ ], "attributes": { "type": "S", - "timeout": null, + "timeout": { + "key": "push-timeout", + "target": "cancelled", + "versionStrategy": "Minor", + "timer": { + "reset": "OnEntry", + "duration": "PT10M" + } + }, "labels": [ { "language": "en-US", @@ -24,6 +33,20 @@ "label": "Alt Akış Görünüm Testi - Alt Akış" } ], + "cancel": { + "key": "cancel", + "target": "cancelled", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Cancel Child Workflow" + } + ], + "onExecutionTasks": [], + "availableIn": [] + }, "functions": [], "features": [], "extensions": [ @@ -34,7 +57,46 @@ "flow": "sys-extensions" } ], - "sharedTransitions": [], + "sharedTransitions": [ + { + "key": "child-shared-update", + "target": "$self", + "triggerType": 0, + "versionStrategy": "Minor", + "availableIn": [ + "waiting-for-grandchild" + ], + "labels": [ + { + "language": "en-US", + "label": "Child Shared Update (issue #425)" + }, + { + "language": "tr-TR", + "label": "Alt Akış Paylaşımlı Güncelleme (#425)" + } + ], + "schema": null, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/ChildSharedUpdateMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gQ2hpbGQgU2hhcmVkIFVwZGF0ZSBNYXBwaW5nIC0gUHJvY2Vzc2VzIGRhdGEgc2VudCB2aWEgY2hpbGQncyBzaGFyZWQgdHJhbnNpdGlvbiAodGFyZ2V0ICRzZWxmKS4KLy8vIFVzZWQgdG8gdmVyaWZ5IGlzc3VlICM0MjU6IGNoaWxkIChzdWJmbG93KSBjYW4gaGFuZGxlIHNoYXJlZCB0cmFuc2l0aW9ucyB3aGlsZSBpbiBpdHMgb3duIHN1YmZsb3cuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBDaGlsZFNoYXJlZFVwZGF0ZU1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkNoaWxkU2hhcmVkVXBkYXRlTWFwcGluZyAtIFByb2Nlc3Npbmcgc2hhcmVkIHRyYW5zaXRpb24gZGF0YSBvbiBjaGlsZCAodGFyZ2V0ICRzZWxmKSIpOwoKICAgICAgICAgICAgdmFyIGJvZHkgPSBjb250ZXh0LkJvZHkgYXMgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuSURpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+OwogICAgICAgICAgICBvYmplY3QgbSwgdjsKICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBib2R5ICE9IG51bGwgJiYgYm9keS5UcnlHZXRWYWx1ZSgibWVzc2FnZSIsIG91dCBtKSA/IG0/LlRvU3RyaW5nKCkgOiBudWxsOwogICAgICAgICAgICB2YXIgdmFsdWUgPSBib2R5ICE9IG51bGwgJiYgYm9keS5UcnlHZXRWYWx1ZSgidmFsdWUiLCBvdXQgdikgPyB2IDogbnVsbDsKCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImNoaWxkLXNoYXJlZC11cGRhdGUtcHJvY2Vzc2VkIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzaGFyZWRVcGRhdGVGcm9tQ2hpbGQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBtZXNzYWdlID8/ICJubyBtZXNzYWdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgd29ya2Zsb3dLZXkgPSBjb250ZXh0LldvcmtmbG93Py5LZXksCiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgICAgICAgICAgbm90ZSA9ICJDaGlsZCBmbG93IHByb2Nlc3NlZCB0aGlzIHdoaWxlIGluIHN1YmZsb3cgKGlzc3VlICM0MjUgdGVzdCkiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJzdWJmbG93LXRlc3QiLCAic2hhcmVkLXRyYW5zaXRpb24iLCAiY2hpbGQiLCAiaXNzdWUtNDI1IiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiQ2hpbGRTaGFyZWRVcGRhdGVNYXBwaW5nIC0gRXJyb3I6IHswfSIsIGFyZ3M6IG5ldyBvYmplY3Q/W10geyBleC5NZXNzYWdlIH0pOwogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJjaGlsZC1zaGFyZWQtdXBkYXRlLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQo=" + } + } + ] + } + ], "startTransition": { "key": "start-child", "target": "child-initial", @@ -113,6 +175,12 @@ "label": "Torun Alt Akışı Başlat" } ], + "roles": [ + { + "role": "morph-idm.viewer", + "grant": "deny" + } + ], "schema": null, "rule": null, "timer": null, @@ -148,6 +216,52 @@ "mapping": { "location": "./src/ChildToGrandchildSubFlowMapping.csx", "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLkR5bmFtaWM7CnVzaW5nIFN5c3RlbS5UaHJlYWRpbmcuVGFza3M7CnVzaW5nIEJCVC5Xb3JrZmxvdy5EZWZpbml0aW9uczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZy5GdW5jdGlvbnM7CgovLy8gPHN1bW1hcnk+Ci8vLyBDaGlsZCB0byBHcmFuZGNoaWxkIFN1YkZsb3cgTWFwcGluZyAtIEhhbmRsZXMgaW5wdXQvb3V0cHV0IGZvciBncmFuZGNoaWxkIHN1YmZsb3cgc3RhdGUKLy8vIFRoaXMgbWFwcGluZyBwcmVwYXJlcyBkYXRhIGZvciBncmFuZGNoaWxkIHN1YmZsb3cgYW5kIHByb2Nlc3NlcyBpdHMgcmVzdWx0LgovLy8gTWFuYWdlcyB0aGUgTGV2ZWwgMiB0byBMZXZlbCAzIHRyYW5zaXRpb24gaW4gdGhlIHN1YmZsb3cgaGllcmFyY2h5LgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgQ2hpbGRUb0dyYW5kY2hpbGRTdWJGbG93TWFwcGluZyA6IFNjcmlwdEJhc2UsIElTdWJGbG93TWFwcGluZwp7CiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gUHJlcGFyZXMgaW5wdXQgZGF0YSBmb3IgdGhlIGdyYW5kY2hpbGQgc3ViZmxvdwogICAgLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkNoaWxkVG9HcmFuZGNoaWxkU3ViRmxvd01hcHBpbmcgLSBQcmVwYXJpbmcgZ3JhbmRjaGlsZCBzdWJmbG93IGlucHV0IGRhdGEiKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFByZXBhcmUgZGF0YSB0byBwYXNzIHRvIGdyYW5kY2hpbGQgd29ya2Zsb3cgdXNpbmcgRGljdGlvbmFyeQogICAgICAgICAgICB2YXIgdGVzdENvbnRleHQgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJ0ZXN0VHlwZSJdID0gImRlZXAtbmVzdGVkLXZpZXctZXh0ZW5zaW9uLWxvbmdwb2xsaW5nIiwKICAgICAgICAgICAgICAgIFsiZXhwZWN0Vmlld0RhdGEiXSA9IHRydWUsCiAgICAgICAgICAgICAgICBbImV4cGVjdEV4dGVuc2lvbkRhdGEiXSA9IHRydWUsCiAgICAgICAgICAgICAgICBbIm5lc3RpbmdMZXZlbCJdID0gMwogICAgICAgICAgICB9OwogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIGlucHV0RGF0YSA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbImNoaWxkSW5zdGFuY2VJZCJdID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICBbImNoaWxkV29ya2Zsb3dJZCJdID0gY29udGV4dC5Xb3JrZmxvdz8uS2V5ID8/IHN0cmluZy5FbXB0eSwKICAgICAgICAgICAgICAgIFsicGFyZW50SW5zdGFuY2VJZCJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50SW5zdGFuY2VJZCwKICAgICAgICAgICAgICAgIFsicGFyZW50V29ya2Zsb3dJZCJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50V29ya2Zsb3dJZCwKICAgICAgICAgICAgICAgIFsiaW5pdGlhdGVkQXQiXSA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIFsiaW5pdGlhdGVkQnkiXSA9ICJjaGlsZC13b3JrZmxvdyIsCiAgICAgICAgICAgICAgICBbIm5lc3RpbmdMZXZlbCJdID0gMywKICAgICAgICAgICAgICAgIFsidGVzdENvbnRleHQiXSA9IHRlc3RDb250ZXh0CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9IGNvbnRleHQuSW5zdGFuY2U/LktleSwKICAgICAgICAgICAgICAgIERhdGEgPSBpbnB1dERhdGEsCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAic3ViZmxvdy10ZXN0IiwgImdyYW5kY2hpbGQtc3ViZmxvdy1pbnB1dCIsICJsZXZlbC0zIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiQ2hpbGRUb0dyYW5kY2hpbGRTdWJGbG93TWFwcGluZyBJbnB1dEhhbmRsZXIgLSBFcnJvcjogezB9IiwgYXJnczogbmV3IG9iamVjdD9bXSB7IGV4Lk1lc3NhZ2UgfSk7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdyYW5kY2hpbGQtc3ViZmxvdy1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+IHsgWyJlcnJvciJdID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQoKICAgIC8vLyA8c3VtbWFyeT4KICAgIC8vLyBQcm9jZXNzZXMgdGhlIHJlc3VsdCBmcm9tIHRoZSBjb21wbGV0ZWQgZ3JhbmRjaGlsZCBzdWJmbG93CiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkNoaWxkVG9HcmFuZGNoaWxkU3ViRmxvd01hcHBpbmcgLSBQcm9jZXNzaW5nIGdyYW5kY2hpbGQgc3ViZmxvdyBvdXRwdXQgZGF0YSIpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gR2V0IGdyYW5kY2hpbGQgc3ViZmxvdyByZXN1bHQgZGF0YQogICAgICAgICAgICB2YXIgZ3JhbmRjaGlsZFJlc3VsdCA9IGNvbnRleHQuQm9keTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHZhciBncmFuZGNoaWxkUmVzdWx0RGF0YSA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbImdyYW5kY2hpbGRJbnN0YW5jZURhdGEiXSA9IGdyYW5kY2hpbGRSZXN1bHQsCiAgICAgICAgICAgICAgICBbInByb2Nlc3NlZCJdID0gdHJ1ZSwKICAgICAgICAgICAgICAgIFsidmlld1Rlc3RSZXN1bHQiXSA9ICJzdWNjZXNzIiwKICAgICAgICAgICAgICAgIFsiZXh0ZW5zaW9uVGVzdFJlc3VsdCJdID0gInN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgWyJkZWVwTmVzdGVkVGVzdFJlc3VsdCJdID0gInN1Y2Nlc3MiCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICB2YXIgY2hpbGRDb250aW51YXRpb24gPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJjYW5Qcm9jZWVkIl0gPSB0cnVlLAogICAgICAgICAgICAgICAgWyJuZXh0U3RhdGUiXSA9ICJjaGlsZC1hZnRlci1ncmFuZGNoaWxkIgogICAgICAgICAgICB9OwogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIG91dHB1dERhdGEgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJncmFuZGNoaWxkU3ViZmxvd0NvbXBsZXRlZCJdID0gdHJ1ZSwKICAgICAgICAgICAgICAgIFsiY29tcGxldGVkQXQiXSA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIFsiZ3JhbmRjaGlsZFJlc3VsdCJdID0gZ3JhbmRjaGlsZFJlc3VsdERhdGEsCiAgICAgICAgICAgICAgICBbImNoaWxkQ29udGludWF0aW9uIl0gPSBjaGlsZENvbnRpbnVhdGlvbiwKICAgICAgICAgICAgICAgIFsibmVzdGluZ0xldmVsIl0gPSAzCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJncmFuZGNoaWxkLXN1YmZsb3ctb3V0cHV0LXByb2Nlc3NlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gb3V0cHV0RGF0YSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJzdWJmbG93LXRlc3QiLCAiZ3JhbmRjaGlsZC1zdWJmbG93LW91dHB1dCIsICJjb21wbGV0ZWQiLCAibGV2ZWwtMyIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIkNoaWxkVG9HcmFuZGNoaWxkU3ViRmxvd01hcHBpbmcgT3V0cHV0SGFuZGxlciAtIEVycm9yOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZ3JhbmRjaGlsZC1zdWJmbG93LW91dHB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+IHsgWyJlcnJvciJdID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cg==" + }, + "overrides": { + "states": { + "grandchild-active": { + "queryRoles": [ + { + "role": "morph-idm.maker", + "grant": "deny" + }, + { + "role": "morph-idm.viewer", + "grant": "deny" + }, + { + "role": "morph-idm.full", + "grant": "allow" + }, + { + "role": "morph-idm.editor", + "grant": "allow" + } + ] + } + }, + "transitions": { + "enter-busy-state": { + "roles": [ + { + "role": "$InstanceStarter", + "grant": "allow" + }, + { + "role": "morph-idm.viewer", + "grant": "deny" + }, + { + "role": "morph-idm.full", + "grant": "allow" + }, + { + "role": "morph-idm.maker", + "grant": "deny" + } + ] + } + } } }, "onEntries": [], @@ -267,6 +381,27 @@ "onEntries": [], "onExits": [], "transitions": [] + }, + { + "key": "cancelled", + "stateType": 3, + "subType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Child Workflow Cancelled" + }, + { + "language": "tr-TR", + "label": "Çocuk Akış İptal Edildi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] } ] } diff --git a/core/Workflows/subflow-test/subflow-view-test-grandchild.json b/core/Workflows/subflow-test/subflow-view-test-grandchild.json index 1315292..ac1115f 100644 --- a/core/Workflows/subflow-test/subflow-view-test-grandchild.json +++ b/core/Workflows/subflow-test/subflow-view-test-grandchild.json @@ -1,6 +1,7 @@ { "key": "subflow-view-test-grandchild", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ @@ -95,6 +96,16 @@ "grandchild-data-extension" ] }, + "queryRoles": [ + { + "role": "morph-idm.maker", + "grant": "deny" + }, + { + "role": "morph-idm.viewer", + "grant": "allow" + } + ], "subFlow": null, "onEntries": [], "onExits": [], @@ -114,6 +125,20 @@ "label": "Meşgul Durumuna Geç" } ], + "roles": [ + { + "role": "morph-idm.maker", + "grant": "allow" + }, + { + "role": "morph-idm.viewer", + "grant": "deny" + }, + { + "role": "morph-idm.full", + "grant": "allow" + } + ], "schema": null, "rule": null, "timer": null, diff --git a/core/Workflows/subflow-test/subflow-view-test-parent.json b/core/Workflows/subflow-test/subflow-view-test-parent.json index dfca761..8d4a298 100644 --- a/core/Workflows/subflow-test/subflow-view-test-parent.json +++ b/core/Workflows/subflow-test/subflow-view-test-parent.json @@ -1,6 +1,7 @@ { "key": "subflow-view-test-parent", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ @@ -23,6 +24,20 @@ "label": "Alt Akış Görünüm Testi - Ana Akış" } ], + "cancel": { + "key": "cancel", + "target": "cancelled", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Cancel Parent Workflow" + } + ], + "onExecutionTasks": [], + "availableIn": [] + }, "functions": [], "features": [], "extensions": [ @@ -33,7 +48,46 @@ "flow": "sys-extensions" } ], - "sharedTransitions": [], + "sharedTransitions": [ + { + "key": "parent-shared-update", + "target": "$self", + "triggerType": 0, + "versionStrategy": "Minor", + "availableIn": [ + "waiting-for-subflow" + ], + "labels": [ + { + "language": "en-US", + "label": "Parent Shared Update (issue #425)" + }, + { + "language": "tr-TR", + "label": "Üst Akış Paylaşımlı Güncelleme (#425)" + } + ], + "schema": null, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/ParentSharedUpdateMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gUGFyZW50IFNoYXJlZCBVcGRhdGUgTWFwcGluZyAtIFByb2Nlc3NlcyBkYXRhIHNlbnQgdmlhIHBhcmVudCdzIHNoYXJlZCB0cmFuc2l0aW9uICh0YXJnZXQgJHNlbGYpLgovLy8gVXNlZCB0byB2ZXJpZnkgaXNzdWUgIzQyNTogcGFyZW50IGZsb3cgY2FuIGhhbmRsZSBzaGFyZWQgdHJhbnNpdGlvbnMgd2hpbGUgaW5zdGFuY2UgaXMgaW4gc3ViZmxvdy4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFBhcmVudFNoYXJlZFVwZGF0ZU1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIlBhcmVudFNoYXJlZFVwZGF0ZU1hcHBpbmcgLSBQcm9jZXNzaW5nIHNoYXJlZCB0cmFuc2l0aW9uIGRhdGEgb24gcGFyZW50ICh0YXJnZXQgJHNlbGYpIik7CgogICAgICAgICAgICAvLyBUcmFuc2l0aW9uIGJvZHkgaXMgdGhlIFBBVENIIHJlcXVlc3QgYm9keSAoZS5nLiB7ICJtZXNzYWdlIjogIi4uLiIsICJ2YWx1ZSI6IC4uLiB9KQogICAgICAgICAgICB2YXIgYm9keSA9IGNvbnRleHQuQm9keSBhcyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5JRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD47CiAgICAgICAgICAgIG9iamVjdCBtLCB2OwogICAgICAgICAgICB2YXIgbWVzc2FnZSA9IGJvZHkgIT0gbnVsbCAmJiBib2R5LlRyeUdldFZhbHVlKCJtZXNzYWdlIiwgb3V0IG0pID8gbT8uVG9TdHJpbmcoKSA6IG51bGw7CiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGJvZHkgIT0gbnVsbCAmJiBib2R5LlRyeUdldFZhbHVlKCJ2YWx1ZSIsIG91dCB2KSA/IHYgOiBudWxsOwoKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAicGFyZW50LXNoYXJlZC11cGRhdGUtcHJvY2Vzc2VkIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzaGFyZWRVcGRhdGVGcm9tUGFyZW50ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gbWVzc2FnZSA/PyAibm8gbWVzc2FnZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtmbG93S2V5ID0gY29udGV4dC5Xb3JrZmxvdz8uS2V5LAogICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICAgICAgICAgIG5vdGUgPSAiUGFyZW50IGZsb3cgcHJvY2Vzc2VkIHRoaXMgd2hpbGUgaW4gc3ViZmxvdyAoaXNzdWUgIzQyNSB0ZXN0KSIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInN1YmZsb3ctdGVzdCIsICJzaGFyZWQtdHJhbnNpdGlvbiIsICJwYXJlbnQiLCAiaXNzdWUtNDI1IiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiUGFyZW50U2hhcmVkVXBkYXRlTWFwcGluZyAtIEVycm9yOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAicGFyZW50LXNoYXJlZC11cGRhdGUtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cg==" + } + } + ] + } + ], "startTransition": { "key": "start-parent", "target": "parent-initial", @@ -96,6 +150,16 @@ "subFlow": null, "onEntries": [], "onExits": [], + "queryRoles": [ + { + "role": "morph-idm.maker", + "grant": "allow" + }, + { + "role": "morph-idm.viewer", + "grant": "allow" + } + ], "transitions": [ { "key": "start-subflow", @@ -147,6 +211,57 @@ "mapping": { "location": "./src/SubFlowMapping.csx", "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLkR5bmFtaWM7CnVzaW5nIFN5c3RlbS5UaHJlYWRpbmcuVGFza3M7CnVzaW5nIEJCVC5Xb3JrZmxvdy5EZWZpbml0aW9uczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZy5GdW5jdGlvbnM7CgovLy8gPHN1bW1hcnk+Ci8vLyBTdWJGbG93IE1hcHBpbmcgLSBIYW5kbGVzIGlucHV0L291dHB1dCBmb3Igc3ViZmxvdyBzdGF0ZQovLy8gVGhpcyBtYXBwaW5nIHByZXBhcmVzIGRhdGEgZm9yIHN1YmZsb3cgYW5kIHByb2Nlc3NlcyBpdHMgcmVzdWx0Ci8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBTdWJGbG93TWFwcGluZyA6IFNjcmlwdEJhc2UsIElTdWJGbG93TWFwcGluZwp7CiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gUHJlcGFyZXMgaW5wdXQgZGF0YSBmb3IgdGhlIHN1YmZsb3cKICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJTdWJGbG93TWFwcGluZyAtIFByZXBhcmluZyBzdWJmbG93IGlucHV0IGRhdGEiKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFByZXBhcmUgZGF0YSB0byBwYXNzIHRvIGNoaWxkIHdvcmtmbG93IHVzaW5nIERpY3Rpb25hcnkKICAgICAgICAgICAgdmFyIHRlc3RDb250ZXh0ID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFsidGVzdFR5cGUiXSA9ICJ2aWV3LWV4dGVuc2lvbi1sb25ncG9sbGluZyIsCiAgICAgICAgICAgICAgICBbImV4cGVjdFZpZXdEYXRhIl0gPSB0cnVlLAogICAgICAgICAgICAgICAgWyJleHBlY3RFeHRlbnNpb25EYXRhIl0gPSB0cnVlCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICB2YXIgaW5wdXREYXRhID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFsicGFyZW50SW5zdGFuY2VJZCJdID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICBbInBhcmVudFdvcmtmbG93SWQiXSA9IGNvbnRleHQuV29ya2Zsb3c/LktleSA/PyBzdHJpbmcuRW1wdHksCiAgICAgICAgICAgICAgICBbImluaXRpYXRlZEF0Il0gPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICBbImluaXRpYXRlZEJ5Il0gPSAicGFyZW50LXdvcmtmbG93IiwKICAgICAgICAgICAgICAgIFsidGVzdENvbnRleHQiXSA9IHRlc3RDb250ZXh0CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9IGNvbnRleHQuSW5zdGFuY2U/LktleSwKICAgICAgICAgICAgICAgIERhdGEgPSBpbnB1dERhdGEsCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAic3ViZmxvdy10ZXN0IiwgInN1YmZsb3ctaW5wdXQiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0Vycm9yKCJTdWJGbG93TWFwcGluZyBJbnB1dEhhbmRsZXIgLSBFcnJvcjogezB9IiwgYXJnczogbmV3IG9iamVjdD9bXSB7IGV4Lk1lc3NhZ2UgfSk7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInN1YmZsb3ctaW5wdXQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0PiB7IFsiZXJyb3IiXSA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KCiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gUHJvY2Vzc2VzIHRoZSByZXN1bHQgZnJvbSB0aGUgY29tcGxldGVkIHN1YmZsb3cKICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiU3ViRmxvd01hcHBpbmcgLSBQcm9jZXNzaW5nIHN1YmZsb3cgb3V0cHV0IGRhdGEiKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEdldCBzdWJmbG93IHJlc3VsdCBkYXRhCiAgICAgICAgICAgIHZhciBzdWJmbG93UmVzdWx0ID0gY29udGV4dC5Cb2R5OwogICAgICAgICAgICAKICAgICAgICAgICAgdmFyIHN1YmZsb3dSZXN1bHREYXRhID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFsiY2hpbGRJbnN0YW5jZURhdGEiXSA9IHN1YmZsb3dSZXN1bHQsCiAgICAgICAgICAgICAgICBbInByb2Nlc3NlZCJdID0gdHJ1ZSwKICAgICAgICAgICAgICAgIFsidmlld1Rlc3RSZXN1bHQiXSA9ICJzdWNjZXNzIiwKICAgICAgICAgICAgICAgIFsiZXh0ZW5zaW9uVGVzdFJlc3VsdCJdID0gInN1Y2Nlc3MiCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICB2YXIgcGFyZW50Q29udGludWF0aW9uID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFsiY2FuUHJvY2VlZCJdID0gdHJ1ZSwKICAgICAgICAgICAgICAgIFsibmV4dFN0YXRlIl0gPSAicGFyZW50LWFmdGVyLXN1YmZsb3ciCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIAogICAgICAgICAgICB2YXIgb3V0cHV0RGF0YSA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbInN1YmZsb3dDb21wbGV0ZWQiXSA9IHRydWUsCiAgICAgICAgICAgICAgICBbImNvbXBsZXRlZEF0Il0gPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICBbInN1YmZsb3dSZXN1bHQiXSA9IHN1YmZsb3dSZXN1bHREYXRhLAogICAgICAgICAgICAgICAgWyJwYXJlbnRDb250aW51YXRpb24iXSA9IHBhcmVudENvbnRpbnVhdGlvbgogICAgICAgICAgICB9OwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAic3ViZmxvdy1vdXRwdXQtcHJvY2Vzc2VkIiwKICAgICAgICAgICAgICAgIERhdGEgPSBvdXRwdXREYXRhLAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInN1YmZsb3ctdGVzdCIsICJzdWJmbG93LW91dHB1dCIsICJjb21wbGV0ZWQiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0Vycm9yKCJTdWJGbG93TWFwcGluZyBPdXRwdXRIYW5kbGVyIC0gRXJyb3I6IHswfSIsIGFyZ3M6IG5ldyBvYmplY3Q/W10geyBleC5NZXNzYWdlIH0pOwogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzdWJmbG93LW91dHB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+IHsgWyJlcnJvciJdID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" + }, + "overrides": { + "timeout": { + "key": "push-timeout", + "target": "cancelled", + "versionStrategy": "Minor", + "timer": { + "reset": "OnEntry", + "duration": "PT25M" + } + }, + "transitions": { + "start-grandchild-subflow": { + "roles": [ + { + "role": "morph-idm.maker", + "grant": "allow" + }, + { + "role": "morph-idm.viewer", + "grant": "deny" + } + ] + } + }, + "states": { + "child-initial": { + "queryRoles": [ + { + "role": "morph-idm.maker", + "grant": "allow" + }, + { + "role": "morph-idm.viewer", + "grant": "deny" + } + ] + }, + "waiting-for-grandchild": { + "queryRoles": [ + { + "role": "morph-idm.maker", + "grant": "deny" + }, + { + "role": "morph-idm.viewer", + "grant": "deny" + } + ] + } + } } }, "onEntries": [], @@ -266,6 +381,27 @@ "onEntries": [], "onExits": [], "transitions": [] + }, + { + "key": "cancelled", + "stateType": 3, + "subType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Parent Workflow Cancelled" + }, + { + "language": "tr-TR", + "label": "Ana Akış İptal Edildi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] } ] } diff --git a/core/Workflows/subflow-test/subflow-view-test.http b/core/Workflows/subflow-test/subflow-view-test.http index 035bef0..aa33316 100644 --- a/core/Workflows/subflow-test/subflow-view-test.http +++ b/core/Workflows/subflow-test/subflow-view-test.http @@ -80,9 +80,24 @@ Content-Type: application/json GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/state Accept: application/json +### ============================================ +### STEP 6b: [Issue #425] Parent shared transition (target $self) while in subflow +### Call parent's shared transition on PARENT instance while it is in "waiting-for-subflow". +### Expected: Parent flow handles the transition (shared-transition policy); data merged into parent. +### ============================================ + +# @name parentSharedUpdate +PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/transitions/parent-shared-update +Content-Type: application/json + +{ + "message": "Update from client while parent is in subflow (issue #425)", + "value": 42 +} + ### ============================================ ### STEP 7: Get Parent Data to Find Child Instance ID -### Check parent data to find child instance ID +### Check parent data to find child instance ID (and sharedUpdateFromParent from step 6b) ### ============================================ # @name getParentDataForChildId @@ -141,9 +156,24 @@ Content-Type: application/json GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/state Accept: application/json +### ============================================ +### STEP 12b: [Issue #425] Child shared transition (target $self) while in grandchild subflow +### Call child's shared transition on CHILD instance while it is in "waiting-for-grandchild". +### Expected: Child flow handles the transition; data merged into child. +### ============================================ + +# @name childSharedUpdate +PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/transitions/child-shared-update +Content-Type: application/json + +{ + "message": "Update from client while child is in grandchild subflow (issue #425)", + "value": 100 +} + ### ============================================ ### STEP 13: Get Child Data to Find Grandchild Instance ID -### Check child data to find grandchild instance ID +### Check child data to find grandchild instance ID (and sharedUpdateFromChild from step 12b) ### ============================================ # @name getChildDataForGrandchildId diff --git a/core/Workflows/task-test/error-boundary-test-workflow.json b/core/Workflows/task-test/error-boundary-test-workflow.json index 6592fc3..70dffb4 100644 --- a/core/Workflows/task-test/error-boundary-test-workflow.json +++ b/core/Workflows/task-test/error-boundary-test-workflow.json @@ -33,31 +33,12 @@ "sharedTransitions": [], "errorBoundary": { "onError": [ - { - "action": 4, - "priority": 999, - "logOnly": false, - "transition": "recovery-to-rollback" - }, { "action": 5, "priority": 1000, "logOnly": true } - ], - "onTimeout": { - "action": 0, - "transition": "timeout-state", - "notificationConfig": { - "channel": "slack", - "recipients": [ - "#ops-alerts" - ], - "templateKey": "timeout-notification-template", - "includeErrorDetails": true, - "priority": "critical" - } - } + ] }, "startTransition": { "key": "start-error-boundary-test", @@ -112,27 +93,22 @@ { "order": 1, "task": { - "key": "error-boundary-retry-task", + "key": "error-boundary-ignore-task", "domain": "core", "version": "1.0.0", "flow": "sys-tasks" }, "mapping": { "location": "./src/ErrorBoundaryRetryMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBFcnJvckJvdW5kYXJ5IFJldHJ5IE1hcHBpbmcgLSBUZXN0cyBUYXNrLWxldmVsIHJldHJ5IHdpdGggZXhwb25lbnRpYWwgYmFja29mZgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRXJyb3JCb3VuZGFyeVJldHJ5TWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwogICAgICAgIH0KCiAgICAgICAgdmFyIHJlcXVlc3RCb2R5ID0gbmV3CiAgICAgICAgewogICAgICAgICAgICB0ZXN0SWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50ZXN0SWQgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgdGVzdFR5cGUgPSAidGFzay1ib3VuZGFyeS1yZXRyeSIsCiAgICAgICAgICAgIHRpbWVzdGFtcCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgbWVzc2FnZSA9ICJUZXN0aW5nIFRhc2stbGV2ZWwgRXJyb3JCb3VuZGFyeSB3aXRoIFJldHJ5IGFjdGlvbiIKICAgICAgICB9OwoKICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KTsKCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInJldHJ5LXN1Y2Nlc3MiLAogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRhc2tCb3VuZGFyeVJldHJ5UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPz8gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHJlc3BvbnNlPy5zdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgIHRlc3RUeXBlID0gIlRhc2stTGV2ZWwgRXJyb3JCb3VuZGFyeSBSZXRyeSIsCiAgICAgICAgICAgICAgICAgICAgY29tcGxldGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImVycm9yLWJvdW5kYXJ5LXRlc3QiLCAidGFzay1ib3VuZGFyeSIsICJyZXRyeSIgfQogICAgICAgIH07CiAgICB9Cn0KCg==" + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBFcnJvckJvdW5kYXJ5IFJldHJ5IE1hcHBpbmcgLSBUZXN0cyBUYXNrLWxldmVsIHJldHJ5IHdpdGggZXhwb25lbnRpYWwgYmFja29mZgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRXJyb3JCb3VuZGFyeVJldHJ5TWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwogICAgICAgIH0KCiAgICAgICAgdmFyIHJlcXVlc3RCb2R5ID0gbmV3CiAgICAgICAgewogICAgICAgICAgICB0ZXN0SWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50ZXN0SWQgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgdGVzdFR5cGUgPSAidGFzay1ib3VuZGFyeS1yZXRyeSIsCiAgICAgICAgICAgIHRpbWVzdGFtcCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgbWVzc2FnZSA9ICJUZXN0aW5nIFRhc2stbGV2ZWwgRXJyb3JCb3VuZGFyeSB3aXRoIFJldHJ5IGFjdGlvbiIKICAgICAgICB9OwoKICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KQoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwoKICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBLZXkgPSAicmV0cnktc3VjY2VzcyIsCiAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGFza0JvdW5kYXJ5UmV0cnlSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gcmVzcG9uc2U/LmlzU3VjY2VzcyA/PyBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gcmVzcG9uc2U/LnN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgdGVzdFR5cGUgPSAiVGFzay1MZXZlbCBFcnJvckJvdW5kYXJ5IFJldHJ5IiwKICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZXJyb3ItYm91bmRhcnktdGVzdCIsICJ0YXNrLWJvdW5kYXJ5IiwgInJldHJ5IiB9CiAgICAgICAgfTsKICAgIH0KfQoK" }, "errorBoundary": { "onError": [ { "action": 1, - "errorTypes": [ - "HttpRequestException", - "TaskCanceledException" - ], + "errorTypes": [], "errorCodes": [ - "503", - "502", - "504" + "400" ], "priority": 100, "retryPolicy": { @@ -144,12 +120,12 @@ } }, { - "action": 0, + "action": 5, + "errorTypes": [], "errorCodes": [ - "500" + "Task:400002" ], - "priority": 50, - "transition": "recovery-to-rollback" + "priority": 99 } ] } @@ -203,7 +179,7 @@ "errorBoundary": { "onError": [ { - "action": 3, + "action": 0, "errorCodes": [ "400", "404", @@ -445,7 +421,6 @@ "onError": [], "onTimeout": { "action": 0, - "transition": "timeout-state", "defaultRetryPolicy": { "maxRetries": 2, "initialDelay": "PT5S", diff --git a/core/Workflows/task-test/src/ErrorBoundaryRetryMapping.csx b/core/Workflows/task-test/src/ErrorBoundaryRetryMapping.csx index 098a75f..95f1f00 100644 --- a/core/Workflows/task-test/src/ErrorBoundaryRetryMapping.csx +++ b/core/Workflows/task-test/src/ErrorBoundaryRetryMapping.csx @@ -24,7 +24,7 @@ public class ErrorBoundaryRetryMapping : IMapping message = "Testing Task-level ErrorBoundary with Retry action" }; - httpTask.SetBody(requestBody); + httpTask.SetBody(requestBody) return Task.FromResult(new ScriptResponse()); } diff --git a/core/Workflows/task-test/task-test-subflow.json b/core/Workflows/task-test/task-test-subflow.json index 90deb96..5cc3a98 100644 --- a/core/Workflows/task-test/task-test-subflow.json +++ b/core/Workflows/task-test/task-test-subflow.json @@ -1,6 +1,7 @@ { "key": "task-test-subflow", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/core/Workflows/task-test/task-test-workflow.json b/core/Workflows/task-test/task-test-workflow.json index 4ef3b21..771f861 100644 --- a/core/Workflows/task-test/task-test-workflow.json +++ b/core/Workflows/task-test/task-test-workflow.json @@ -1,6 +1,7 @@ { "key": "task-test-workflow", "flow": "sys-flows", + "flowVersion": "1.0.0", "domain": "core", "version": "1.0.0", "tags": [ diff --git a/package-lock.json b/package-lock.json index dbc7861..af36ced 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,14 +10,14 @@ "hasInstallScript": true, "license": "MIT", "dependencies": { - "@burgan-tech/vnext-schema": "^0.0.33" + "@burgan-tech/vnext-schema": "^0.0.38" }, "bin": { "vnext-setup": "setup.js", "vnext-template": "init.js" }, "devDependencies": { - "@burgan-tech/vnext-schema": "^0.0.33", + "@burgan-tech/vnext-schema": "^0.0.38", "ajv": "^8.12.0", "ajv-formats": "^2.1.1" }, @@ -26,9 +26,9 @@ } }, "node_modules/@burgan-tech/vnext-schema": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@burgan-tech/vnext-schema/-/vnext-schema-0.0.33.tgz", - "integrity": "sha512-xDKVPuoib0jmfAI8vYFOvXWOq8Kl+K/QyEYHLH2Veib5QupZhqhFCIrUdw/uRzivAwQ2ZogAy/dd+9PIzD23+g==", + "version": "0.0.38", + "resolved": "https://registry.npmjs.org/@burgan-tech/vnext-schema/-/vnext-schema-0.0.38.tgz", + "integrity": "sha512-Lqrl5IjLVbJTirBSEK5w806PXjEJm6f/fR9rmvOMFkmvIII5vgFwKsL1cvfi28TIKp7UKwx/7vDZy71PQakyfA==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 52a1e6c..46841b6 100644 --- a/package.json +++ b/package.json @@ -55,11 +55,11 @@ "node": ">=16.0.0" }, "devDependencies": { - "@burgan-tech/vnext-schema": "^0.0.33", + "@burgan-tech/vnext-schema": "^0.0.38", "ajv": "^8.12.0", "ajv-formats": "^2.1.1" }, "dependencies": { - "@burgan-tech/vnext-schema": "^0.0.33" + "@burgan-tech/vnext-schema": "^0.0.38" } } diff --git a/validate.js b/validate.js index 5e735cb..499fd22 100644 --- a/validate.js +++ b/validate.js @@ -2,7 +2,8 @@ const fs = require('fs'); const path = require('path'); -const Ajv = require('ajv'); +const Ajv7 = require('ajv'); +const Ajv2019 = require('ajv/dist/2019'); const addFormats = require('ajv-formats'); // ANSI color codes for terminal output @@ -652,13 +653,18 @@ validate('JSON files schema validation using @burgan-tech/vnext-schema', () => { return true; } - // Initialize AJV with formats support - const ajv = new Ajv({ - strict: false, // Allow unknown keywords like enumDescriptions - allErrors: true, // Collect all errors - verbose: true // Include schema path in errors - }); - addFormats(ajv); + // Initialize AJV instances for draft-07 and draft 2019-09 + const ajv7 = new Ajv7({ strict: false, allErrors: true, verbose: true }); + addFormats(ajv7); + + const ajv2019 = new Ajv2019({ strict: false, allErrors: true, verbose: true }); + addFormats(ajv2019); + + // Pick the correct AJV instance based on the schema's $schema field + function getAjvInstance(schema) { + const draft = schema?.$schema || ''; + return draft.includes('2019-09') ? ajv2019 : ajv7; + } // Map directory names to schema types dynamically from paths config const directoryToSchemaType = { @@ -681,7 +687,7 @@ validate('JSON files schema validation using @burgan-tech/vnext-schema', () => { const schema = vnextSchema.getSchema ? vnextSchema.getSchema(schemaType) : null; if (schema) { validators[dirName] = { - validator: ajv.compile(schema), + validator: getAjvInstance(schema).compile(schema), type: schemaType }; } diff --git a/vnext.config.json b/vnext.config.json index 1c32a39..913b5ce 100644 --- a/vnext.config.json +++ b/vnext.config.json @@ -3,7 +3,7 @@ "description": "core Domain Definition Configuration", "domain": "core", "runtimeVersion": "0.0.32", - "schemaVersion": "0.0.33", + "schemaVersion": "0.0.38", "paths": { "componentsRoot": "core", "tasks": "Tasks", From ae2fb637c65ad6244063abdb84de10e372673ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tayfun=20Y=C4=B1lmaz?= Date: Tue, 7 Apr 2026 09:58:37 +0300 Subject: [PATCH 3/4] add test flows --- CLAUDE.md | 96 +++ .../multi-task-function-test.json | 50 ++ .../account-opening/payment-types.json | 31 + .../src/FunctionGetInstanceDataMapping.csx | 26 + .../src/FunctionOutputMapping.csx | 31 + .../src/FunctionValidatePoliciesMapping.csx | 48 ++ .../src/LookupPaymentTypes.csx | 28 + .../account-opening-master.json | 269 +++++++++ .../discovery/domain-start-schema.json | 46 ++ .../discovery/domain-update-schema.json | 50 ++ core/Tasks/discovery/check-domain-exists.json | 23 + .../discovery/check-health-endpoint.json | 26 + core/Tasks/discovery/fetch-domains-list.json | 28 + .../discovery/get-domain-health-url.json | 26 + .../discovery/register-domain-lifecycle.json | 21 + core/Tasks/discovery/register-domain.json | 27 + .../discovery/schedule-health-check.json | 24 + .../discovery/update-domain-lifecycle.json | 22 + core/Tasks/discovery/update-domain.json | 27 + .../Tasks/discovery/update-health-status.json | 27 + .../start-transfer-from-absence-entry.json | 30 + .../collection-object-test-workflow.json | 521 ++++++++++++++++ .../src/AlwaysTrueRule.csx | 10 + .../src/CreateAndSetMapping.csx | 85 +++ .../src/GetListAndAsListMapping.csx | 68 +++ .../src/InitCollectionTestMapping.csx | 32 + .../src/ListAddRemoveMapping.csx | 83 +++ .../src/ListFilterCountAnyMapping.csx | 87 +++ .../src/ListFirstLastMapping.csx | 84 +++ .../src/ListSelectMapping.csx | 74 +++ .../src/RemovePropertyToDictionaryMapping.csx | 94 +++ .../domain-health-check-workflow.json | 569 ++++++++++++++++++ .../domain-registration-workflow.json | 557 +++++++++++++++++ core/Workflows/discovery/domain-workflow.json | 102 ++++ .../discovery/src/AggregateResultsMapping.csx | 55 ++ .../src/CheckDomainDontMatchRule.csx | 46 ++ .../src/CheckDomainExistsMapping.csx | 149 +++++ .../src/CheckDomainHealthMapping.csx | 157 +++++ .../discovery/src/CheckDomainMatchRule.csx | 46 ++ .../src/CheckHealthEndpointMapping.csx | 151 +++++ .../discovery/src/CheckPaginationRule.csx | 27 + .../discovery/src/DomainExistsRule.csx | 66 ++ .../discovery/src/DomainNotExistsRule.csx | 31 + .../discovery/src/DomainsFetchedRule.csx | 22 + .../discovery/src/FetchDomainsListMapping.csx | 103 ++++ .../discovery/src/FetchFailedRule.csx | 22 + .../discovery/src/FetchNextPageMapping.csx | 110 ++++ .../src/GetDomainHealthUrlMapping.csx | 174 ++++++ .../discovery/src/HasMoreDomainsRule.csx | 32 + .../discovery/src/HealthCheckFailedRule.csx | 33 + .../discovery/src/HealthCheckPassedRule.csx | 33 + .../src/HealthCheckScheduledRule.csx | 31 + .../src/HealthCheckTriggeredRule.csx | 26 + .../src/HealthStatusUpdateSuccessRule.csx | 30 + .../discovery/src/HealthUrlMissingRule.csx | 29 + .../discovery/src/HealthUrlRetrievedRule.csx | 29 + .../discovery/src/InitialTransitionRule.csx | 25 + .../discovery/src/MarkUnhealthyRule.csx | 45 ++ .../discovery/src/NextPageFetchedRule.csx | 22 + .../Workflows/discovery/src/NoDomainsRule.csx | 26 + core/Workflows/discovery/src/NoNextRule.csx | 25 + .../discovery/src/PageCompleteRule.csx | 31 + .../discovery/src/ProcessPageMapping.csx | 103 ++++ .../src/RegisterDomainLifecycleMapping.csx | 128 ++++ .../discovery/src/RegisterDomainMapping.csx | 130 ++++ .../discovery/src/RegisterSuccessRule.csx | 31 + .../src/ScheduleHealthCheckMapping.csx | 83 +++ .../src/ScheduleHealthCheckTimerMapping.csx | 24 + .../discovery/src/ScheduleNextRunMapping.csx | 71 +++ .../src/ScheduleNextRunTimerMapping.csx | 24 + .../Workflows/discovery/src/ScheduledRule.csx | 22 + .../src/ShouldTriggerHealthCheckRule.csx | 22 + .../discovery/src/SkipHealthCheckRule.csx | 23 + .../discovery/src/ToCheckHealthRule.csx | 26 + .../discovery/src/ToCheckPaginationRule.csx | 21 + .../src/UpdateDomainLifecycleMapping.csx | 135 +++++ .../discovery/src/UpdateDomainMapping.csx | 130 ++++ .../src/UpdateHealthStatusMapping.csx | 171 ++++++ .../discovery/src/UpdateSuccessRule.csx | 31 + .../discovery/src/UpsertFailureRule.csx | 31 + .../discovery/src/UpsertSuccessRule.csx | 31 + .../test-error-boundary-flow.diagram.json | 32 + .../error-boundary/src/Trigger400Mapping.csx | 46 ++ .../error-boundary/src/Trigger404Mapping.csx | 43 ++ .../error-boundary/src/Trigger409Mapping.csx | 45 ++ .../error-boundary/src/Trigger500Mapping.csx | 48 ++ .../test-error-boundary-flow.http | 87 +++ .../test-error-boundary-flow.json | 391 ++++++++++++ core/Workflows/morph-touch/absence-entry.json | 146 +++++ .../src/CanStartTransferMapping.csx | 14 + .../StartTransferFromAbsenceEntryMapping.csx | 94 +++ .../self-loop-repro-workflow.json | 252 ++++++++ .../self-loop-repro/self-loop-repro.http | 54 ++ .../self-loop-repro/src/AlwaysTrueRule.csx | 13 + .../src/SelfLoopOnExecutionMapping.csx | 29 + .../self-loop-repro/src/StartMapping.csx | 28 + .../src/ChildSharedUpdateMapping.csx | 57 ++ .../src/ParentSharedUpdateMapping.csx | 58 ++ 98 files changed, 7572 insertions(+) create mode 100644 CLAUDE.md create mode 100644 core/Functions/account-opening/multi-task-function-test.json create mode 100644 core/Functions/account-opening/payment-types.json create mode 100644 core/Functions/account-opening/src/FunctionGetInstanceDataMapping.csx create mode 100644 core/Functions/account-opening/src/FunctionOutputMapping.csx create mode 100644 core/Functions/account-opening/src/FunctionValidatePoliciesMapping.csx create mode 100644 core/Functions/account-opening/src/LookupPaymentTypes.csx create mode 100644 core/Schemas/account-opening/account-opening-master.json create mode 100644 core/Schemas/discovery/domain-start-schema.json create mode 100644 core/Schemas/discovery/domain-update-schema.json create mode 100644 core/Tasks/discovery/check-domain-exists.json create mode 100644 core/Tasks/discovery/check-health-endpoint.json create mode 100644 core/Tasks/discovery/fetch-domains-list.json create mode 100644 core/Tasks/discovery/get-domain-health-url.json create mode 100644 core/Tasks/discovery/register-domain-lifecycle.json create mode 100644 core/Tasks/discovery/register-domain.json create mode 100644 core/Tasks/discovery/schedule-health-check.json create mode 100644 core/Tasks/discovery/update-domain-lifecycle.json create mode 100644 core/Tasks/discovery/update-domain.json create mode 100644 core/Tasks/discovery/update-health-status.json create mode 100644 core/Tasks/morph-touch/start-transfer-from-absence-entry.json create mode 100644 core/Workflows/collection-object-test/collection-object-test-workflow.json create mode 100644 core/Workflows/collection-object-test/src/AlwaysTrueRule.csx create mode 100644 core/Workflows/collection-object-test/src/CreateAndSetMapping.csx create mode 100644 core/Workflows/collection-object-test/src/GetListAndAsListMapping.csx create mode 100644 core/Workflows/collection-object-test/src/InitCollectionTestMapping.csx create mode 100644 core/Workflows/collection-object-test/src/ListAddRemoveMapping.csx create mode 100644 core/Workflows/collection-object-test/src/ListFilterCountAnyMapping.csx create mode 100644 core/Workflows/collection-object-test/src/ListFirstLastMapping.csx create mode 100644 core/Workflows/collection-object-test/src/ListSelectMapping.csx create mode 100644 core/Workflows/collection-object-test/src/RemovePropertyToDictionaryMapping.csx create mode 100644 core/Workflows/discovery/domain-health-check-workflow.json create mode 100644 core/Workflows/discovery/domain-registration-workflow.json create mode 100644 core/Workflows/discovery/domain-workflow.json create mode 100644 core/Workflows/discovery/src/AggregateResultsMapping.csx create mode 100644 core/Workflows/discovery/src/CheckDomainDontMatchRule.csx create mode 100644 core/Workflows/discovery/src/CheckDomainExistsMapping.csx create mode 100644 core/Workflows/discovery/src/CheckDomainHealthMapping.csx create mode 100644 core/Workflows/discovery/src/CheckDomainMatchRule.csx create mode 100644 core/Workflows/discovery/src/CheckHealthEndpointMapping.csx create mode 100644 core/Workflows/discovery/src/CheckPaginationRule.csx create mode 100644 core/Workflows/discovery/src/DomainExistsRule.csx create mode 100644 core/Workflows/discovery/src/DomainNotExistsRule.csx create mode 100644 core/Workflows/discovery/src/DomainsFetchedRule.csx create mode 100644 core/Workflows/discovery/src/FetchDomainsListMapping.csx create mode 100644 core/Workflows/discovery/src/FetchFailedRule.csx create mode 100644 core/Workflows/discovery/src/FetchNextPageMapping.csx create mode 100644 core/Workflows/discovery/src/GetDomainHealthUrlMapping.csx create mode 100644 core/Workflows/discovery/src/HasMoreDomainsRule.csx create mode 100644 core/Workflows/discovery/src/HealthCheckFailedRule.csx create mode 100644 core/Workflows/discovery/src/HealthCheckPassedRule.csx create mode 100644 core/Workflows/discovery/src/HealthCheckScheduledRule.csx create mode 100644 core/Workflows/discovery/src/HealthCheckTriggeredRule.csx create mode 100644 core/Workflows/discovery/src/HealthStatusUpdateSuccessRule.csx create mode 100644 core/Workflows/discovery/src/HealthUrlMissingRule.csx create mode 100644 core/Workflows/discovery/src/HealthUrlRetrievedRule.csx create mode 100644 core/Workflows/discovery/src/InitialTransitionRule.csx create mode 100644 core/Workflows/discovery/src/MarkUnhealthyRule.csx create mode 100644 core/Workflows/discovery/src/NextPageFetchedRule.csx create mode 100644 core/Workflows/discovery/src/NoDomainsRule.csx create mode 100644 core/Workflows/discovery/src/NoNextRule.csx create mode 100644 core/Workflows/discovery/src/PageCompleteRule.csx create mode 100644 core/Workflows/discovery/src/ProcessPageMapping.csx create mode 100644 core/Workflows/discovery/src/RegisterDomainLifecycleMapping.csx create mode 100644 core/Workflows/discovery/src/RegisterDomainMapping.csx create mode 100644 core/Workflows/discovery/src/RegisterSuccessRule.csx create mode 100644 core/Workflows/discovery/src/ScheduleHealthCheckMapping.csx create mode 100644 core/Workflows/discovery/src/ScheduleHealthCheckTimerMapping.csx create mode 100644 core/Workflows/discovery/src/ScheduleNextRunMapping.csx create mode 100644 core/Workflows/discovery/src/ScheduleNextRunTimerMapping.csx create mode 100644 core/Workflows/discovery/src/ScheduledRule.csx create mode 100644 core/Workflows/discovery/src/ShouldTriggerHealthCheckRule.csx create mode 100644 core/Workflows/discovery/src/SkipHealthCheckRule.csx create mode 100644 core/Workflows/discovery/src/ToCheckHealthRule.csx create mode 100644 core/Workflows/discovery/src/ToCheckPaginationRule.csx create mode 100644 core/Workflows/discovery/src/UpdateDomainLifecycleMapping.csx create mode 100644 core/Workflows/discovery/src/UpdateDomainMapping.csx create mode 100644 core/Workflows/discovery/src/UpdateHealthStatusMapping.csx create mode 100644 core/Workflows/discovery/src/UpdateSuccessRule.csx create mode 100644 core/Workflows/discovery/src/UpsertFailureRule.csx create mode 100644 core/Workflows/discovery/src/UpsertSuccessRule.csx create mode 100644 core/Workflows/error-boundary/.meta/test-error-boundary-flow.diagram.json create mode 100644 core/Workflows/error-boundary/src/Trigger400Mapping.csx create mode 100644 core/Workflows/error-boundary/src/Trigger404Mapping.csx create mode 100644 core/Workflows/error-boundary/src/Trigger409Mapping.csx create mode 100644 core/Workflows/error-boundary/src/Trigger500Mapping.csx create mode 100644 core/Workflows/error-boundary/test-error-boundary-flow.http create mode 100644 core/Workflows/error-boundary/test-error-boundary-flow.json create mode 100644 core/Workflows/morph-touch/absence-entry.json create mode 100644 core/Workflows/morph-touch/src/CanStartTransferMapping.csx create mode 100644 core/Workflows/morph-touch/src/StartTransferFromAbsenceEntryMapping.csx create mode 100644 core/Workflows/self-loop-repro/self-loop-repro-workflow.json create mode 100644 core/Workflows/self-loop-repro/self-loop-repro.http create mode 100644 core/Workflows/self-loop-repro/src/AlwaysTrueRule.csx create mode 100644 core/Workflows/self-loop-repro/src/SelfLoopOnExecutionMapping.csx create mode 100644 core/Workflows/self-loop-repro/src/StartMapping.csx create mode 100644 core/Workflows/subflow-test/src/ChildSharedUpdateMapping.csx create mode 100644 core/Workflows/subflow-test/src/ParentSharedUpdateMapping.csx diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..19e8220 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,96 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Commands + +```bash +npm run validate # Validate all components against schemas (run before every commit) +npm run build # Build runtime package (default) +npm run build:reference # Build reference package (exports only, for cross-domain usage) +npm run build:runtime # Explicitly build runtime package +npm test # Run tests +npm run sync-schema # Sync schema version from dependencies +``` + +## Architecture Overview + +This is a **vNext domain-driven workflow automation system**. The "core" domain defines workflows, tasks, views, schemas, functions, and extensions as JSON component files, which are deployed to a vNext Runtime engine. + +### Component Root + +All components live under `core/` organized by type: +- `core/Workflows/` — State machine definitions; each workflow folder may contain a `src/` subfolder for C# mapping files (`.csx`) +- `core/Tasks/` — Reusable task definitions (HTTP, subprocess, script, service) +- `core/Views/` — UI component definitions bound to workflow states +- `core/Schemas/` — JSON Schema definitions for data validation +- `core/Functions/` — Reusable business logic callable from workflows +`core/Extensions/` — Runtime capability extensions + +### Standard Component JSON Shape + +Every component regardless of type follows this envelope: + +```json +{ + "key": "kebab-case-name", + "version": "1.0.0", + "domain": "core", + "flow": "sys-workflows", + "flowVersion": "1.0.0", + "tags": ["searchable", "tags"], + "attributes": { /* type-specific content */ } +} +``` + +**Flow type values**: `sys-workflows`, `sys-tasks`, `sys-schemas`, `sys-views`, `sys-functions`, `sys-extensions` + +### C# Mapping Files + +Workflows reference C# script files (`.csx`) located in `src/` folders next to the workflow JSON. The vNext VS Code extension automatically handles base64-encoding these files into the workflow JSON when saving. **Never manually convert `.csx` files to base64.** + +### Build Outputs + +- **Runtime build** (`@burgan-tech/vnext-core-runtime`) — Complete domain structure for engine deployment +- **Reference build** (`@burgan-tech/vnext-core-reference`) — Exported components only, for cross-domain usage + +### Local Development Servers + +| Server | Port | Purpose | +|--------|------|---------| +| vNext Runtime | `localhost:4201` | Workflow engine; use for instance start, transitions, state queries | +| Mockoon | `localhost:3001` | External API mocks; all HTTP tasks point here | + +**Never** call the Mockoon API (`localhost:3001`) for workflow operations, and **never** hardcode production URLs in HTTP task configs — always use Mockoon during development. + +### HTTP Test Files + +Every workflow should have a `.http` test file demonstrating full instance progression. vNext Runtime API endpoints follow this pattern: + +```http +@baseUrl = http://localhost:4201 +@apiVersion = 1 +@domain = core + +### Start instance +POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{workflow-key}/instances/start + +### Execute transition +PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{workflow-key}/instances/{instanceKey}/transitions/{transitionKey} + +### Get state (long polling) +GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{workflow-key}/instances/{instanceKey}/functions/state +``` + +### Mockoon Mock Organization + +When adding new routes to `mockoon/`, always create a **folder with the domain name first**, then place routes inside. Endpoint pattern: `api/{domain}/{resource}/{action}`. Include success (2xx) and error (4xx/5xx) response scenarios with realistic latency (500–1000ms). + +## Critical Rules + +- Each workflow must have **exactly one** initial state (defined by `startTransition.target`). +- Auto transitions (`triggerType: 1`) must come in complementary pairs with mutually exclusive conditions. A lone auto transition is only valid if its rule always returns true (unconditional). +- All component references use the format: `{domain}/{component-type}/{key}/{version}` — strict mode is enabled in `vnext.config.json`. +- Run `npm run validate` after any component change. It validates JSON syntax and schema compliance for all components. +- JSON files use **2-space indentation**, double quotes, no trailing commas. +- All keys and file names use **kebab-case**; C# class names use **PascalCase**. diff --git a/core/Functions/account-opening/multi-task-function-test.json b/core/Functions/account-opening/multi-task-function-test.json new file mode 100644 index 0000000..459ba98 --- /dev/null +++ b/core/Functions/account-opening/multi-task-function-test.json @@ -0,0 +1,50 @@ +{ + "key": "multi-task-function-test", + "flow": "sys-functions", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "system", + "core", + "sys-extensions", + "components", + "users", + "lookup" + ], + "attributes": { + "scope": "I", + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "validate-account-policies", + "domain": "core", + "flow": "sys-tasks", + "version": "1.0.0" + }, + "mapping": { + "location": "./src/FunctionValidatePoliciesMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGFzayAxIG1hcHBpbmcgZm9yIG11bHRpLXRhc2sgZnVuY3Rpb24gdGVzdC4KLy8vIENhbGxzIHZhbGlkYXRlLWFjY291bnQtcG9saWNpZXMgSFRUUCB0YXNrIHdpdGggaW5zdGFuY2UgZGF0YS4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEZ1bmN0aW9uVmFsaWRhdGVQb2xpY2llc01hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICBpZiAoaHR0cFRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CgogICAgICAgIHZhciB1c2VyU2Vzc2lvbiA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnVzZXJTZXNzaW9uOwogICAgICAgIHZhciBhY2NvdW50VHlwZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFjY291bnRUeXBlOwoKICAgICAgICBodHRwVGFzay5TZXRCb2R5KG5ldwogICAgICAgIHsKICAgICAgICAgICAgdXNlcklkID0gdXNlclNlc3Npb24/LnVzZXJJZCwKICAgICAgICAgICAgYWNjb3VudFR5cGUgPSBhY2NvdW50VHlwZSA/PyAiZGVtYW5kLWRlcG9zaXQiLAogICAgICAgICAgICBjdXJyZW5jeSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmN1cnJlbmN5LAogICAgICAgICAgICByZXF1ZXN0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgIH0pOwoKICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICB7CiAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgIFsiWC1JbnN0YW5jZS1JZCJdID0gY29udGV4dC5JbnN0YW5jZT8uSWQuVG9TdHJpbmcoKSwKICAgICAgICAgICAgWyJYLVJlcXVlc3QtSWQiXSA9IGNvbnRleHQuSGVhZGVycz9bIngtcmVxdWVzdC1pZCJdID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCkKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBLZXkgPSAicG9saWN5LWNoZWNrLXJlc3VsdCIsCiAgICAgICAgICAgIERhdGEgPSBjb250ZXh0LkJvZHkKICAgICAgICB9KTsKICAgIH0KfQo=" + } + }, + { + "order": 2, + "task": { + "key": "get-data-from-workflow", + "domain": "core", + "flow": "sys-tasks", + "version": "1.0.0" + }, + "mapping": { + "location": "./src/FunctionGetInstanceDataMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGFzayAyIG1hcHBpbmcgZm9yIG11bHRpLXRhc2sgZnVuY3Rpb24gdGVzdC4KLy8vIEZldGNoZXMgY3VycmVudCB3b3JrZmxvdyBpbnN0YW5jZSBkYXRhIHZpYSBHZXRJbnN0YW5jZURhdGFUYXNrLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRnVuY3Rpb25HZXRJbnN0YW5jZURhdGFNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBpbnN0YW5jZVRhc2sgPSB0YXNrIGFzIEdldEluc3RhbmNlRGF0YVRhc2s7CiAgICAgICAgaW5zdGFuY2VUYXNrPy5TZXRJbnN0YW5jZShjb250ZXh0Lkluc3RhbmNlLktleSk7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBLZXkgPSAiaW5zdGFuY2UtZGF0YS1yZXN1bHQiLAogICAgICAgICAgICBEYXRhID0gY29udGV4dC5Cb2R5CiAgICAgICAgfSk7CiAgICB9Cn0K" + } + } + ], + "output": { + "location": "./src/FunctionOutputMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nOwoKLy8vIDxzdW1tYXJ5PgovLy8gT3V0cHV0IG1hcHBpbmcgZm9yIG11bHRpLXRhc2sgZnVuY3Rpb24gdGVzdC4KLy8vIE5vcm1hbGl6ZXMgcmVzdWx0cyBmcm9tIHZhbGlkYXRlLWFjY291bnQtcG9saWNpZXMgKHRhc2sgMSkgYW5kCi8vLyBnZXQtZGF0YS1mcm9tLXdvcmtmbG93ICh0YXNrIDIpIGludG8gYSBzaW5nbGUgcmVzcG9uc2UuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBGdW5jdGlvbk91dHB1dE1hcHBpbmcgOiBJT3V0cHV0SGFuZGxlcgp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIHBvbGljeVJlc3VsdCA9IGNvbnRleHQuT3V0cHV0UmVzcG9uc2VbInZhbGlkYXRlQWNjb3VudFBvbGljaWVzIl0uZGF0YTsKICAgICAgICB2YXIgaW5zdGFuY2VEYXRhID0gY29udGV4dC5PdXRwdXRSZXNwb25zZT9bImdldERhdGFGcm9tV29ya2Zsb3ciXS5kYXRhOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gIm11bHRpLXRhc2stZnVuY3Rpb24tb3V0cHV0IiwKICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwb2xpY3lWYWxpZGF0aW9uID0gcG9saWN5UmVzdWx0LAogICAgICAgICAgICAgICAgaW5zdGFuY2VTbmFwc2hvdCA9IGluc3RhbmNlRGF0YSwKICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIGluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgIGluc3RhbmNlS2V5ID0gY29udGV4dC5JbnN0YW5jZT8uS2V5LAogICAgICAgICAgICAgICAgbXVsdGkgPSB0cnVlCiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgIH0KfQo=" + } + } +} \ No newline at end of file diff --git a/core/Functions/account-opening/payment-types.json b/core/Functions/account-opening/payment-types.json new file mode 100644 index 0000000..7d9d348 --- /dev/null +++ b/core/Functions/account-opening/payment-types.json @@ -0,0 +1,31 @@ +{ + "key": "payment-types", + "flow": "sys-functions", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "system", + "core", + "sys-extensions", + "components", + "users", + "lookup" + ], + "attributes": { + "scope": "I", + "task": { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/LookupPaymentTypes.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGFzayAyIG1hcHBpbmcgZm9yIG11bHRpLXRhc2sgZnVuY3Rpb24gdGVzdC4KLy8vIEZldGNoZXMgY3VycmVudCB3b3JrZmxvdyBpbnN0YW5jZSBkYXRhIHZpYSBHZXRJbnN0YW5jZURhdGFUYXNrLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgTG9va3VwUGF5bWVudFR5cGVzIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInNlbGYtbG9vcC10YXNrLWRvbmUiLAogICAgICAgICAgICBEYXRhID0gbmV3IHsgCiAgICAgICAgICAgICAgICBleGVjdXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LCAKICAgICAgICAgICAgICAgIG5vdGUgPSAib25FeGVjdXRpb25UYXNrIHRhcmdldCBpcyBzZWxmIC0+IHJ1bGUgaW52YWxpZGF0ZWQsIG5vIDJuZCBsb29wIiwKICAgICAgICAgICAgICAgIGNvbmRpdGlvbiA9IDAKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgfQp9Cg==" + } + } + } +} \ No newline at end of file diff --git a/core/Functions/account-opening/src/FunctionGetInstanceDataMapping.csx b/core/Functions/account-opening/src/FunctionGetInstanceDataMapping.csx new file mode 100644 index 0000000..fbd525c --- /dev/null +++ b/core/Functions/account-opening/src/FunctionGetInstanceDataMapping.csx @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Task 2 mapping for multi-task function test. +/// Fetches current workflow instance data via GetInstanceDataTask. +/// +public class FunctionGetInstanceDataMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + var instanceTask = task as GetInstanceDataTask; + instanceTask?.SetInstance(context.Instance.Key); + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + return Task.FromResult(new ScriptResponse + { + Key = "instance-data-result", + Data = context.Body + }); + } +} diff --git a/core/Functions/account-opening/src/FunctionOutputMapping.csx b/core/Functions/account-opening/src/FunctionOutputMapping.csx new file mode 100644 index 0000000..d9b3428 --- /dev/null +++ b/core/Functions/account-opening/src/FunctionOutputMapping.csx @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Output mapping for multi-task function test. +/// Normalizes results from validate-account-policies (task 1) and +/// get-data-from-workflow (task 2) into a single response. +/// +public class FunctionOutputMapping : IOutputHandler +{ + public Task OutputHandler(ScriptContext context) + { + var policyResult = context.OutputResponse["validateAccountPolicies"].data; + var instanceData = context.OutputResponse?["getDataFromWorkflow"].data; + + return Task.FromResult(new ScriptResponse + { + Key = "multi-task-function-output", + Data = new + { + policyValidation = policyResult, + instanceSnapshot = instanceData, + normalizedAt = DateTime.UtcNow, + instanceId = context.Instance?.Id, + instanceKey = context.Instance?.Key, + multi = true + } + }); + } +} diff --git a/core/Functions/account-opening/src/FunctionValidatePoliciesMapping.csx b/core/Functions/account-opening/src/FunctionValidatePoliciesMapping.csx new file mode 100644 index 0000000..a934123 --- /dev/null +++ b/core/Functions/account-opening/src/FunctionValidatePoliciesMapping.csx @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Task 1 mapping for multi-task function test. +/// Calls validate-account-policies HTTP task with instance data. +/// +public class FunctionValidatePoliciesMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + var httpTask = task as HttpTask; + if (httpTask == null) + return Task.FromResult(new ScriptResponse()); + + var userSession = context.Instance?.Data?.userSession; + var accountType = context.Instance?.Data?.accountType; + + httpTask.SetBody(new + { + userId = userSession?.userId, + accountType = accountType ?? "demand-deposit", + currency = context.Instance?.Data?.currency, + requestedAt = DateTime.UtcNow + }); + + httpTask.SetHeaders(new Dictionary + { + ["Content-Type"] = "application/json", + ["X-Instance-Id"] = context.Instance?.Id.ToString(), + ["X-Request-Id"] = context.Headers?["x-request-id"] ?? Guid.NewGuid().ToString() + }); + + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + return Task.FromResult(new ScriptResponse + { + Key = "policy-check-result", + Data = context.Body + }); + } +} diff --git a/core/Functions/account-opening/src/LookupPaymentTypes.csx b/core/Functions/account-opening/src/LookupPaymentTypes.csx new file mode 100644 index 0000000..db8345c --- /dev/null +++ b/core/Functions/account-opening/src/LookupPaymentTypes.csx @@ -0,0 +1,28 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Task 2 mapping for multi-task function test. +/// Fetches current workflow instance data via GetInstanceDataTask. +/// +public class LookupPaymentTypes : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + return Task.FromResult(new ScriptResponse + { + Key = "self-loop-task-done", + Data = new { + executedAt = DateTime.UtcNow, + note = "onExecutionTask target is self -> rule invalidated, no 2nd loop", + condition = 0 + } + }); + } +} diff --git a/core/Schemas/account-opening/account-opening-master.json b/core/Schemas/account-opening/account-opening-master.json new file mode 100644 index 0000000..7676653 --- /dev/null +++ b/core/Schemas/account-opening/account-opening-master.json @@ -0,0 +1,269 @@ +{ + "key": "account-opening-master", + "version": "1.0.0", + "domain": "core", + "flow": "sys-schemas", + "flowVersion": "1.0.0", + "tags": [ + "banking", + "account-opening", + "master-schema", + "role-visibility", + "demand-deposit" + ], + "attributes": { + "type": "workflow", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.vnext.com/banking/account-opening-master.json", + "title": "Account Opening Workflow Master Schema", + "description": "Master schema for account-opening instance data with field-level visibility (x-roles). Used by function response filtering per request header role.", + "type": "object", + "additionalProperties": true, + "properties": { + "initial": { + "type": "object", + "description": "Initial request/session data", + "additionalProperties": true, + "properties": { + "session": { + "type": "string", + "description": "Session identifier" + }, + "requestId": { + "type": "string", + "description": "Request correlation ID", + "roles": [ + { "role": "morph-idm.maker", "grant": "allow" }, + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + } + } + }, + "currency": { + "type": "string", + "description": "Account currency" + }, + "confirmed": { + "type": "boolean", + "description": "User confirmation flag" + }, + "branchCode": { + "type": "string", + "description": "Branch code", + "roles": [ + { "role": "$PreviousUser", "grant": "allow" } + ] + }, + "accountName": { + "type": "string", + "description": "Account name/alias", + "roles": [ + { "role": "$InstanceStarter", "grant": "allow" } + ] + }, + "accountType": { + "type": "string", + "description": "Account type (e.g. demand-deposit)" + }, + "userSession": { + "type": "object", + "description": "User/session context; restricted to approver and above", + "additionalProperties": true, + "properties": { + "userId": { + "type": "string", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "deviceId": { + "type": "string", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "ipAddress": { + "type": "string", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "userAgent": { + "type": "string", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + } + } + }, + "notifications": { + "type": "object", + "description": "Notification preferences", + "additionalProperties": true, + "properties": { + "smsNotifications": { "type": "boolean" }, + "pushNotifications": { "type": "boolean" }, + "emailNotifications": { "type": "boolean" } + } + }, + "termsAccepted": { + "type": "boolean" + }, + "accountPurpose": { + "type": "string" + }, + "accountSummary": { + "type": "object", + "description": "Summary of created account", + "additionalProperties": true, + "properties": { + "iban": { "type": "string" }, + "status": { "type": "string" }, + "currency": { "type": "string" }, + "createdAt": { "type": "string", "format": "date-time" }, + "accountType": { "type": "string" }, + "accountNumber": { "type": "string" } + } + }, + "initialDeposit": { + "type": "number", + "description": "Initial deposit amount" + }, + "accountCreation": { + "type": "object", + "description": "Full account creation result; internal IDs and limits restricted", + "additionalProperties": true, + "properties": { + "iban": { "type": "string" }, + "limits": { + "type": "object", + "additionalProperties": true, + "properties": { + "maximumBalance": { "type": "number" }, + "minimumBalance": { "type": "number" }, + "dailyTransactionLimit": { "type": "number" }, + "monthlyTransactionLimit": { "type": "number" } + }, + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "status": { "type": "string" }, + "success": { "type": "boolean" }, + "currency": { "type": "string" }, + "isActive": { "type": "boolean" }, + "services": { + "type": "array", + "items": { "type": "string" } + }, + "accountId": { + "type": "string", + "roles": [ + { "role": "morph-idm.maker", "grant": "allow" }, + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "createdAt": { "type": "string", "format": "date-time" }, + "branchCode": { "type": "string" }, + "accountType": { "type": "string" }, + "accountNumber": { "type": "string" }, + "coreBankingId": { + "type": "string", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "currentBalance": { "type": "number" }, + "availableBalance": { "type": "number" }, + "creationReference": { + "type": "string", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "debitCardRequested": { "type": "boolean" }, + "mobileBankingEnabled": { "type": "boolean" }, + "onlineBankingEnabled": { "type": "boolean" } + } + }, + "policyValidation": { + "type": "object", + "description": "Policy/compliance validation result; internal details restricted", + "additionalProperties": true, + "properties": { + "passed": { "type": "boolean" }, + "approvedBy": { + "type": "string", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "validatedAt": { "type": "string", "format": "date-time" }, + "validationId": { + "type": "string", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "accountLimits": { + "type": "object", + "additionalProperties": true, + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "approvalLevel": { + "type": "string", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "policyVersion": { "type": "string" }, + "validationScore": { + "type": "number", + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "complianceChecks": { + "type": "object", + "additionalProperties": true, + "properties": { + "amlCompliant": { "type": "boolean" }, + "kycCompliant": { "type": "boolean" }, + "riskAssessment": { "type": "string" }, + "sanctionsCheck": { "type": "boolean" } + }, + "roles": [ + { "role": "morph-idm.approver", "grant": "allow" }, + { "role": "morph-idm.manager", "grant": "allow" } + ] + }, + "additionalRequirements": { + "type": "array", + "items": {} + } + } + }, + "privacyPolicyAccepted": { + "type": "boolean" + } + } + } + } +} diff --git a/core/Schemas/discovery/domain-start-schema.json b/core/Schemas/discovery/domain-start-schema.json new file mode 100644 index 0000000..6fdd921 --- /dev/null +++ b/core/Schemas/discovery/domain-start-schema.json @@ -0,0 +1,46 @@ +{ + "key": "domain-start", + "version": "1.0.0", + "domain": "core", + "flow": "sys-schemas", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "workflow", + "instance", + "lookup", + "registration" + ], + "attributes": { + "type": "workflow", + "schema": { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://schemas.vnext.com/banking/domain-start.json", + "title": "Domain start transition Schema", + "description": "Domain start transition Schema", + "type": "object", + "required": [ + "domainName" + ], + "properties": { + "domainName": { + "type": "string", + "description": "Domain name identifier" + }, + "baseUrl": { + "type": "string", + "description": "Base URL of the domain service" + }, + "healthUrl": { + "type": "string", + "description": "Health check URL of the domain service" + }, + "appId": { + "type": "string", + "description": "Application identifier" + } + }, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/core/Schemas/discovery/domain-update-schema.json b/core/Schemas/discovery/domain-update-schema.json new file mode 100644 index 0000000..a3fc34e --- /dev/null +++ b/core/Schemas/discovery/domain-update-schema.json @@ -0,0 +1,50 @@ +{ + "key": "domain-update", + "version": "1.0.0", + "domain": "core", + "flow": "sys-schemas", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "workflow", + "instance", + "lookup", + "registration" + ], + "attributes": { + "type": "workflow", + "schema": { + "$id": "https://schemas.vnext.com/banking/domain-update.json", + "title": "Domain update transition Schema", + "description": "Domain update transition Schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "required": [ + "domainName" + ], + "properties": { + "domainName": { + "type": "string", + "description": "Domain name identifier" + }, + "baseUrl": { + "type": "string", + "description": "Base URL of the domain service" + }, + "healthUrl": { + "type": "string", + "description": "Health check URL of the domain service" + }, + "appId": { + "type": "string", + "description": "Application identifier" + }, + "eTag": { + "type": "string", + "description": "Entity tag for optimistic concurrency control" + } + }, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/core/Tasks/discovery/check-domain-exists.json b/core/Tasks/discovery/check-domain-exists.json new file mode 100644 index 0000000..3e1d982 --- /dev/null +++ b/core/Tasks/discovery/check-domain-exists.json @@ -0,0 +1,23 @@ +{ + "key": "check-domain-exists", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "workflow", + "instance", + "lookup", + "registration" + ], + "attributes": { + "type": "3", + "config": { + "appId": "{{discoveryAPPId}}", + "methodName": "/api/v1/core/workflows/domain/instances/{domainName}/functions/data", + "httpVerb": "GET" + } + } +} + diff --git a/core/Tasks/discovery/check-health-endpoint.json b/core/Tasks/discovery/check-health-endpoint.json new file mode 100644 index 0000000..b27bfce --- /dev/null +++ b/core/Tasks/discovery/check-health-endpoint.json @@ -0,0 +1,26 @@ +{ + "key": "check-health-endpoint", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "health-check", + "http", + "monitoring" + ], + "attributes": { + "type": "6", + "config": { + "url": "", + "method": "GET", + "headers": { + "Content-Type": "application/json" + }, + "timeoutSeconds": 5, + "validateSsl": true + } + } +} + diff --git a/core/Tasks/discovery/fetch-domains-list.json b/core/Tasks/discovery/fetch-domains-list.json new file mode 100644 index 0000000..597b440 --- /dev/null +++ b/core/Tasks/discovery/fetch-domains-list.json @@ -0,0 +1,28 @@ +{ + "key": "fetch-domains-list", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "api", + "http", + "fetch", + "pagination" + ], + "attributes": { + "type": "6", + "config": { + "url": "{{discoveryBaseUrl}}/api/v1/core/workflows/domain/functions/data?Page=1&PageSize=10", + "method": "GET", + "headers": { + "Content-Type": "application/json", + "accept": "*/*" + }, + "timeoutSeconds": 30, + "validateSsl": false + } + } +} + diff --git a/core/Tasks/discovery/get-domain-health-url.json b/core/Tasks/discovery/get-domain-health-url.json new file mode 100644 index 0000000..99ea987 --- /dev/null +++ b/core/Tasks/discovery/get-domain-health-url.json @@ -0,0 +1,26 @@ +{ + "key": "get-domain-health-url", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "redis", + "health-check", + "lookup" + ], + "attributes": { + "type": "6", + "config": { + "url": "{{discoveryDaprUrl}}/v1.0/state/vnext-execution-state/domain:{domainName}", + "method": "GET", + "headers": { + "Content-Type": "application/json" + }, + "timeoutSeconds": 10, + "validateSsl": true + } + } +} + diff --git a/core/Tasks/discovery/register-domain-lifecycle.json b/core/Tasks/discovery/register-domain-lifecycle.json new file mode 100644 index 0000000..d206823 --- /dev/null +++ b/core/Tasks/discovery/register-domain-lifecycle.json @@ -0,0 +1,21 @@ +{ + "key": "register-domain-lifecycle", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "start", + "lifecycle", + "register" + ], + "attributes": { + "type": "11", + "config": { + "domain": "core", + "flow": "domain" + } + } +} + diff --git a/core/Tasks/discovery/register-domain.json b/core/Tasks/discovery/register-domain.json new file mode 100644 index 0000000..438cb97 --- /dev/null +++ b/core/Tasks/discovery/register-domain.json @@ -0,0 +1,27 @@ +{ + "key": "register-domain", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "redis", + "create", + "registration" + ], + "attributes": { + "type": "6", + "config": { + "url": "{{discoveryDaprUrl}/v1.0/state/vnext-execution-state", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "body": {}, + "timeoutSeconds": 10, + "validateSsl": false + } + } +} + diff --git a/core/Tasks/discovery/schedule-health-check.json b/core/Tasks/discovery/schedule-health-check.json new file mode 100644 index 0000000..a7213a0 --- /dev/null +++ b/core/Tasks/discovery/schedule-health-check.json @@ -0,0 +1,24 @@ +{ + "key": "schedule-health-check", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "subprocess", + "health-check", + "trigger" + ], + "attributes": { + "type": "14", + "config": { + "domain": "core", + "flow": "domain-health-check", + "version": "1.0.0" + } + } +} + + + diff --git a/core/Tasks/discovery/update-domain-lifecycle.json b/core/Tasks/discovery/update-domain-lifecycle.json new file mode 100644 index 0000000..1026f52 --- /dev/null +++ b/core/Tasks/discovery/update-domain-lifecycle.json @@ -0,0 +1,22 @@ +{ + "key": "update-domain-lifecycle", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "trigger", + "lifecycle", + "update" + ], + "attributes": { + "type": "12", + "config": { + "domain": "core", + "flow": "domain", + "transitionName": "update" + } + } +} + diff --git a/core/Tasks/discovery/update-domain.json b/core/Tasks/discovery/update-domain.json new file mode 100644 index 0000000..1f5b4f3 --- /dev/null +++ b/core/Tasks/discovery/update-domain.json @@ -0,0 +1,27 @@ +{ + "key": "update-domain", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "redis", + "update", + "registration" + ], + "attributes": { + "type": "6", + "config": { + "url": "{{discoveryDaprUrl}/v1.0/state/vnext-execution-state", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "body": {}, + "timeoutSeconds": 10, + "validateSsl": false + } + } +} + diff --git a/core/Tasks/discovery/update-health-status.json b/core/Tasks/discovery/update-health-status.json new file mode 100644 index 0000000..475e0a9 --- /dev/null +++ b/core/Tasks/discovery/update-health-status.json @@ -0,0 +1,27 @@ +{ + "key": "update-health-status", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "domain", + "redis", + "health-check", + "update" + ], + "attributes": { + "type": "6", + "config": { + "url": "{{discoveryDaprUrl}/v1.0/state/vnext-execution-state", + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "body": {}, + "timeoutSeconds": 10, + "validateSsl": false + } + } +} + diff --git a/core/Tasks/morph-touch/start-transfer-from-absence-entry.json b/core/Tasks/morph-touch/start-transfer-from-absence-entry.json new file mode 100644 index 0000000..07327e3 --- /dev/null +++ b/core/Tasks/morph-touch/start-transfer-from-absence-entry.json @@ -0,0 +1,30 @@ +{ + "key": "start-transfer-from-absence-entry", + "flow": "sys-tasks", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "absence-entry", + "transfer", + "start-task" + ], + "attributes": { + "type": "11", + "labels": [ + { + "label": "Start Transfer from Absence Entry", + "language": "en-US" + }, + { + "label": "Yokluk Kaydından Transfer Başlat", + "language": "tr-TR" + } + ], + "description": "StartTask that starts a rezervation-transfer subflow when a personal-leave absence-entry is created.", + "config": { + "domain": "touch", + "flow": "rezervation-transfer" + } + } +} \ No newline at end of file diff --git a/core/Workflows/collection-object-test/collection-object-test-workflow.json b/core/Workflows/collection-object-test/collection-object-test-workflow.json new file mode 100644 index 0000000..199bf5a --- /dev/null +++ b/core/Workflows/collection-object-test/collection-object-test-workflow.json @@ -0,0 +1,521 @@ +{ + "key": "collection-object-test-workflow", + "flow": "sys-flows", + "flowVersion": "1.0.0", + "domain": "core", + "version": "1.0.0", + "tags": [ + "collection-object-test", + "dynamic-collection", + "dynamic-object", + "script-base", + "integration-test", + "create-object", + "create-list", + "set-property", + "get-list", + "as-list", + "list-filter", + "list-count", + "list-any", + "list-first", + "list-last", + "list-select", + "list-add", + "list-remove", + "remove-property", + "to-dictionary" + ], + "attributes": { + "type": "F", + "timeout": null, + "labels": [ + { + "language": "en-US", + "label": "Dynamic Collection & Object Test Workflow" + }, + { + "language": "tr-TR", + "label": "Dinamik Koleksiyon ve Nesne Test İş Akışı" + } + ], + "functions": [], + "features": [], + "extensions": [], + "sharedTransitions": [], + "startTransition": { + "key": "start-collection-test", + "target": "test-create-and-set-state", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Start Collection & Object Test" + }, + { + "language": "tr-TR", + "label": "Koleksiyon ve Nesne Testini Başlat" + } + ], + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/InitCollectionTestMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gSW5pdGlhbCB0cmFuc2l0aW9uIG1hcHBpbmcgLSBJbml0aWFsaXplcyB0aGUgY29sbGVjdGlvbi9vYmplY3QgdGVzdCB3b3JrZmxvdwovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgSW5pdENvbGxlY3Rpb25UZXN0TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgTG9nSW5mb3JtYXRpb24oIkNvbGxlY3Rpb25PYmplY3RUZXN0IC0gV29ya2Zsb3cgaW5pdGlhbGl6ZWQiKTsKCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICB7CiAgICAgICAgICAgIEtleSA9ICJpbml0LXN1Y2Nlc3MiLAogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRlc3RJZCA9IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgfSwKICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImNvbGxlY3Rpb24tb2JqZWN0LXRlc3QiLCAiaW5pdGlhbGl6ZWQiIH0KICAgICAgICB9KTsKICAgIH0KfQo=" + } + } + ] + }, + "states": [ + { + "key": "test-create-and-set-state", + "stateType": 1, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test CreateObject, CreateList, SetProperty, ListAdd" + }, + { + "language": "tr-TR", + "label": "CreateObject, CreateList, SetProperty, ListAdd Testi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/CreateAndSetMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGVzdHM6IENyZWF0ZU9iamVjdCgpLCBDcmVhdGVMaXN0KCksIFNldFByb3BlcnR5KCksIExpc3RBZGQoKQovLy8gQ3JlYXRlcyBhIGxpc3Qgb2YgMyBkeW5hbWljIHBlcnNvbiBvYmplY3RzIGFuZCBzdG9yZXMgdGhlbSBpbiBJbnN0YW5jZS5EYXRhLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgQ3JlYXRlQW5kU2V0TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiQ3JlYXRlQW5kU2V0IFRlc3QgLSBTdGFydGluZyIpOwoKICAgICAgICAgICAgLy8gVGVzdCBDcmVhdGVPYmplY3QoKSArIFNldFByb3BlcnR5KCkKICAgICAgICAgICAgZHluYW1pYyBpdGVtMSA9IENyZWF0ZU9iamVjdCgpOwogICAgICAgICAgICBTZXRQcm9wZXJ0eShpdGVtMSwgImlkIiwgIml0ZW0tMDAxIik7CiAgICAgICAgICAgIFNldFByb3BlcnR5KGl0ZW0xLCAibmFtZSIsICJBbGljZSIpOwogICAgICAgICAgICBTZXRQcm9wZXJ0eShpdGVtMSwgImFnZSIsIDMwKTsKICAgICAgICAgICAgU2V0UHJvcGVydHkoaXRlbTEsICJzdGF0dXMiLCAiYWN0aXZlIik7CgogICAgICAgICAgICBkeW5hbWljIGl0ZW0yID0gQ3JlYXRlT2JqZWN0KCk7CiAgICAgICAgICAgIFNldFByb3BlcnR5KGl0ZW0yLCAiaWQiLCAiaXRlbS0wMDIiKTsKICAgICAgICAgICAgU2V0UHJvcGVydHkoaXRlbTIsICJuYW1lIiwgIkJvYiIpOwogICAgICAgICAgICBTZXRQcm9wZXJ0eShpdGVtMiwgImFnZSIsIDI1KTsKICAgICAgICAgICAgU2V0UHJvcGVydHkoaXRlbTIsICJzdGF0dXMiLCAiaW5hY3RpdmUiKTsKCiAgICAgICAgICAgIGR5bmFtaWMgaXRlbTMgPSBDcmVhdGVPYmplY3QoKTsKICAgICAgICAgICAgU2V0UHJvcGVydHkoaXRlbTMsICJpZCIsICJpdGVtLTAwMyIpOwogICAgICAgICAgICBTZXRQcm9wZXJ0eShpdGVtMywgIm5hbWUiLCAiQ2hhcmxpZSIpOwogICAgICAgICAgICBTZXRQcm9wZXJ0eShpdGVtMywgImFnZSIsIDM1KTsKICAgICAgICAgICAgU2V0UHJvcGVydHkoaXRlbTMsICJzdGF0dXMiLCAiYWN0aXZlIik7CgogICAgICAgICAgICAvLyBUZXN0IENyZWF0ZUxpc3QoKSArIExpc3RBZGQoKQogICAgICAgICAgICB2YXIgaXRlbXMgPSBDcmVhdGVMaXN0KCk7CiAgICAgICAgICAgIExpc3RBZGQoaXRlbXMsIGl0ZW0xKTsKICAgICAgICAgICAgTGlzdEFkZChpdGVtcywgaXRlbTIpOwogICAgICAgICAgICBMaXN0QWRkKGl0ZW1zLCBpdGVtMyk7CgogICAgICAgICAgICAvLyBOZXN0ZWQgZHluYW1pYyBvYmplY3QgZm9yIG1ldGFkYXRhCiAgICAgICAgICAgIGR5bmFtaWMgbWV0YWRhdGEgPSBDcmVhdGVPYmplY3QoKTsKICAgICAgICAgICAgU2V0UHJvcGVydHkobWV0YWRhdGEsICJjcmVhdGVkQXQiLCBEYXRlVGltZS5VdGNOb3cuVG9TdHJpbmcoIk8iKSk7CiAgICAgICAgICAgIFNldFByb3BlcnR5KG1ldGFkYXRhLCAic291cmNlIiwgImNvbGxlY3Rpb24tb2JqZWN0LXRlc3QiKTsKICAgICAgICAgICAgU2V0UHJvcGVydHkobWV0YWRhdGEsICJpdGVtQ291bnQiLCBpdGVtcy5Db3VudCk7CgogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiQ3JlYXRlQW5kU2V0IFRlc3QgLSBDcmVhdGVkIHswfSBpdGVtcyIsIGFyZ3M6IG5ldyBvYmplY3RbXSB7IGl0ZW1zLkNvdW50IH0pOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImNyZWF0ZS1hbmQtc2V0LXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGl0ZW1zID0gaXRlbXMsCiAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGEgPSBtZXRhZGF0YSwKICAgICAgICAgICAgICAgICAgICBjcmVhdGVBbmRTZXRSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBvYmplY3RzQ3JlYXRlZCA9IDMsCiAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RJdGVtQ291bnQgPSBpdGVtcy5Db3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllc1NldCA9IHRydWUKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImNvbGxlY3Rpb24tb2JqZWN0LXRlc3QiLCAiY3JlYXRlLWFuZC1zZXQiLCAic3VjY2VzcyIgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0Vycm9yKCJDcmVhdGVBbmRTZXQgVGVzdCAtIEZhaWxlZDogezB9IiwgYXJnczogbmV3IG9iamVjdFtdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImNyZWF0ZS1hbmQtc2V0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9Cn0K" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "create-and-set-completed", + "target": "test-get-list-state", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "CreateObject / SetProperty Completed" + }, + { + "language": "tr-TR", + "label": "CreateObject / SetProperty Tamamlandı" + } + ], + "schema": null, + "rule": { + "location": "./src/AlwaysTrueRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "test-get-list-state", + "stateType": 2, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test GetList, AsList" + }, + { + "language": "tr-TR", + "label": "GetList, AsList Testi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/GetListAndAsListMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGVzdHM6IEdldExpc3QoKSwgQXNMaXN0KCkKLy8vIFJldHJpZXZlcyB0aGUgaXRlbXMgbGlzdCBmcm9tIEluc3RhbmNlLkRhdGEgYW5kIHZlcmlmaWVzIEFzTGlzdCgpIGVkZ2UgY2FzZXMuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBHZXRMaXN0QW5kQXNMaXN0TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiR2V0TGlzdCBhbmQgQXNMaXN0IFRlc3QgLSBTdGFydGluZyIpOwoKICAgICAgICAgICAgdmFyIGluc3RhbmNlRGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE7CgogICAgICAgICAgICAvLyBUZXN0IEdldExpc3QoKSAtIHJldHJpZXZlIGl0ZW1zIGZyb20gaW5zdGFuY2UgZGF0YSBieSBwcm9wZXJ0eSBuYW1lCiAgICAgICAgICAgIHZhciBpdGVtcyA9IEdldExpc3QoaW5zdGFuY2VEYXRhLCAiaXRlbXMiKTsKCiAgICAgICAgICAgIC8vIFRlc3QgQXNMaXN0KCkgd2l0aCBhIHZhbGlkIGxpc3QgLSBzaG91bGQgcmV0dXJuIHNhbWUgaXRlbXMKICAgICAgICAgICAgdmFyIGFzTGlzdEZyb21WYWxpZCA9IEFzTGlzdChpdGVtcyk7CgogICAgICAgICAgICAvLyBUZXN0IEFzTGlzdCgpIHdpdGggbnVsbCAtIHNob3VsZCByZXR1cm4gZW1wdHkgbGlzdCAoZ3JhY2VmdWwgZGVncmFkYXRpb24pCiAgICAgICAgICAgIHZhciBhc0xpc3RGcm9tTnVsbCA9IEFzTGlzdChudWxsKTsKCiAgICAgICAgICAgIC8vIFRlc3QgQXNMaXN0KCkgd2l0aCBhIG5vbi1saXN0IHZhbHVlIC0gc2hvdWxkIHJldHVybiBlbXB0eSBsaXN0CiAgICAgICAgICAgIHZhciBhc0xpc3RGcm9tU3RyaW5nID0gQXNMaXN0KCJub3QgYSBsaXN0Iik7CgogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiR2V0TGlzdCBUZXN0IC0gUmV0cmlldmVkIHswfSBpdGVtcyIsIGFyZ3M6IG5ldyBvYmplY3RbXSB7IGl0ZW1zLkNvdW50IH0pOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdldC1saXN0LXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGdldExpc3RSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBpdGVtQ291bnQgPSBpdGVtcy5Db3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TGlzdFdvcmtlZCA9IGl0ZW1zLkNvdW50ID09IDMsCiAgICAgICAgICAgICAgICAgICAgICAgIGFzTGlzdEZyb21WYWxpZENvdW50ID0gYXNMaXN0RnJvbVZhbGlkLkNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICBhc0xpc3ROdWxsUmV0dXJuc0VtcHR5ID0gYXNMaXN0RnJvbU51bGwuQ291bnQgPT0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgYXNMaXN0SW52YWxpZFJldHVybnNFbXB0eSA9IGFzTGlzdEZyb21TdHJpbmcuQ291bnQgPT0gMAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiY29sbGVjdGlvbi1vYmplY3QtdGVzdCIsICJnZXQtbGlzdCIsICJhcy1saXN0IiwgInN1Y2Nlc3MiIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiR2V0TGlzdCBUZXN0IC0gRmFpbGVkOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0W10geyBleC5NZXNzYWdlIH0pOwogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZ2V0LWxpc3QtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KfQo=" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "get-list-completed", + "target": "test-filter-count-any-state", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "GetList / AsList Completed" + }, + { + "language": "tr-TR", + "label": "GetList / AsList Tamamlandı" + } + ], + "schema": null, + "rule": { + "location": "./src/AlwaysTrueRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "test-filter-count-any-state", + "stateType": 2, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test ListFilter, ListCount, ListAny" + }, + { + "language": "tr-TR", + "label": "ListFilter, ListCount, ListAny Testi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/ListFilterCountAnyMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGVzdHM6IExpc3RGaWx0ZXIoKSwgTGlzdENvdW50KCksIExpc3RBbnkoKQovLy8gVXNlcyB0aGUgaXRlbXMgbGlzdCAoQWxpY2U9YWN0aXZlLCBCb2I9aW5hY3RpdmUsIENoYXJsaWU9YWN0aXZlKSBmcm9tIEluc3RhbmNlLkRhdGEuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBMaXN0RmlsdGVyQ291bnRBbnlNYXBwaW5nIDogU2NyaXB0QmFzZSwgSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJMaXN0RmlsdGVyLCBMaXN0Q291bnQsIExpc3RBbnkgVGVzdCAtIFN0YXJ0aW5nIik7CgogICAgICAgICAgICBvYmplY3QgaW5zdGFuY2VEYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKICAgICAgICAgICAgdmFyIGl0ZW1zID0gR2V0TGlzdChpbnN0YW5jZURhdGEsICJpdGVtcyIpOwoKICAgICAgICAgICAgLy8gVGVzdCBMaXN0RmlsdGVyKCkgLSBmaWx0ZXIgYWN0aXZlIGl0ZW1zIChBbGljZSArIENoYXJsaWUpCiAgICAgICAgICAgIHZhciBhY3RpdmVJdGVtcyA9IExpc3RGaWx0ZXIoaXRlbXMsIHggPT4geC5zdGF0dXMgPT0gImFjdGl2ZSIpOwoKICAgICAgICAgICAgLy8gVGVzdCBMaXN0Q291bnQoKSAtIG5vIHByZWRpY2F0ZSAodG90YWwpCiAgICAgICAgICAgIHZhciB0b3RhbENvdW50ID0gTGlzdENvdW50KGl0ZW1zKTsKCiAgICAgICAgICAgIC8vIFRlc3QgTGlzdENvdW50KCkgd2l0aCBwcmVkaWNhdGUKICAgICAgICAgICAgdmFyIGFjdGl2ZUNvdW50ID0gTGlzdENvdW50KGl0ZW1zLCB4ID0+IHguc3RhdHVzID09ICJhY3RpdmUiKTsKICAgICAgICAgICAgdmFyIGluYWN0aXZlQ291bnQgPSBMaXN0Q291bnQoaXRlbXMsIHggPT4geC5zdGF0dXMgPT0gImluYWN0aXZlIik7CgogICAgICAgICAgICAvLyBUZXN0IExpc3RBbnkoKSAtIG5vIHByZWRpY2F0ZSAoaGFzIGFueSBlbGVtZW50KQogICAgICAgICAgICB2YXIgaGFzSXRlbXMgPSBMaXN0QW55KGl0ZW1zKTsKCiAgICAgICAgICAgIC8vIFRlc3QgTGlzdEFueSgpIHdpdGggcHJlZGljYXRlCiAgICAgICAgICAgIHZhciBoYXNBY3RpdmUgPSBMaXN0QW55KGl0ZW1zLCB4ID0+IHguc3RhdHVzID09ICJhY3RpdmUiKTsKICAgICAgICAgICAgdmFyIGhhc0FkbWluUm9sZSA9IExpc3RBbnkoaXRlbXMsIHggPT4geC5zdGF0dXMgPT0gImFkbWluIik7CgogICAgICAgICAgICAvLyBFbXB0eSBsaXN0IGNoZWNrcwogICAgICAgICAgICB2YXIgZW1wdHlMaXN0ID0gQ3JlYXRlTGlzdCgpOwogICAgICAgICAgICB2YXIgZW1wdHlIYXNJdGVtcyA9IExpc3RBbnkoZW1wdHlMaXN0KTsKICAgICAgICAgICAgdmFyIGVtcHR5Q291bnQgPSBMaXN0Q291bnQoZW1wdHlMaXN0KTsKCiAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJMaXN0RmlsdGVyOiBhY3RpdmU9ezB9LCBpbmFjdGl2ZT17MX0sIHRvdGFsPXsyfSIsCiAgICAgICAgICAgICAgICBhcmdzOiBuZXcgb2JqZWN0W10geyBhY3RpdmVDb3VudCwgaW5hY3RpdmVDb3VudCwgdG90YWxDb3VudCB9KTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJmaWx0ZXItY291bnQtYW55LXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZpbHRlckNvdW50QW55UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxDb3VudCA9IHRvdGFsQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUNvdW50ID0gYWN0aXZlQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgIGluYWN0aXZlQ291bnQgPSBpbmFjdGl2ZUNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVJdGVtc0ZpbHRlcmVkID0gYWN0aXZlSXRlbXMuQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgIGhhc0l0ZW1zID0gaGFzSXRlbXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGhhc0FjdGl2ZSA9IGhhc0FjdGl2ZSwKICAgICAgICAgICAgICAgICAgICAgICAgaGFzQWRtaW5Sb2xlID0gaGFzQWRtaW5Sb2xlLAogICAgICAgICAgICAgICAgICAgICAgICBlbXB0eUxpc3RIYXNJdGVtcyA9IGVtcHR5SGFzSXRlbXMsCiAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5TGlzdENvdW50ID0gZW1wdHlDb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyV29ya2VkID0gYWN0aXZlSXRlbXMuQ291bnQgPT0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgY291bnRXb3JrZWQgPSB0b3RhbENvdW50ID09IDMgJiYgYWN0aXZlQ291bnQgPT0gMiAmJiBpbmFjdGl2ZUNvdW50ID09IDEsCiAgICAgICAgICAgICAgICAgICAgICAgIGFueVdvcmtlZCA9IGhhc0l0ZW1zICYmIGhhc0FjdGl2ZSAmJiAhaGFzQWRtaW5Sb2xlICYmICFlbXB0eUhhc0l0ZW1zCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJjb2xsZWN0aW9uLW9iamVjdC10ZXN0IiwgImxpc3QtZmlsdGVyIiwgImxpc3QtY291bnQiLCAibGlzdC1hbnkiLCAic3VjY2VzcyIgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0Vycm9yKCJMaXN0RmlsdGVyL0NvdW50L0FueSBUZXN0IC0gRmFpbGVkOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0W10geyBleC5NZXNzYWdlIH0pOwogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZmlsdGVyLWNvdW50LWFueS1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQp9Cg==" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "filter-count-any-completed", + "target": "test-first-last-state", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "ListFilter / ListCount / ListAny Completed" + }, + { + "language": "tr-TR", + "label": "ListFilter / ListCount / ListAny Tamamlandı" + } + ], + "schema": null, + "rule": { + "location": "./src/AlwaysTrueRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "test-first-last-state", + "stateType": 2, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test ListFirst, ListLast" + }, + { + "language": "tr-TR", + "label": "ListFirst, ListLast Testi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/ListFirstLastMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGVzdHM6IExpc3RGaXJzdCgpLCBMaXN0TGFzdCgpCi8vLyBJdGVtcyBvcmRlcjogQWxpY2UoYWN0aXZlKSwgQm9iKGluYWN0aXZlKSwgQ2hhcmxpZShhY3RpdmUpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBMaXN0Rmlyc3RMYXN0TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiTGlzdEZpcnN0IGFuZCBMaXN0TGFzdCBUZXN0IC0gU3RhcnRpbmciKTsKCiAgICAgICAgICAgIG9iamVjdCBpbnN0YW5jZURhdGEgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhOwogICAgICAgICAgICB2YXIgaXRlbXMgPSBHZXRMaXN0KGluc3RhbmNlRGF0YSwgIml0ZW1zIik7CgogICAgICAgICAgICAvLyBUZXN0IExpc3RGaXJzdCgpIHdpdGhvdXQgcHJlZGljYXRlIOKGkiBBbGljZQogICAgICAgICAgICB2YXIgZmlyc3QgPSBMaXN0Rmlyc3QoaXRlbXMpOwoKICAgICAgICAgICAgLy8gVGVzdCBMaXN0Rmlyc3QoKSB3aXRoIHByZWRpY2F0ZSDihpIgZmlyc3QgYWN0aXZlID0gQWxpY2UsIGZpcnN0IGluYWN0aXZlID0gQm9iCiAgICAgICAgICAgIHZhciBmaXJzdEFjdGl2ZSA9IExpc3RGaXJzdChpdGVtcywgeCA9PiB4LnN0YXR1cyA9PSAiYWN0aXZlIik7CiAgICAgICAgICAgIHZhciBmaXJzdEluYWN0aXZlID0gTGlzdEZpcnN0KGl0ZW1zLCB4ID0+IHguc3RhdHVzID09ICJpbmFjdGl2ZSIpOwoKICAgICAgICAgICAgLy8gVGVzdCBMaXN0Rmlyc3QoKSB3aXRoIG5vIG1hdGNoIOKGkiBudWxsCiAgICAgICAgICAgIHZhciBmaXJzdE5vdEZvdW5kID0gTGlzdEZpcnN0KGl0ZW1zLCB4ID0+IHguc3RhdHVzID09ICJhZG1pbiIpOwoKICAgICAgICAgICAgLy8gVGVzdCBMaXN0TGFzdCgpIHdpdGhvdXQgcHJlZGljYXRlIOKGkiBDaGFybGllCiAgICAgICAgICAgIHZhciBsYXN0ID0gTGlzdExhc3QoaXRlbXMpOwoKICAgICAgICAgICAgLy8gVGVzdCBMaXN0TGFzdCgpIHdpdGggcHJlZGljYXRlIOKGkiBsYXN0IGFjdGl2ZSA9IENoYXJsaWUKICAgICAgICAgICAgdmFyIGxhc3RBY3RpdmUgPSBMaXN0TGFzdChpdGVtcywgeCA9PiB4LnN0YXR1cyA9PSAiYWN0aXZlIik7CgogICAgICAgICAgICAvLyBUZXN0IG9uIGVtcHR5IGxpc3Qg4oaSIG51bGwKICAgICAgICAgICAgdmFyIGVtcHR5Rmlyc3QgPSBMaXN0Rmlyc3QoQ3JlYXRlTGlzdCgpKTsKICAgICAgICAgICAgdmFyIGVtcHR5TGFzdCA9IExpc3RMYXN0KENyZWF0ZUxpc3QoKSk7CgogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiRmlyc3Q6IHswfSwgTGFzdDogezF9IiwgYXJnczogbmV3IG9iamVjdFtdIHsgZmlyc3Q/Lm5hbWUsIGxhc3Q/Lm5hbWUgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZmlyc3QtbGFzdC1zdWNjZXNzIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBmaXJzdExhc3RSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBmaXJzdE5hbWUgPSAoc3RyaW5nKShmaXJzdD8ubmFtZSA/PyAibnVsbCIpLAogICAgICAgICAgICAgICAgICAgICAgICBsYXN0TmFtZSA9IChzdHJpbmcpKGxhc3Q/Lm5hbWUgPz8gIm51bGwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RBY3RpdmVOYW1lID0gKHN0cmluZykoZmlyc3RBY3RpdmU/Lm5hbWUgPz8gIm51bGwiKSwKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RJbmFjdGl2ZU5hbWUgPSAoc3RyaW5nKShmaXJzdEluYWN0aXZlPy5uYW1lID8/ICJudWxsIiksCiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RBY3RpdmVOYW1lID0gKHN0cmluZykobGFzdEFjdGl2ZT8ubmFtZSA/PyAibnVsbCIpLAogICAgICAgICAgICAgICAgICAgICAgICBmaXJzdE5vdEZvdW5kSXNOdWxsID0gZmlyc3ROb3RGb3VuZCA9PSBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICBlbXB0eUZpcnN0SXNOdWxsID0gZW1wdHlGaXJzdCA9PSBudWxsLAogICAgICAgICAgICAgICAgICAgICAgICBlbXB0eUxhc3RJc051bGwgPSBlbXB0eUxhc3QgPT0gbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RXb3JrZWQgPSBmaXJzdD8uaWQgPT0gIml0ZW0tMDAxIiwKICAgICAgICAgICAgICAgICAgICAgICAgbGFzdFdvcmtlZCA9IGxhc3Q/LmlkID09ICJpdGVtLTAwMyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0V2l0aFByZWRpY2F0ZVdvcmtlZCA9IGZpcnN0QWN0aXZlPy5pZCA9PSAiaXRlbS0wMDEiLAogICAgICAgICAgICAgICAgICAgICAgICBsYXN0V2l0aFByZWRpY2F0ZVdvcmtlZCA9IGxhc3RBY3RpdmU/LmlkID09ICJpdGVtLTAwMyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImNvbGxlY3Rpb24tb2JqZWN0LXRlc3QiLCAibGlzdC1maXJzdCIsICJsaXN0LWxhc3QiLCAic3VjY2VzcyIgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0Vycm9yKCJMaXN0Rmlyc3QvTGFzdCBUZXN0IC0gRmFpbGVkOiB7MH0iLCBhcmdzOiBuZXcgb2JqZWN0W10geyBleC5NZXNzYWdlIH0pOwogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZmlyc3QtbGFzdC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQp9Cg==" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "first-last-completed", + "target": "test-list-select-state", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "ListFirst / ListLast Completed" + }, + { + "language": "tr-TR", + "label": "ListFirst / ListLast Tamamlandı" + } + ], + "schema": null, + "rule": { + "location": "./src/AlwaysTrueRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "test-list-select-state", + "stateType": 2, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test ListSelect" + }, + { + "language": "tr-TR", + "label": "ListSelect Testi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/ListSelectMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGVzdHM6IExpc3RTZWxlY3QmbHQ7VFJlc3VsdCZndDsoKQovLy8gUHJvamVjdHMgbGlzdCBpdGVtcyBpbnRvIGRpZmZlcmVudCB0eXBlczogc3RyaW5nLCBpbnQsIG9iamVjdAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgTGlzdFNlbGVjdE1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkxpc3RTZWxlY3QgVGVzdCAtIFN0YXJ0aW5nIik7CgogICAgICAgICAgICBvYmplY3QgaW5zdGFuY2VEYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKICAgICAgICAgICAgdmFyIGl0ZW1zID0gR2V0TGlzdChpbnN0YW5jZURhdGEsICJpdGVtcyIpOwoKICAgICAgICAgICAgLy8gVGVzdCBMaXN0U2VsZWN0PHN0cmluZz4oKSAtIGV4dHJhY3QgbmFtZXMKICAgICAgICAgICAgdmFyIG5hbWVzID0gTGlzdFNlbGVjdDxzdHJpbmc+KGl0ZW1zLCB4ID0+IChzdHJpbmcpeC5uYW1lKTsKCiAgICAgICAgICAgIC8vIFRlc3QgTGlzdFNlbGVjdDxpbnQ+KCkgLSBleHRyYWN0IGFnZXMKICAgICAgICAgICAgdmFyIGFnZXMgPSBMaXN0U2VsZWN0PGludD4oaXRlbXMsIHggPT4gKGludCl4LmFnZSk7CgogICAgICAgICAgICAvLyBUZXN0IExpc3RTZWxlY3Q8c3RyaW5nPigpIHdpdGggdHJhbnNmb3JtYXRpb24KICAgICAgICAgICAgdmFyIGxhYmVscyA9IExpc3RTZWxlY3Q8c3RyaW5nPihpdGVtcywgeCA9PiAkInt4Lm5hbWV9ICh7eC5zdGF0dXN9KSIpOwoKICAgICAgICAgICAgLy8gVGVzdCBMaXN0U2VsZWN0IG9uIGVtcHR5IGxpc3QgLSBzaG91bGQgcmV0dXJuIGVtcHR5IGxpc3QKICAgICAgICAgICAgdmFyIGVtcHR5UmVzdWx0ID0gTGlzdFNlbGVjdDxzdHJpbmc+KENyZWF0ZUxpc3QoKSwgeCA9PiAoc3RyaW5nKXgubmFtZSk7CgogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiTGlzdFNlbGVjdDogezB9IG5hbWVzLCB7MX0gYWdlcyIsIGFyZ3M6IG5ldyBvYmplY3RbXSB7IG5hbWVzLkNvdW50LCBhZ2VzLkNvdW50IH0pOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImxpc3Qtc2VsZWN0LXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGxpc3RTZWxlY3RSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lcyA9IG5hbWVzLAogICAgICAgICAgICAgICAgICAgICAgICBhZ2VzID0gYWdlcywKICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gbGFiZWxzLAogICAgICAgICAgICAgICAgICAgICAgICBuYW1lc0NvdW50ID0gbmFtZXMuQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgIGFnZXNDb3VudCA9IGFnZXMuQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5U2VsZWN0Q291bnQgPSBlbXB0eVJlc3VsdC5Db3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0U3RyaW5nV29ya2VkID0gbmFtZXMuQ291bnQgPT0gMyAmJiBuYW1lc1swXSA9PSAiQWxpY2UiLAogICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RJbnRXb3JrZWQgPSBhZ2VzLkNvdW50ID09IDMgJiYgYWdlc1swXSA9PSAzMCwKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0VHJhbnNmb3JtV29ya2VkID0gbGFiZWxzLkNvdW50ID09IDMsCiAgICAgICAgICAgICAgICAgICAgICAgIGVtcHR5U2VsZWN0V29ya2VkID0gZW1wdHlSZXN1bHQuQ291bnQgPT0gMAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiY29sbGVjdGlvbi1vYmplY3QtdGVzdCIsICJsaXN0LXNlbGVjdCIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIkxpc3RTZWxlY3QgVGVzdCAtIEZhaWxlZDogezB9IiwgYXJnczogbmV3IG9iamVjdFtdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImxpc3Qtc2VsZWN0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9Cn0K" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "list-select-completed", + "target": "test-add-remove-state", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "ListSelect Completed" + }, + { + "language": "tr-TR", + "label": "ListSelect Tamamlandı" + } + ], + "schema": null, + "rule": { + "location": "./src/AlwaysTrueRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "test-add-remove-state", + "stateType": 2, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test ListAdd, ListRemove" + }, + { + "language": "tr-TR", + "label": "ListAdd, ListRemove Testi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/ListAddRemoveMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGVzdHM6IExpc3RBZGQoKSwgTGlzdFJlbW92ZSgpCi8vLyBTdGFydHMgd2l0aCBBbGljZShhY3RpdmUpLCBCb2IoaW5hY3RpdmUpLCBDaGFybGllKGFjdGl2ZSkuCi8vLyBBZGRzIERpYW5hKGFjdGl2ZSkg4oaSIHJlbW92ZXMgYWxsIGluYWN0aXZlIChCb2IpIOKGkiBlbmRzIHdpdGggQWxpY2UsIENoYXJsaWUsIERpYW5hLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgTGlzdEFkZFJlbW92ZU1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkxpc3RBZGQgYW5kIExpc3RSZW1vdmUgVGVzdCAtIFN0YXJ0aW5nIik7CgogICAgICAgICAgICBvYmplY3Q/IGluc3RhbmNlRGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE7CiAgICAgICAgICAgIHZhciBpdGVtcyA9IEdldExpc3QoaW5zdGFuY2VEYXRhLCAiaXRlbXMiKTsKCiAgICAgICAgICAgIHZhciBjb3VudEJlZm9yZSA9IExpc3RDb3VudChpdGVtcyk7CgogICAgICAgICAgICAvLyBUZXN0IExpc3RBZGQoKSAtIGFkZCBhIG5ldyBpdGVtCiAgICAgICAgICAgIGR5bmFtaWMgbmV3SXRlbSA9IENyZWF0ZU9iamVjdCgpOwogICAgICAgICAgICBTZXRQcm9wZXJ0eShuZXdJdGVtLCAiaWQiLCAiaXRlbS0wMDQiKTsKICAgICAgICAgICAgU2V0UHJvcGVydHkobmV3SXRlbSwgIm5hbWUiLCAiRGlhbmEiKTsKICAgICAgICAgICAgU2V0UHJvcGVydHkobmV3SXRlbSwgImFnZSIsIDI4KTsKICAgICAgICAgICAgU2V0UHJvcGVydHkobmV3SXRlbSwgInN0YXR1cyIsICJhY3RpdmUiKTsKCiAgICAgICAgICAgIExpc3RBZGQoaXRlbXMsIG5ld0l0ZW0pOwoKICAgICAgICAgICAgdmFyIGNvdW50QWZ0ZXJBZGQgPSBMaXN0Q291bnQoaXRlbXMpOwoKICAgICAgICAgICAgLy8gVGVzdCBMaXN0UmVtb3ZlKCkgLSByZW1vdmUgYWxsIGluYWN0aXZlIGl0ZW1zIChCb2IpCiAgICAgICAgICAgIHZhciByZW1vdmVkQ291bnQgPSBMaXN0UmVtb3ZlKGl0ZW1zLCB4ID0+IHguc3RhdHVzID09ICJpbmFjdGl2ZSIpOwoKICAgICAgICAgICAgdmFyIGNvdW50QWZ0ZXJSZW1vdmUgPSBMaXN0Q291bnQoaXRlbXMpOwoKICAgICAgICAgICAgLy8gVmVyaWZ5IG5vIGluYWN0aXZlIGl0ZW1zIHJlbWFpbgogICAgICAgICAgICB2YXIgaGFzSW5hY3RpdmVBZnRlclJlbW92ZSA9IExpc3RBbnkoaXRlbXMsIHggPT4geC5zdGF0dXMgPT0gImluYWN0aXZlIik7CgogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiQWRkL1JlbW92ZTogYmVmb3JlPXswfSwgYWZ0ZXJBZGQ9ezF9LCByZW1vdmVkPXsyfSwgYWZ0ZXJSZW1vdmU9ezN9IiwKICAgICAgICAgICAgICAgIGFyZ3M6IG5ldyBvYmplY3RbXSB7IGNvdW50QmVmb3JlLCBjb3VudEFmdGVyQWRkLCByZW1vdmVkQ291bnQsIGNvdW50QWZ0ZXJSZW1vdmUgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiYWRkLXJlbW92ZS1zdWNjZXNzIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpdGVtcyA9IGl0ZW1zLAogICAgICAgICAgICAgICAgICAgIGxpc3RBZGRSZW1vdmVSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBjb3VudEJlZm9yZSA9IGNvdW50QmVmb3JlLAogICAgICAgICAgICAgICAgICAgICAgICBjb3VudEFmdGVyQWRkID0gY291bnRBZnRlckFkZCwKICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlZENvdW50ID0gcmVtb3ZlZENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICBjb3VudEFmdGVyUmVtb3ZlID0gY291bnRBZnRlclJlbW92ZSwKICAgICAgICAgICAgICAgICAgICAgICAgaGFzSW5hY3RpdmVBZnRlclJlbW92ZSA9IGhhc0luYWN0aXZlQWZ0ZXJSZW1vdmUsCiAgICAgICAgICAgICAgICAgICAgICAgIGFkZFdvcmtlZCA9IGNvdW50QWZ0ZXJBZGQgPT0gY291bnRCZWZvcmUgKyAxLAogICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVXb3JrZWQgPSByZW1vdmVkQ291bnQgPT0gMSAmJiAhaGFzSW5hY3RpdmVBZnRlclJlbW92ZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiY29sbGVjdGlvbi1vYmplY3QtdGVzdCIsICJsaXN0LWFkZCIsICJsaXN0LXJlbW92ZSIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIkxpc3RBZGQvUmVtb3ZlIFRlc3QgLSBGYWlsZWQ6IHswfSIsIGFyZ3M6IG5ldyBvYmplY3RbXSB7IGV4Lk1lc3NhZ2UgfSk7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJhZGQtcmVtb3ZlLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9Cn0K" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "add-remove-completed", + "target": "test-remove-prop-to-dict-state", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "ListAdd / ListRemove Completed" + }, + { + "language": "tr-TR", + "label": "ListAdd / ListRemove Tamamlandı" + } + ], + "schema": null, + "rule": { + "location": "./src/AlwaysTrueRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "test-remove-prop-to-dict-state", + "stateType": 2, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test RemoveProperty, ToDictionary, HasProperty" + }, + { + "language": "tr-TR", + "label": "RemoveProperty, ToDictionary, HasProperty Testi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/RemovePropertyToDictionaryMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGVzdHM6IFJlbW92ZVByb3BlcnR5KCksIFRvRGljdGlvbmFyeSgpLCBIYXNQcm9wZXJ0eSgpCi8vLyBDcmVhdGVzIGEgZHluYW1pYyBvYmplY3QsIHJlbW92ZXMgYSBwcm9wZXJ0eSwgY29udmVydHMgdG8gZGljdGlvbmFyeS4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFJlbW92ZVByb3BlcnR5VG9EaWN0aW9uYXJ5TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiUmVtb3ZlUHJvcGVydHkgYW5kIFRvRGljdGlvbmFyeSBUZXN0IC0gU3RhcnRpbmciKTsKCiAgICAgICAgICAgIC8vIENyZWF0ZSBhIHRlc3Qgb2JqZWN0IHdpdGggbXVsdGlwbGUgcHJvcGVydGllcwogICAgICAgICAgICBkeW5hbWljIHRlc3RPYmogPSBDcmVhdGVPYmplY3QoKTsKICAgICAgICAgICAgU2V0UHJvcGVydHkodGVzdE9iaiwgImlkIiwgInRlc3QtMDAxIik7CiAgICAgICAgICAgIFNldFByb3BlcnR5KHRlc3RPYmosICJuYW1lIiwgIlRlc3QgT2JqZWN0Iik7CiAgICAgICAgICAgIFNldFByb3BlcnR5KHRlc3RPYmosICJ0ZW1wRmllbGQiLCAidGhpcyB3aWxsIGJlIHJlbW92ZWQiKTsKICAgICAgICAgICAgU2V0UHJvcGVydHkodGVzdE9iaiwgImtlZXBGaWVsZCIsICJ0aGlzIHN0YXlzIik7CgogICAgICAgICAgICAvLyBWZXJpZnkgcHJvcGVydHkgZXhpc3RzIGJlZm9yZSByZW1vdmFsICh1c2VzIEhhc1Byb3BlcnR5IGZyb20gU2NyaXB0QmFzZSkKICAgICAgICAgICAgdmFyIGhhZFRlbXBGaWVsZCA9IEhhc1Byb3BlcnR5KHRlc3RPYmosICJ0ZW1wRmllbGQiKTsKICAgICAgICAgICAgdmFyIGhhZEtlZXBGaWVsZCA9IEhhc1Byb3BlcnR5KHRlc3RPYmosICJrZWVwRmllbGQiKTsKCiAgICAgICAgICAgIC8vIFRlc3QgUmVtb3ZlUHJvcGVydHkoKQogICAgICAgICAgICB2YXIgcmVtb3ZlUmVzdWx0ID0gUmVtb3ZlUHJvcGVydHkodGVzdE9iaiwgInRlbXBGaWVsZCIpOwoKICAgICAgICAgICAgLy8gVmVyaWZ5IHByb3BlcnR5IGlzIGdvbmUKICAgICAgICAgICAgdmFyIGhhc1RlbXBGaWVsZEFmdGVyID0gSGFzUHJvcGVydHkodGVzdE9iaiwgInRlbXBGaWVsZCIpOwogICAgICAgICAgICB2YXIgaGFzS2VlcEZpZWxkQWZ0ZXIgPSBIYXNQcm9wZXJ0eSh0ZXN0T2JqLCAia2VlcEZpZWxkIik7CgogICAgICAgICAgICAvLyBUZXN0IFJlbW92ZVByb3BlcnR5KCkgb24gbm9uLWV4aXN0ZW50IHByb3BlcnR5IOKGkiBmYWxzZQogICAgICAgICAgICB2YXIgcmVtb3ZlTm9uRXhpc3RlbnQgPSBSZW1vdmVQcm9wZXJ0eSh0ZXN0T2JqLCAiZG9lc05vdEV4aXN0Iik7CgogICAgICAgICAgICAvLyBUZXN0IFRvRGljdGlvbmFyeSgpCiAgICAgICAgICAgIHZhciBkaWN0ID0gVG9EaWN0aW9uYXJ5KHRlc3RPYmopOwogICAgICAgICAgICB2YXIgZGljdEhhc0lkID0gZGljdC5Db250YWluc0tleSgiaWQiKTsKICAgICAgICAgICAgdmFyIGRpY3RIYXNOYW1lID0gZGljdC5Db250YWluc0tleSgibmFtZSIpOwogICAgICAgICAgICB2YXIgZGljdEhhc1RlbXAgPSBkaWN0LkNvbnRhaW5zS2V5KCJ0ZW1wRmllbGQiKTsKICAgICAgICAgICAgdmFyIGRpY3RIYXNLZWVwID0gZGljdC5Db250YWluc0tleSgia2VlcEZpZWxkIik7CgogICAgICAgICAgICAvLyBUZXN0IFRvRGljdGlvbmFyeSgpIHdpdGggbnVsbCDihpIgZW1wdHkgZGljdGlvbmFyeQogICAgICAgICAgICB2YXIgZW1wdHlEaWN0ID0gVG9EaWN0aW9uYXJ5KG51bGwpOwoKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIlJlbW92ZVByb3BlcnR5OiByZW1vdmVkPXswfSwgZGljdENvdW50PXsxfSIsIGFyZ3M6IG5ldyBvYmplY3RbXSB7IHJlbW92ZVJlc3VsdCwgZGljdC5Db3VudCB9KTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJyZW1vdmUtdG8tZGljdC1zdWNjZXNzIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZW1vdmVUb0RpY3RSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBoYWRUZW1wRmllbGRCZWZvcmUgPSBoYWRUZW1wRmllbGQsCiAgICAgICAgICAgICAgICAgICAgICAgIGhhZEtlZXBGaWVsZEJlZm9yZSA9IGhhZEtlZXBGaWVsZCwKICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlUHJvcGVydHlSZXN1bHQgPSByZW1vdmVSZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgIGhhc1RlbXBGaWVsZEFmdGVyUmVtb3ZlID0gaGFzVGVtcEZpZWxkQWZ0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIGhhc0tlZXBGaWVsZEFmdGVyUmVtb3ZlID0gaGFzS2VlcEZpZWxkQWZ0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZU5vbkV4aXN0ZW50UmV0dXJuc0ZhbHNlID0gIXJlbW92ZU5vbkV4aXN0ZW50LAogICAgICAgICAgICAgICAgICAgICAgICBkaWN0Q291bnQgPSBkaWN0LkNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICBkaWN0SGFzSWQgPSBkaWN0SGFzSWQsCiAgICAgICAgICAgICAgICAgICAgICAgIGRpY3RIYXNOYW1lID0gZGljdEhhc05hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGRpY3RSZW1vdmVkVGVtcEZpZWxkID0gIWRpY3RIYXNUZW1wLAogICAgICAgICAgICAgICAgICAgICAgICBkaWN0S2VwdEtlZXBGaWVsZCA9IGRpY3RIYXNLZWVwLAogICAgICAgICAgICAgICAgICAgICAgICBudWxsVG9EaWN0UmV0dXJuc0VtcHR5ID0gZW1wdHlEaWN0LkNvdW50ID09IDAsCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZVByb3BlcnR5V29ya2VkID0gcmVtb3ZlUmVzdWx0ICYmICFoYXNUZW1wRmllbGRBZnRlciAmJiBoYXNLZWVwRmllbGRBZnRlciwKICAgICAgICAgICAgICAgICAgICAgICAgdG9EaWN0aW9uYXJ5V29ya2VkID0gZGljdEhhc0lkICYmIGRpY3RIYXNOYW1lICYmICFkaWN0SGFzVGVtcCAmJiBkaWN0SGFzS2VlcAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiY29sbGVjdGlvbi1vYmplY3QtdGVzdCIsICJyZW1vdmUtcHJvcGVydHkiLCAidG8tZGljdGlvbmFyeSIsICJoYXMtcHJvcGVydHkiLCAic3VjY2VzcyIgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0Vycm9yKCJSZW1vdmVQcm9wZXJ0eS9Ub0RpY3Rpb25hcnkgVGVzdCAtIEZhaWxlZDogezB9IiwgYXJnczogbmV3IG9iamVjdFtdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInJlbW92ZS10by1kaWN0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9Cn0K" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "remove-prop-to-dict-completed", + "target": "test-completed-state", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "RemoveProperty / ToDictionary Completed" + }, + { + "language": "tr-TR", + "label": "RemoveProperty / ToDictionary Tamamlandı" + } + ], + "schema": null, + "rule": { + "location": "./src/AlwaysTrueRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "test-completed-state", + "stateType": 3, + "subType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "All Tests Completed" + }, + { + "language": "tr-TR", + "label": "Tüm Testler Tamamlandı" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + } + ] + } +} \ No newline at end of file diff --git a/core/Workflows/collection-object-test/src/AlwaysTrueRule.csx b/core/Workflows/collection-object-test/src/AlwaysTrueRule.csx new file mode 100644 index 0000000..28bac4f --- /dev/null +++ b/core/Workflows/collection-object-test/src/AlwaysTrueRule.csx @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +public class AlwaysTrueRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + return true; + } +} diff --git a/core/Workflows/collection-object-test/src/CreateAndSetMapping.csx b/core/Workflows/collection-object-test/src/CreateAndSetMapping.csx new file mode 100644 index 0000000..9fa0e85 --- /dev/null +++ b/core/Workflows/collection-object-test/src/CreateAndSetMapping.csx @@ -0,0 +1,85 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Tests: CreateObject(), CreateList(), SetProperty(), ListAdd() +/// Creates a list of 3 dynamic person objects and stores them in Instance.Data. +/// +public class CreateAndSetMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + try + { + LogInformation("CreateAndSet Test - Starting"); + + // Test CreateObject() + SetProperty() + dynamic item1 = CreateObject(); + SetProperty(item1, "id", "item-001"); + SetProperty(item1, "name", "Alice"); + SetProperty(item1, "age", 30); + SetProperty(item1, "status", "active"); + + dynamic item2 = CreateObject(); + SetProperty(item2, "id", "item-002"); + SetProperty(item2, "name", "Bob"); + SetProperty(item2, "age", 25); + SetProperty(item2, "status", "inactive"); + + dynamic item3 = CreateObject(); + SetProperty(item3, "id", "item-003"); + SetProperty(item3, "name", "Charlie"); + SetProperty(item3, "age", 35); + SetProperty(item3, "status", "active"); + + // Test CreateList() + ListAdd() + var items = CreateList(); + ListAdd(items, item1); + ListAdd(items, item2); + ListAdd(items, item3); + + // Nested dynamic object for metadata + dynamic metadata = CreateObject(); + SetProperty(metadata, "createdAt", DateTime.UtcNow.ToString("O")); + SetProperty(metadata, "source", "collection-object-test"); + SetProperty(metadata, "itemCount", items.Count); + + LogInformation("CreateAndSet Test - Created {0} items", args: new object[] { items.Count }); + + return Task.FromResult(new ScriptResponse + { + Key = "create-and-set-success", + Data = new + { + items = items, + metadata = metadata, + createAndSetResult = new + { + success = true, + objectsCreated = 3, + listItemCount = items.Count, + propertiesSet = true + } + }, + Tags = new[] { "collection-object-test", "create-and-set", "success" } + }); + } + catch (Exception ex) + { + LogError("CreateAndSet Test - Failed: {0}", args: new object[] { ex.Message }); + return Task.FromResult(new ScriptResponse + { + Key = "create-and-set-error", + Data = new { error = ex.Message } + }); + } + } +} diff --git a/core/Workflows/collection-object-test/src/GetListAndAsListMapping.csx b/core/Workflows/collection-object-test/src/GetListAndAsListMapping.csx new file mode 100644 index 0000000..44d2a89 --- /dev/null +++ b/core/Workflows/collection-object-test/src/GetListAndAsListMapping.csx @@ -0,0 +1,68 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Tests: GetList(), AsList() +/// Retrieves the items list from Instance.Data and verifies AsList() edge cases. +/// +public class GetListAndAsListMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + try + { + LogInformation("GetList and AsList Test - Starting"); + + var instanceData = context.Instance?.Data; + + // Test GetList() - retrieve items from instance data by property name + var items = GetList(instanceData, "items"); + + // Test AsList() with a valid list - should return same items + var asListFromValid = AsList(items); + + // Test AsList() with null - should return empty list (graceful degradation) + var asListFromNull = AsList(null); + + // Test AsList() with a non-list value - should return empty list + var asListFromString = AsList("not a list"); + + LogInformation("GetList Test - Retrieved {0} items", args: new object[] { items.Count }); + + return Task.FromResult(new ScriptResponse + { + Key = "get-list-success", + Data = new + { + getListResult = new + { + success = true, + itemCount = items.Count, + getListWorked = items.Count == 3, + asListFromValidCount = asListFromValid.Count, + asListNullReturnsEmpty = asListFromNull.Count == 0, + asListInvalidReturnsEmpty = asListFromString.Count == 0 + } + }, + Tags = new[] { "collection-object-test", "get-list", "as-list", "success" } + }); + } + catch (Exception ex) + { + LogError("GetList Test - Failed: {0}", args: new object[] { ex.Message }); + return Task.FromResult(new ScriptResponse + { + Key = "get-list-error", + Data = new { error = ex.Message } + }); + } + } +} diff --git a/core/Workflows/collection-object-test/src/InitCollectionTestMapping.csx b/core/Workflows/collection-object-test/src/InitCollectionTestMapping.csx new file mode 100644 index 0000000..9221910 --- /dev/null +++ b/core/Workflows/collection-object-test/src/InitCollectionTestMapping.csx @@ -0,0 +1,32 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Initial transition mapping - Initializes the collection/object test workflow +/// +public class InitCollectionTestMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + LogInformation("CollectionObjectTest - Workflow initialized"); + + return Task.FromResult(new ScriptResponse + { + Key = "init-success", + Data = new + { + testId = Guid.NewGuid().ToString(), + startedAt = DateTime.UtcNow + }, + Tags = new[] { "collection-object-test", "initialized" } + }); + } +} diff --git a/core/Workflows/collection-object-test/src/ListAddRemoveMapping.csx b/core/Workflows/collection-object-test/src/ListAddRemoveMapping.csx new file mode 100644 index 0000000..2134b40 --- /dev/null +++ b/core/Workflows/collection-object-test/src/ListAddRemoveMapping.csx @@ -0,0 +1,83 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Tests: ListAdd(), ListRemove() +/// Starts with Alice(active), Bob(inactive), Charlie(active). +/// Adds Diana(active) → removes all inactive (Bob) → ends with Alice, Charlie, Diana. +/// +public class ListAddRemoveMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + try + { + LogInformation("ListAdd and ListRemove Test - Starting"); + + object? instanceData = context.Instance?.Data; + var items = GetList(instanceData, "items"); + + var countBefore = ListCount(items); + + // Test ListAdd() - add a new item + dynamic newItem = CreateObject(); + SetProperty(newItem, "id", "item-004"); + SetProperty(newItem, "name", "Diana"); + SetProperty(newItem, "age", 28); + SetProperty(newItem, "status", "active"); + + ListAdd(items, newItem); + + var countAfterAdd = ListCount(items); + + // Test ListRemove() - remove all inactive items (Bob) + var removedCount = ListRemove(items, x => x.status == "inactive"); + + var countAfterRemove = ListCount(items); + + // Verify no inactive items remain + var hasInactiveAfterRemove = ListAny(items, x => x.status == "inactive"); + + LogInformation("Add/Remove: before={0}, afterAdd={1}, removed={2}, afterRemove={3}", + args: new object[] { countBefore, countAfterAdd, removedCount, countAfterRemove }); + + return Task.FromResult(new ScriptResponse + { + Key = "add-remove-success", + Data = new + { + items = items, + listAddRemoveResult = new + { + success = true, + countBefore = countBefore, + countAfterAdd = countAfterAdd, + removedCount = removedCount, + countAfterRemove = countAfterRemove, + hasInactiveAfterRemove = hasInactiveAfterRemove, + addWorked = countAfterAdd == countBefore + 1, + removeWorked = removedCount == 1 && !hasInactiveAfterRemove + } + }, + Tags = new[] { "collection-object-test", "list-add", "list-remove", "success" } + }); + } + catch (Exception ex) + { + LogError("ListAdd/Remove Test - Failed: {0}", args: new object[] { ex.Message }); + return Task.FromResult(new ScriptResponse + { + Key = "add-remove-error", + Data = new { error = ex.Message } + }); + } + } +} diff --git a/core/Workflows/collection-object-test/src/ListFilterCountAnyMapping.csx b/core/Workflows/collection-object-test/src/ListFilterCountAnyMapping.csx new file mode 100644 index 0000000..5751a27 --- /dev/null +++ b/core/Workflows/collection-object-test/src/ListFilterCountAnyMapping.csx @@ -0,0 +1,87 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Tests: ListFilter(), ListCount(), ListAny() +/// Uses the items list (Alice=active, Bob=inactive, Charlie=active) from Instance.Data. +/// +public class ListFilterCountAnyMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + try + { + LogInformation("ListFilter, ListCount, ListAny Test - Starting"); + + object instanceData = context.Instance?.Data; + var items = GetList(instanceData, "items"); + + // Test ListFilter() - filter active items (Alice + Charlie) + var activeItems = ListFilter(items, x => x.status == "active"); + + // Test ListCount() - no predicate (total) + var totalCount = ListCount(items); + + // Test ListCount() with predicate + var activeCount = ListCount(items, x => x.status == "active"); + var inactiveCount = ListCount(items, x => x.status == "inactive"); + + // Test ListAny() - no predicate (has any element) + var hasItems = ListAny(items); + + // Test ListAny() with predicate + var hasActive = ListAny(items, x => x.status == "active"); + var hasAdminRole = ListAny(items, x => x.status == "admin"); + + // Empty list checks + var emptyList = CreateList(); + var emptyHasItems = ListAny(emptyList); + var emptyCount = ListCount(emptyList); + + LogInformation("ListFilter: active={0}, inactive={1}, total={2}", + args: new object[] { activeCount, inactiveCount, totalCount }); + + return Task.FromResult(new ScriptResponse + { + Key = "filter-count-any-success", + Data = new + { + filterCountAnyResult = new + { + success = true, + totalCount = totalCount, + activeCount = activeCount, + inactiveCount = inactiveCount, + activeItemsFiltered = activeItems.Count, + hasItems = hasItems, + hasActive = hasActive, + hasAdminRole = hasAdminRole, + emptyListHasItems = emptyHasItems, + emptyListCount = emptyCount, + filterWorked = activeItems.Count == 2, + countWorked = totalCount == 3 && activeCount == 2 && inactiveCount == 1, + anyWorked = hasItems && hasActive && !hasAdminRole && !emptyHasItems + } + }, + Tags = new[] { "collection-object-test", "list-filter", "list-count", "list-any", "success" } + }); + } + catch (Exception ex) + { + LogError("ListFilter/Count/Any Test - Failed: {0}", args: new object[] { ex.Message }); + return Task.FromResult(new ScriptResponse + { + Key = "filter-count-any-error", + Data = new { error = ex.Message } + }); + } + } +} diff --git a/core/Workflows/collection-object-test/src/ListFirstLastMapping.csx b/core/Workflows/collection-object-test/src/ListFirstLastMapping.csx new file mode 100644 index 0000000..2add005 --- /dev/null +++ b/core/Workflows/collection-object-test/src/ListFirstLastMapping.csx @@ -0,0 +1,84 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Tests: ListFirst(), ListLast() +/// Items order: Alice(active), Bob(inactive), Charlie(active) +/// +public class ListFirstLastMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + try + { + LogInformation("ListFirst and ListLast Test - Starting"); + + object instanceData = context.Instance?.Data; + var items = GetList(instanceData, "items"); + + // Test ListFirst() without predicate → Alice + var first = ListFirst(items); + + // Test ListFirst() with predicate → first active = Alice, first inactive = Bob + var firstActive = ListFirst(items, x => x.status == "active"); + var firstInactive = ListFirst(items, x => x.status == "inactive"); + + // Test ListFirst() with no match → null + var firstNotFound = ListFirst(items, x => x.status == "admin"); + + // Test ListLast() without predicate → Charlie + var last = ListLast(items); + + // Test ListLast() with predicate → last active = Charlie + var lastActive = ListLast(items, x => x.status == "active"); + + // Test on empty list → null + var emptyFirst = ListFirst(CreateList()); + var emptyLast = ListLast(CreateList()); + + LogInformation("First: {0}, Last: {1}", args: new object[] { first?.name, last?.name }); + + return Task.FromResult(new ScriptResponse + { + Key = "first-last-success", + Data = new + { + firstLastResult = new + { + success = true, + firstName = (string)(first?.name ?? "null"), + lastName = (string)(last?.name ?? "null"), + firstActiveName = (string)(firstActive?.name ?? "null"), + firstInactiveName = (string)(firstInactive?.name ?? "null"), + lastActiveName = (string)(lastActive?.name ?? "null"), + firstNotFoundIsNull = firstNotFound == null, + emptyFirstIsNull = emptyFirst == null, + emptyLastIsNull = emptyLast == null, + firstWorked = first?.id == "item-001", + lastWorked = last?.id == "item-003", + firstWithPredicateWorked = firstActive?.id == "item-001", + lastWithPredicateWorked = lastActive?.id == "item-003" + } + }, + Tags = new[] { "collection-object-test", "list-first", "list-last", "success" } + }); + } + catch (Exception ex) + { + LogError("ListFirst/Last Test - Failed: {0}", args: new object[] { ex.Message }); + return Task.FromResult(new ScriptResponse + { + Key = "first-last-error", + Data = new { error = ex.Message } + }); + } + } +} diff --git a/core/Workflows/collection-object-test/src/ListSelectMapping.csx b/core/Workflows/collection-object-test/src/ListSelectMapping.csx new file mode 100644 index 0000000..7dfca71 --- /dev/null +++ b/core/Workflows/collection-object-test/src/ListSelectMapping.csx @@ -0,0 +1,74 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Tests: ListSelect<TResult>() +/// Projects list items into different types: string, int, object +/// +public class ListSelectMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + try + { + LogInformation("ListSelect Test - Starting"); + + object instanceData = context.Instance?.Data; + var items = GetList(instanceData, "items"); + + // Test ListSelect() - extract names + var names = ListSelect(items, x => (string)x.name); + + // Test ListSelect() - extract ages + var ages = ListSelect(items, x => (int)x.age); + + // Test ListSelect() with transformation + var labels = ListSelect(items, x => $"{x.name} ({x.status})"); + + // Test ListSelect on empty list - should return empty list + var emptyResult = ListSelect(CreateList(), x => (string)x.name); + + LogInformation("ListSelect: {0} names, {1} ages", args: new object[] { names.Count, ages.Count }); + + return Task.FromResult(new ScriptResponse + { + Key = "list-select-success", + Data = new + { + listSelectResult = new + { + success = true, + names = names, + ages = ages, + labels = labels, + namesCount = names.Count, + agesCount = ages.Count, + emptySelectCount = emptyResult.Count, + selectStringWorked = names.Count == 3 && names[0] == "Alice", + selectIntWorked = ages.Count == 3 && ages[0] == 30, + selectTransformWorked = labels.Count == 3, + emptySelectWorked = emptyResult.Count == 0 + } + }, + Tags = new[] { "collection-object-test", "list-select", "success" } + }); + } + catch (Exception ex) + { + LogError("ListSelect Test - Failed: {0}", args: new object[] { ex.Message }); + return Task.FromResult(new ScriptResponse + { + Key = "list-select-error", + Data = new { error = ex.Message } + }); + } + } +} diff --git a/core/Workflows/collection-object-test/src/RemovePropertyToDictionaryMapping.csx b/core/Workflows/collection-object-test/src/RemovePropertyToDictionaryMapping.csx new file mode 100644 index 0000000..68bec03 --- /dev/null +++ b/core/Workflows/collection-object-test/src/RemovePropertyToDictionaryMapping.csx @@ -0,0 +1,94 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Tests: RemoveProperty(), ToDictionary(), HasProperty() +/// Creates a dynamic object, removes a property, converts to dictionary. +/// +public class RemovePropertyToDictionaryMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + try + { + LogInformation("RemoveProperty and ToDictionary Test - Starting"); + + // Create a test object with multiple properties + dynamic testObj = CreateObject(); + SetProperty(testObj, "id", "test-001"); + SetProperty(testObj, "name", "Test Object"); + SetProperty(testObj, "tempField", "this will be removed"); + SetProperty(testObj, "keepField", "this stays"); + + // Verify property exists before removal (uses HasProperty from ScriptBase) + var hadTempField = HasProperty(testObj, "tempField"); + var hadKeepField = HasProperty(testObj, "keepField"); + + // Test RemoveProperty() + var removeResult = RemoveProperty(testObj, "tempField"); + + // Verify property is gone + var hasTempFieldAfter = HasProperty(testObj, "tempField"); + var hasKeepFieldAfter = HasProperty(testObj, "keepField"); + + // Test RemoveProperty() on non-existent property → false + var removeNonExistent = RemoveProperty(testObj, "doesNotExist"); + + // Test ToDictionary() + var dict = ToDictionary(testObj); + var dictHasId = dict.ContainsKey("id"); + var dictHasName = dict.ContainsKey("name"); + var dictHasTemp = dict.ContainsKey("tempField"); + var dictHasKeep = dict.ContainsKey("keepField"); + + // Test ToDictionary() with null → empty dictionary + var emptyDict = ToDictionary(null); + + LogInformation("RemoveProperty: removed={0}, dictCount={1}", args: new object[] { removeResult, dict.Count }); + + return Task.FromResult(new ScriptResponse + { + Key = "remove-to-dict-success", + Data = new + { + removeToDictResult = new + { + success = true, + hadTempFieldBefore = hadTempField, + hadKeepFieldBefore = hadKeepField, + removePropertyResult = removeResult, + hasTempFieldAfterRemove = hasTempFieldAfter, + hasKeepFieldAfterRemove = hasKeepFieldAfter, + removeNonExistentReturnsFalse = !removeNonExistent, + dictCount = dict.Count, + dictHasId = dictHasId, + dictHasName = dictHasName, + dictRemovedTempField = !dictHasTemp, + dictKeptKeepField = dictHasKeep, + nullToDictReturnsEmpty = emptyDict.Count == 0, + removePropertyWorked = removeResult && !hasTempFieldAfter && hasKeepFieldAfter, + toDictionaryWorked = dictHasId && dictHasName && !dictHasTemp && dictHasKeep + } + }, + Tags = new[] { "collection-object-test", "remove-property", "to-dictionary", "has-property", "success" } + }); + } + catch (Exception ex) + { + LogError("RemoveProperty/ToDictionary Test - Failed: {0}", args: new object[] { ex.Message }); + return Task.FromResult(new ScriptResponse + { + Key = "remove-to-dict-error", + Data = new { error = ex.Message } + }); + } + } +} diff --git a/core/Workflows/discovery/domain-health-check-workflow.json b/core/Workflows/discovery/domain-health-check-workflow.json new file mode 100644 index 0000000..11db359 --- /dev/null +++ b/core/Workflows/discovery/domain-health-check-workflow.json @@ -0,0 +1,569 @@ +{ + "key": "domain-health-check", + "flow": "sys-flows", + "flowVersion": "1.0.0", + "domain": "core", + "version": "1.0.0", + "tags": [ + "domain", + "health-check", + "api", + "monitoring", + "scheduled", + "pagination" + ], + "attributes": { + "type": "F", + "timeout": null, + "labels": [ + { + "language": "en-US", + "label": "Domain Health Check Workflow" + }, + { + "language": "tr-TR", + "label": "Domain Sağlık Kontrolü İş Akışı" + } + ], + "functions": [], + "features": [], + "extensions": [], + "sharedTransitions": [], + "startTransition": { + "key": "start-health-check", + "target": "initial", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Start Health Check" + }, + { + "language": "tr-TR", + "label": "Sağlık Kontrolünü Başlat" + } + ], + "onExecutionTasks": [] + }, + "states": [ + { + "key": "initial", + "stateType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Initial" + }, + { + "language": "tr-TR", + "label": "Başlangıç" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "to-fetch-domains", + "target": "fetch-domains", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Fetch Domains" + }, + { + "language": "tr-TR", + "label": "Otomatik - Domainleri Getir" + } + ], + "schema": null, + "rule": { + "location": "./src/InitialTransitionRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEluaXRpYWwgVHJhbnNpdGlvbiBSdWxlIC0gQWx3YXlzIGFsbG93cyB0cmFuc2l0aW9uIGZyb20gaW5pdGlhbCBzdGF0ZQovLy8gVGhpcyBydWxlIGFsd2F5cyByZXR1cm5zIHRydWUgdG8gYWxsb3cgYXV0b21hdGljIHRyYW5zaXRpb24gZnJvbSBpbml0aWFsIHN0YXRlCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBJbml0aWFsVHJhbnNpdGlvblJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIEFsd2F5cyBhbGxvdyB0cmFuc2l0aW9uIGZyb20gaW5pdGlhbCBzdGF0ZQogICAgICAgICAgICAvLyBJbml0aWFsIHN0YXRlIGlzIHRoZSBlbnRyeSBwb2ludCwgc28gdHJhbnNpdGlvbiBzaG91bGQgYWx3YXlzIHByb2NlZWQKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICAvLyBPbiBlcnJvciwgc3RpbGwgYWxsb3cgdHJhbnNpdGlvbiB0byBwcmV2ZW50IHdvcmtmbG93IGZyb20gZ2V0dGluZyBzdHVjawogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9Cn0KCg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "fetch-domains", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Fetch Domains" + }, + { + "language": "tr-TR", + "label": "Domainleri Getir" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "domains-fetched", + "target": "process-page", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Domains Fetched" + }, + { + "language": "tr-TR", + "label": "Otomatik - Domainler Getirildi" + } + ], + "schema": null, + "rule": { + "location": "./src/DomainsFetchedRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIERvbWFpbnMgRmV0Y2hlZCBSdWxlIC0gQ2hlY2tzIGlmIGRvbWFpbnMgd2VyZSBzdWNjZXNzZnVsbHkgZmV0Y2hlZAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRG9tYWluc0ZldGNoZWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICAvLyBBbHdheXMgcmV0dXJuIHRydWUgLSBtYXBwaW5nIGhhbmRsZXMgdGhlIGxvZ2ljIHZpYSBLZXkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + }, + { + "key": "fetch-failed", + "target": "schedule-next-run", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Fetch Failed" + }, + { + "language": "tr-TR", + "label": "Otomatik - Getirme Başarısız" + } + ], + "schema": null, + "rule": { + "location": "./src/FetchFailedRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEZldGNoIEZhaWxlZCBSdWxlIC0gQ2hlY2tzIGlmIGZldGNoIGZhaWxlZAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRmV0Y2hGYWlsZWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICAvLyBBbHdheXMgcmV0dXJuIHRydWUgLSBtYXBwaW5nIGhhbmRsZXMgdGhlIGxvZ2ljIHZpYSBLZXkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "process-page", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Process Page" + }, + { + "language": "tr-TR", + "label": "Sayfayı İşle" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "to-check-health", + "target": "check-domain-health", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - To Check Health" + }, + { + "language": "tr-TR", + "label": "Otomatik - Sağlık Kontrolüne" + } + ], + "schema": null, + "rule": { + "location": "./src/ToCheckHealthRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUbyBDaGVjayBIZWFsdGggUnVsZSAtIENoZWNrcyBpZiBzaG91bGQgcHJvY2VlZCB0byBoZWFsdGggY2hlY2sKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFRvQ2hlY2tIZWFsdGhSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBwZW5kaW5nRG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5wZW5kaW5nRG9tYWlucyBhcyBMaXN0PG9iamVjdD47CiAgICAgICAgICAgIHJldHVybiBwZW5kaW5nRG9tYWlucyAhPSBudWxsICYmIHBlbmRpbmdEb21haW5zLkNvdW50ID4gMDsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + }, + { + "key": "no-domains", + "target": "check-pagination", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - No Domains" + }, + { + "language": "tr-TR", + "label": "Otomatik - Domain Yok" + } + ], + "schema": null, + "rule": { + "location": "./src/NoDomainsRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBObyBEb21haW5zIFJ1bGUgLSBDaGVja3MgaWYgbm8gZG9tYWlucyB0byBwcm9jZXNzCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBOb0RvbWFpbnNSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgdmFyIHBlbmRpbmdEb21haW5zID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLnBlbmRpbmdEb21haW5zIGFzIExpc3Q8b2JqZWN0PjsKICAgICAgICAgICAgcmV0dXJuIHBlbmRpbmdEb21haW5zID09IG51bGwgfHwgcGVuZGluZ0RvbWFpbnMuQ291bnQgPT0gMDsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0KfQoK" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "check-domain-health", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Check Domain Health" + }, + { + "language": "tr-TR", + "label": "Domain Sağlığını Kontrol Et" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "check-health-endpoint", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/CheckDomainHealthMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIFN5c3RlbS5MaW5xOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CgovLy8gPHN1bW1hcnk+Ci8vLyBDaGVjayBEb21haW4gSGVhbHRoIE1hcHBpbmcgLSBDaGVja3MgaGVhbHRoIGZvciBvbmUgZG9tYWluIGF0IGEgdGltZSAoc2VxdWVudGlhbCBwcm9jZXNzaW5nKQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgQ2hlY2tEb21haW5IZWFsdGhNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gR2V0IGN1cnJlbnQgZG9tYWluIGZyb20gcGVuZGluZ0RvbWFpbnMgYXJyYXkgdXNpbmcgY3VycmVudERvbWFpbkluZGV4CiAgICAgICAgICAgIHZhciBwZW5kaW5nRG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnBlbmRpbmdEb21haW5zIGFzIExpc3Q8b2JqZWN0PjsKICAgICAgICAgICAgdmFyIGN1cnJlbnREb21haW5JbmRleCA9IENvbnZlcnQuVG9JbnQzMihjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5jdXJyZW50RG9tYWluSW5kZXggPz8gMCk7CgogICAgICAgICAgICBpZiAocGVuZGluZ0RvbWFpbnMgPT0gbnVsbCB8fCBjdXJyZW50RG9tYWluSW5kZXggPj0gcGVuZGluZ0RvbWFpbnMuQ291bnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInBhZ2UtY29tcGxldGUiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9ICJObyBtb3JlIGRvbWFpbnMgdG8gcHJvY2VzcyIgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEdldCBjdXJyZW50IGRvbWFpbgogICAgICAgICAgICB2YXIgY3VycmVudERvbWFpbiA9IHBlbmRpbmdEb21haW5zW2N1cnJlbnREb21haW5JbmRleF0gYXMgRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD47CiAgICAgICAgICAgIGlmIChjdXJyZW50RG9tYWluID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInBhZ2UtY29tcGxldGUiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9ICJJbnZhbGlkIGRvbWFpbiBkYXRhIiB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGhlYWx0aFVybCA9IGN1cnJlbnREb21haW4uQ29udGFpbnNLZXkoImhlYWx0aFVybCIpID8gY3VycmVudERvbWFpblsiaGVhbHRoVXJsIl0/LlRvU3RyaW5nKCkgOiBudWxsOwoKICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGhlYWx0aFVybCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImhlYWx0aC1jaGVjay1lcnJvciIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gIkhlYWx0aCBVUkwgaXMgbWlzc2luZyIgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFNldCB0aGUgaGVhbHRoIFVSTCBmb3IgdGhlIEhUVFAgcmVxdWVzdAogICAgICAgICAgICBodHRwVGFzay5TZXRVcmwoaGVhbHRoVXJsKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImhlYWx0aC1jaGVjay1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMDsKICAgICAgICAgICAgdmFyIHBlbmRpbmdEb21haW5zID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGVuZGluZ0RvbWFpbnMgYXMgTGlzdDxvYmplY3Q+ID8/IG5ldyBMaXN0PG9iamVjdD4oKTsKICAgICAgICAgICAgdmFyIGN1cnJlbnREb21haW5JbmRleCA9IENvbnZlcnQuVG9JbnQzMihjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5jdXJyZW50RG9tYWluSW5kZXggPz8gMCk7CiAgICAgICAgICAgIHZhciBoZWFsdGh5RG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LkhlYWx0aHlEb21haW5zIGFzIExpc3Q8b2JqZWN0PiA/PyBuZXcgTGlzdDxvYmplY3Q+KCk7CiAgICAgICAgICAgIHZhciBub3RIZWFsdGh5RG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/Lk5vdEhlYWx0aHlEb21haW5zIGFzIExpc3Q8b2JqZWN0PiA/PyBuZXcgTGlzdDxvYmplY3Q+KCk7CgogICAgICAgICAgICAvLyBHZXQgY3VycmVudCBkb21haW4KICAgICAgICAgICAgaWYgKGN1cnJlbnREb21haW5JbmRleCA+PSBwZW5kaW5nRG9tYWlucy5Db3VudCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJwYWdlLWNvbXBsZXRlIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBIZWFsdGh5RG9tYWlucyA9IGhlYWx0aHlEb21haW5zLAogICAgICAgICAgICAgICAgICAgICAgICBOb3RIZWFsdGh5RG9tYWlucyA9IG5vdEhlYWx0aHlEb21haW5zLAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImRvbWFpbiIsICJoZWFsdGgtY2hlY2siLCAiY29tcGxldGUiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBjdXJyZW50RG9tYWluID0gcGVuZGluZ0RvbWFpbnNbY3VycmVudERvbWFpbkluZGV4XSBhcyBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0PjsKICAgICAgICAgICAgdmFyIGRvbWFpbk5hbWUgPSBjdXJyZW50RG9tYWluPy5Db250YWluc0tleSgiZG9tYWluTmFtZSIpID09IHRydWUgPyBjdXJyZW50RG9tYWluWyJkb21haW5OYW1lIl0/LlRvU3RyaW5nKCkgOiBudWxsOwoKICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIGhlYWx0aCBzdGF0dXMgYmFzZWQgb24gSFRUUCBzdGF0dXMgY29kZQogICAgICAgICAgICAvLyAyMDAgPSBoZWFsdGh5LCBvdGhlcndpc2UgdW5oZWFsdGh5CiAgICAgICAgICAgIGJvb2wgaXNIZWFsdGh5ID0gc3RhdHVzQ29kZSA9PSAyMDA7CgogICAgICAgICAgICAvLyBBZGQgdG8gYXBwcm9wcmlhdGUgbGlzdAogICAgICAgICAgICBpZiAoaXNIZWFsdGh5KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWhlYWx0aHlEb21haW5zLkNvbnRhaW5zKGRvbWFpbk5hbWUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGhlYWx0aHlEb21haW5zLkFkZChkb21haW5OYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghbm90SGVhbHRoeURvbWFpbnMuQ29udGFpbnMoZG9tYWluTmFtZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbm90SGVhbHRoeURvbWFpbnMuQWRkKGRvbWFpbk5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBJbmNyZW1lbnQgaW5kZXggZm9yIG5leHQgZG9tYWluCiAgICAgICAgICAgIHZhciBuZXh0SW5kZXggPSBjdXJyZW50RG9tYWluSW5kZXggKyAxOwogICAgICAgICAgICB2YXIgaGFzTW9yZURvbWFpbnMgPSBuZXh0SW5kZXggPCBwZW5kaW5nRG9tYWlucy5Db3VudDsKCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gaGFzTW9yZURvbWFpbnMgPyAiaGFzLW1vcmUtZG9tYWlucyIgOiAicGFnZS1jb21wbGV0ZSIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudERvbWFpbkluZGV4ID0gbmV4dEluZGV4LAogICAgICAgICAgICAgICAgICAgIEhlYWx0aHlEb21haW5zID0gaGVhbHRoeURvbWFpbnMsCiAgICAgICAgICAgICAgICAgICAgTm90SGVhbHRoeURvbWFpbnMgPSBub3RIZWFsdGh5RG9tYWlucywKICAgICAgICAgICAgICAgICAgICBpc0hlYWx0aHkgPSBpc0hlYWx0aHksCiAgICAgICAgICAgICAgICAgICAgZG9tYWluTmFtZSA9IGRvbWFpbk5hbWUsCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImRvbWFpbiIsICJoZWFsdGgtY2hlY2siLCBpc0hlYWx0aHkgPyAiaGVhbHRoeSIgOiAidW5oZWFsdGh5IiwgaGFzTW9yZURvbWFpbnMgPyAiY29udGludWUiIDogImNvbXBsZXRlIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJoZWFsdGgtY2hlY2stZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkV4Y2VwdGlvbiBkdXJpbmcgaGVhbHRoIGNoZWNrIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBjaGVja2VkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImhlYWx0aC1jaGVjayIsICJleGNlcHRpb24iLCAiZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "has-more-domains", + "target": "check-domain-health", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Has More Domains (Loop)" + }, + { + "language": "tr-TR", + "label": "Otomatik - Daha Fazla Domain Var (Döngü)" + } + ], + "schema": null, + "rule": { + "location": "./src/HasMoreDomainsRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBIYXMgTW9yZSBEb21haW5zIFJ1bGUgLSBDaGVja3MgaWYgdGhlcmUgYXJlIG1vcmUgZG9tYWlucyB0byBwcm9jZXNzIGluIGN1cnJlbnQgcGFnZQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgSGFzTW9yZURvbWFpbnNSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBwZW5kaW5nRG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5wZW5kaW5nRG9tYWlucyBhcyBMaXN0PG9iamVjdD47CiAgICAgICAgICAgIHZhciBjdXJyZW50RG9tYWluSW5kZXggPSBDb252ZXJ0LlRvSW50MzIoY29udGV4dC5JbnN0YW5jZS5EYXRhLmN1cnJlbnREb21haW5JbmRleCA/PyAwKTsKCiAgICAgICAgICAgIGlmIChwZW5kaW5nRG9tYWlucyA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIG1vcmUgZG9tYWlucyB0byBwcm9jZXNzCiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RG9tYWluSW5kZXggPCBwZW5kaW5nRG9tYWlucy5Db3VudDsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + }, + { + "key": "page-complete", + "target": "aggregate-results", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Page Complete" + }, + { + "language": "tr-TR", + "label": "Otomatik - Sayfa Tamamlandı" + } + ], + "schema": null, + "rule": { + "location": "./src/PageCompleteRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBQYWdlIENvbXBsZXRlIFJ1bGUgLSBDaGVja3MgaWYgY3VycmVudCBwYWdlIHByb2Nlc3NpbmcgaXMgY29tcGxldGUKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFBhZ2VDb21wbGV0ZVJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb250ZXh0Py5JbnN0YW5jZT8uRGF0YSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgdmFyIHBlbmRpbmdEb21haW5zID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLnBlbmRpbmdEb21haW5zIGFzIExpc3Q8b2JqZWN0PjsKICAgICAgICAgICAgdmFyIGN1cnJlbnREb21haW5JbmRleCA9IENvbnZlcnQuVG9JbnQzMihjb250ZXh0Lkluc3RhbmNlLkRhdGEuY3VycmVudERvbWFpbkluZGV4ID8/IDApOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKHBlbmRpbmdEb21haW5zID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RG9tYWluSW5kZXggPj0gcGVuZGluZ0RvbWFpbnMuQ291bnQ7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "aggregate-results", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Aggregate Results" + }, + { + "language": "tr-TR", + "label": "Sonuçları Topla" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "to-check-pagination", + "target": "check-pagination", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - To Check Pagination" + }, + { + "language": "tr-TR", + "label": "Otomatik - Sayfalama Kontrolüne" + } + ], + "schema": null, + "rule": { + "location": "./src/ToCheckPaginationRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFRvIENoZWNrIFBhZ2luYXRpb24gUnVsZSAtIEFsd2F5cyBhbGxvd3MgdHJhbnNpdGlvbiB0byBwYWdpbmF0aW9uIGNoZWNrCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBUb0NoZWNrUGFnaW5hdGlvblJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KfQoK" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "check-pagination", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Check Pagination" + }, + { + "language": "tr-TR", + "label": "Sayfalamayı Kontrol Et" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "has-next", + "target": "fetch-next-page", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Has Next Page" + }, + { + "language": "tr-TR", + "label": "Otomatik - Sonraki Sayfa Var" + } + ], + "schema": null, + "rule": { + "location": "./src/CheckPaginationRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIENoZWNrIFBhZ2luYXRpb24gUnVsZSAtIENoZWNrcyBpZiBuZXh0IGxpbmsgZXhpc3RzIGluIHJlc3BvbnNlCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBDaGVja1BhZ2luYXRpb25SdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBuZXh0UGFnZVVybCA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5uZXh0UGFnZVVybD8uVG9TdHJpbmcoKTsKCiAgICAgICAgICAgIC8vIFJldHVybiB0cnVlIGlmIG5leHQgbGluayBpcyBub3QgbnVsbC9lbXB0eQogICAgICAgICAgICByZXR1cm4gIXN0cmluZy5Jc051bGxPckVtcHR5KG5leHRQYWdlVXJsKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + }, + { + "key": "no-next", + "target": "schedule-next-run", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - No Next Page" + }, + { + "language": "tr-TR", + "label": "Otomatik - Sonraki Sayfa Yok" + } + ], + "schema": null, + "rule": { + "location": "./src/NoNextRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIE5vIE5leHQgUnVsZSAtIENoZWNrcyBpZiB0aGVyZSBpcyBubyBuZXh0IHBhZ2UgKG9wcG9zaXRlIG9mIENoZWNrUGFnaW5hdGlvblJ1bGUpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBOb05leHRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgdmFyIG5leHRQYWdlVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLm5leHRQYWdlVXJsPy5Ub1N0cmluZygpOwogICAgICAgICAgICByZXR1cm4gc3RyaW5nLklzTnVsbE9yRW1wdHkobmV4dFBhZ2VVcmwpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQp9Cgo=" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "fetch-next-page", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Fetch Next Page" + }, + { + "language": "tr-TR", + "label": "Sonraki Sayfayı Getir" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "fetch-domains-list", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/FetchNextPageMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gRmV0Y2ggTmV4dCBQYWdlIE1hcHBpbmcgLSBGZXRjaGVzIG5leHQgcGFnZSB1c2luZyBuZXh0IFVSTCBmcm9tIHJlc3BvbnNlCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBGZXRjaE5leHRQYWdlTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGFuIEh0dHBUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEdldCBuZXh0IHBhZ2UgVVJMIGZyb20gY29udGV4dAogICAgICAgICAgICB2YXIgbmV4dFBhZ2VVcmwgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5uZXh0UGFnZVVybD8uVG9TdHJpbmcoKTsKCiAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShuZXh0UGFnZVVybCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gIm5vLW5leHQtcGFnZSIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gIk5leHQgcGFnZSBVUkwgaXMgbWlzc2luZyIgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFNldCB0aGUgbmV4dCBwYWdlIFVSTCBmb3IgdGhlIEhUVFAgcmVxdWVzdAogICAgICAgICAgICBodHRwVGFzay5TZXRVcmwobmV4dFBhZ2VVcmwpOwoKICAgICAgICAgICAgLy8gVXBkYXRlIGN1cnJlbnRQYWdlVXJsCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImZldGNoLW5leHQtcGFnZS1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMDsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgICAgIC8vIFN1Y2Nlc3NmdWwgcmVzcG9uc2UgKDIwMCBPSykKICAgICAgICAgICAgaWYgKHN0YXR1c0NvZGUgPj0gMjAwICYmIHN0YXR1c0NvZGUgPCAzMDAgJiYgcmVzcG9uc2VEYXRhICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgaXRlbXMgYW5kIGxpbmtzIGZyb20gcmVzcG9uc2UKICAgICAgICAgICAgICAgIHZhciBpdGVtcyA9IHJlc3BvbnNlRGF0YS5pdGVtczsKICAgICAgICAgICAgICAgIHZhciBsaW5rcyA9IHJlc3BvbnNlRGF0YS5saW5rczsKICAgICAgICAgICAgICAgIHZhciBuZXh0VXJsID0gbGlua3M/Lm5leHQ/LlRvU3RyaW5nKCk7CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJuZXh0LXBhZ2UtZmV0Y2hlZCIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgPSBpdGVtcywKICAgICAgICAgICAgICAgICAgICAgICAgbGlua3MgPSBsaW5rcywKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFBhZ2VVcmwgPSBuZXh0VXJsLAogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50UGFnZVVybCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/Lm5leHRQYWdlVXJsLAogICAgICAgICAgICAgICAgICAgICAgICBmZXRjaGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJkb21haW4iLCAiZmV0Y2giLCAicGFnaW5hdGlvbiIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEVycm9yIHJlc3BvbnNlCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJmZXRjaC1uZXh0LXBhZ2UtZmFpbGVkIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJGYWlsZWQgdG8gZmV0Y2ggbmV4dCBwYWdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlRGF0YSA9IHJlc3BvbnNlRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgZmV0Y2hlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImZldGNoIiwgInBhZ2luYXRpb24iLCAiZXJyb3IiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImZldGNoLW5leHQtcGFnZS1mYWlsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkV4Y2VwdGlvbiBkdXJpbmcgbmV4dCBwYWdlIGZldGNoIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBmZXRjaGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImZldGNoIiwgInBhZ2luYXRpb24iLCAiZXhjZXB0aW9uIiwgImVycm9yIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "next-page-fetched", + "target": "process-page", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Next Page Fetched" + }, + { + "language": "tr-TR", + "label": "Otomatik - Sonraki Sayfa Getirildi" + } + ], + "schema": null, + "rule": { + "location": "./src/NextPageFetchedRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIE5leHQgUGFnZSBGZXRjaGVkIFJ1bGUgLSBDaGVja3MgaWYgbmV4dCBwYWdlIHdhcyBzdWNjZXNzZnVsbHkgZmV0Y2hlZAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgTmV4dFBhZ2VGZXRjaGVkUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gQWx3YXlzIHJldHVybiB0cnVlIC0gbWFwcGluZyBoYW5kbGVzIHRoZSBsb2dpYyB2aWEgS2V5CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KfQoK" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "schedule-next-run", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Schedule Next Run" + }, + { + "language": "tr-TR", + "label": "Sonraki Çalıştırmayı Planla" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "schedule-health-check", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/ScheduleNextRunMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gU2NoZWR1bGUgTmV4dCBSdW4gTWFwcGluZyAtIFRyaWdnZXJzIGRvbWFpbi1oZWFsdGgtY2hlY2sgd29ya2Zsb3cgYXMgc3VicHJvY2VzcyBmb3IgbmV4dCBleGVjdXRpb24KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFNjaGVkdWxlTmV4dFJ1bk1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgc3ViUHJvY2Vzc1Rhc2sgPSB0YXNrIGFzIFN1YlByb2Nlc3NUYXNrOwogICAgICAgICAgICBpZiAoc3ViUHJvY2Vzc1Rhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIFN1YlByb2Nlc3NUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBzdWJwcm9jZXNzIHRvIHRyaWdnZXIgdGhlIHNhbWUgd29ya2Zsb3cKICAgICAgICAgICAgc3ViUHJvY2Vzc1Rhc2suU2V0S2V5KCJkb21haW4taGVhbHRoLWNoZWNrIik7CiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldFZlcnNpb24oIjEuMC4wIik7CgogICAgICAgICAgICAvLyBQcmVwYXJlIHN1YnByb2Nlc3MgaW5pdGlhbGl6YXRpb24gZGF0YSAoZW1wdHkgZm9yIHNjaGVkdWxlZCBydW4pCiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldEJvZHkobmV3IHsgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzY2hlZHVsZS1uZXh0LXJ1bi1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFN1YlByb2Nlc3MgaXMgZmlyZS1hbmQtZm9yZ2V0LCBzbyB3ZSBqdXN0IHJldHVybiBzdWNjZXNzCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInNjaGVkdWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgbmV4dFJ1bkluID0gIjEgaG91ciIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgInNjaGVkdWxlIiwgImhlYWx0aC1jaGVjayIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzY2hlZHVsZS1uZXh0LXJ1bi1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRXhjZXB0aW9uIGR1cmluZyBzY2hlZHVsaW5nIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBzY2hlZHVsZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJkb21haW4iLCAic2NoZWR1bGUiLCAiZXhjZXB0aW9uIiwgImVycm9yIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "scheduled", + "target": "completed", + "triggerType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Scheduled - Next Run" + }, + { + "language": "tr-TR", + "label": "Planlandı - Sonraki Çalıştırma" + } + ], + "schema": null, + "timer": { + "location": "./src/ScheduleNextRunTimerMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zLlRpbWVyOwoKLy8vIDxzdW1tYXJ5PgovLy8gU2NoZWR1bGUgTmV4dCBSdW4gVGltZXIgTWFwcGluZyAtIFJldHVybnMgdGltZXIgc2NoZWR1bGUgZm9yIDEgaG91ciBkZWxheQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgU2NoZWR1bGVOZXh0UnVuVGltZXJNYXBwaW5nIDogSVRpbWVyTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxUaW1lclNjaGVkdWxlPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFJldHVybiB0aW1lciBzY2hlZHVsZSBmb3IgMSBob3VyIGZyb20gbm93CiAgICAgICAgICAgIHJldHVybiBUaW1lclNjaGVkdWxlLkZyb21EYXRlVGltZShEYXRlVGltZS5VdGNOb3cuQWRkTWludXRlcygzKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICAvLyBGYWxsYmFjayB0byAxIGhvdXIgb24gZXJyb3IKICAgICAgICAgICAgcmV0dXJuIFRpbWVyU2NoZWR1bGUuRnJvbURhdGVUaW1lKERhdGVUaW1lLlV0Y05vdy5BZGRNaW51dGVzKDMpKTsKICAgICAgICB9CiAgICB9Cn0KCg==" + }, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "completed", + "stateType": 3, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Completed" + }, + { + "language": "tr-TR", + "label": "Tamamlandı" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + } + ] + } +} \ No newline at end of file diff --git a/core/Workflows/discovery/domain-registration-workflow.json b/core/Workflows/discovery/domain-registration-workflow.json new file mode 100644 index 0000000..be7b35c --- /dev/null +++ b/core/Workflows/discovery/domain-registration-workflow.json @@ -0,0 +1,557 @@ +{ + "key": "domain-registration", + "flow": "sys-flows", + "flowVersion": "1.0.0", + "domain": "core", + "version": "1.0.0", + "tags": [ + "domain", + "registration", + "redis", + "health-check", + "dapr" + ], + "attributes": { + "type": "F", + "timeout": null, + "labels": [ + { + "language": "en-US", + "label": "Domain Registration Workflow" + }, + { + "language": "tr-TR", + "label": "Domain Kayıt İş Akışı" + } + ], + "functions": [], + "features": [], + "extensions": [], + "sharedTransitions": [], + "startTransition": { + "key": "start-domain-registration", + "target": "initial", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Start Domain Registration" + }, + { + "language": "tr-TR", + "label": "Domain Kaydını Başlat" + } + ], + "onExecutionTasks": [] + }, + "states": [ + { + "key": "initial", + "stateType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Initial - Check Domain Exists" + }, + { + "language": "tr-TR", + "label": "Başlangıç - Domain Kontrolü" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "check-domain-exists", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/CheckDomainExistsMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nLkZ1bmN0aW9uczsKLy8vIDxzdW1tYXJ5PgovLy8gQ2hlY2sgRG9tYWluIEV4aXN0cyBNYXBwaW5nIC0gUXVlcmllcyBkb21haW4gd29ya2Zsb3cgaW5zdGFuY2UgZm9yIGV4aXN0ZW5jZSB1c2luZyBEYXByU2VydmljZVRhc2sKLy8vIEVuZHBvaW50OiAvYXBpL3YxL2Rpc2NvdmVyeS93b3JrZmxvd3MvZG9tYWluL2luc3RhbmNlcy97ZG9tYWluTmFtZX0vZnVuY3Rpb25zL2RhdGEKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIENoZWNrRG9tYWluRXhpc3RzTWFwcGluZyA6U2NyaXB0QmFzZSwgSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgc3RyaW5nPyBhcHBJZCA9IEdldENvbmZpZ1ZhbHVlKCJPcmNoZXN0cmF0aW9uQXBpOkFwcElkIik7CiAgICAgICAgICAgIHN0cmluZz8gZGFwckFwcElkID0gR2V0Q29uZmlnVmFsdWUoIkRBUFJfQVBQX0lEIik7CiAgICAgICAgICAgCiAgICAgICAgICAgIHZhciAgZGFwclNlcnZpY2VUYXNrPSB0YXNrIGFzIERhcHJTZXJ2aWNlVGFzazsKICAgICAgICAgICAgaWYgKGRhcHJTZXJ2aWNlVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgRGFwclNlcnZpY2VUYXNrIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkFwcElkIGFyaXlvcnVtIGRhcHI6IitkYXByQXBwSWQpOwogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiQXBwSWQgYXJpeW9ydW0gZXhlYyBzZXQ6IithcHBJZCk7CiAgICAgICAgICAgIGRhcHJTZXJ2aWNlVGFzay5TZXRBcHBJZChkYXByQXBwSWQpOwogICAgICAgICAgICB2YXIgZG9tYWluTmFtZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmRvbWFpbk5hbWU7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBSZXBsYWNlIHtkb21haW5OYW1lfSBwbGFjZWhvbGRlciBpbiBtZXRob2ROYW1lCiAgICAgICAgICAgIC8vIE1ldGhvZE5hbWUgZm9ybWF0OiAvYXBpL3YxL2Rpc2NvdmVyeS93b3JrZmxvd3MvZG9tYWluL2luc3RhbmNlcy97ZG9tYWluTmFtZX0vZnVuY3Rpb25zL2RhdGEKICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShkb21haW5OYW1lPy5Ub1N0cmluZygpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIG1ldGhvZE5hbWUgPSBkYXByU2VydmljZVRhc2suTWV0aG9kTmFtZT8uUmVwbGFjZSgie2RvbWFpbk5hbWV9IiwgZG9tYWluTmFtZS5Ub1N0cmluZygpKSA/PyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkIi9hcGkvdjEvZGlzY292ZXJ5L3dvcmtmbG93cy9kb21haW4vaW5zdGFuY2VzL3tkb21haW5OYW1lfS9mdW5jdGlvbnMvZGF0YSI7CiAgICAgICAgICAgICAgICBkYXByU2VydmljZVRhc2suU2V0TWV0aG9kTmFtZShtZXRob2ROYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiY2hlY2stZG9tYWluLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gV29ya2Zsb3cgSW5zdGFuY2UgRGF0YSBBUEkgcmV0dXJuczoKICAgICAgICAgICAgLy8gLSAyMDAgT0sgd2l0aCBkYXRhIChpbmNsdWRpbmcgZXRhZykgaWYgaW5zdGFuY2UgZXhpc3RzCiAgICAgICAgICAgIC8vIC0gNDA0IE5vdCBGb3VuZCBpZiBpbnN0YW5jZSBkb2Vzbid0IGV4aXN0CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMDsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9IGNvbnRleHQuQm9keTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIERvbWFpbiB3b3JrZmxvdyBpbnN0YW5jZSBleGlzdHMgKDIwMCBPSyB3aXRoIGRhdGEpCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID09IDIwMCAmJiByZXNwb25zZURhdGEgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBldGFnIGZyb20gcmVzcG9uc2UgYm9keSAocm9vdCBsZXZlbCwgbG93ZXJjYXNlKQogICAgICAgICAgICAgICAgLy8gUmVzcG9uc2UgZm9ybWF0OiB7ICJkYXRhIjogeyAiYXBwSWQiOiAiLi4uIiwgImhlYWx0aFVybCI6ICIuLi4iLCAiZG9tYWluTmFtZSI6ICIuLi4iLCAiYmFzZVVybCI6ICIuLi4iIH0sICJldGFnIjogIi4uLiIsICJleHRlbnNpb25zIjoge30gfQogICAgICAgICAgICAgICAgdmFyIGVUYWcgPSByZXNwb25zZURhdGEuZGF0YT8uZXRhZz8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBoZWFsdGhVcmwgYW5kIGFwcElkIGZyb20gZXhpc3RpbmcgZG9tYWluIGRhdGEKICAgICAgICAgICAgICAgIC8vIERvbWFpbiBkYXRhIHN0cnVjdHVyZTogZGlyZWN0IHByb3BlcnRpZXMgaW4gZGF0YSBvYmplY3QgKG5vIHVuZGVyc2NvcmUgcHJlZml4KQogICAgICAgICAgICAgICAgdmFyIGV4aXN0aW5nSGVhbHRoVXJsID0gcmVzcG9uc2VEYXRhLmRhdGE/LmRhdGE/LmhlYWx0aFVybD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIHZhciBleGlzdGluZ0Jhc2VVcmwgPSByZXNwb25zZURhdGEuZGF0YT8uZGF0YT8uYmFzZVVybD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIHZhciBleGlzdGluZ0FwcElkID0gcmVzcG9uc2VEYXRhLmRhdGE/LmRhdGE/LmFwcElkPy5Ub1N0cmluZygpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1leGlzdHMiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbkV4aXN0cyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nRG9tYWluID0gcmVzcG9uc2VEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUVUYWcgPSBlVGFnLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0hlYWx0aFVybCA9IGV4aXN0aW5nSGVhbHRoVXJsLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0Jhc2VVcmw9ZXhpc3RpbmdCYXNlVXJsLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0FwcElkID0gZXhpc3RpbmdBcHBJZCwKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImV4aXN0cyIsICJ3b3JrZmxvdyIsICJpbnN0YW5jZSIsICJmb3VuZCIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBEb21haW4gd29ya2Zsb3cgaW5zdGFuY2Ugbm90IGZvdW5kICg0MDQgTm90IEZvdW5kKQogICAgICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID09IDQwNCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJkb21haW4tbm90LWV4aXN0cyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluRXhpc3RzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nRG9tYWluID0gKG9iamVjdD8pbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VFVGFnID0gKHN0cmluZz8pbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdIZWFsdGhVcmwgPSAoc3RyaW5nPyludWxsLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0FwcElkID0gKHN0cmluZz8pbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgIm5vdC1leGlzdHMiLCAid29ya2Zsb3ciLCAiaW5zdGFuY2UiLCAibm90LWZvdW5kIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgc3RhdHVzIGNvZGUKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1jaGVjay1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbkV4aXN0cyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0RvbWFpbiA9IChvYmplY3Q/KW51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlRVRhZyA9IChzdHJpbmc/KW51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nSGVhbHRoVXJsID0gKHN0cmluZz8pbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdBcHBJZCA9IChzdHJpbmc/KW51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gIlVuZXhwZWN0ZWQgc3RhdHVzIGNvZGUgZHVyaW5nIGRvbWFpbiBpbnN0YW5jZSBjaGVjayIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgICAgICBjaGVjaz1yZXNwb25zZURhdGEuZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImV4Y2VwdGlvbiIsICJlcnJvciIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZG9tYWluLWNoZWNrLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZG9tYWluRXhpc3RzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdEb21haW4gPSAob2JqZWN0PyludWxsLAogICAgICAgICAgICAgICAgICAgIGluc3RhbmNlRVRhZyA9IChzdHJpbmc/KW51bGwsCiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdIZWFsdGhVcmwgPSAoc3RyaW5nPyludWxsLAogICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nQXBwSWQgPSAoc3RyaW5nPyludWxsLAogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkV4Y2VwdGlvbiBkdXJpbmcgZG9tYWluIGluc3RhbmNlIGNoZWNrIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBjaGVja2VkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImV4Y2VwdGlvbiIsICJlcnJvciIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "domain-exists", + "target": "check-domain-need-update", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Domain Exists" + }, + { + "language": "tr-TR", + "label": "Otomatik - Domain Mevcut" + } + ], + "schema": null, + "rule": { + "location": "./src/DomainExistsRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIERvbWFpbiBFeGlzdHMgUnVsZSAtIENoZWNrcyBpZiBkb21haW4gYWxyZWFkeSBleGlzdHMgaW4gd29ya2Zsb3cgaW5zdGFuY2UKLy8vIEFsc28gY2hlY2tzIEVUYWcgdG8gZGV0ZXJtaW5lIGlmIHVwZGF0ZSBpcyBuZWVkZWQKLy8vIFJldHVybnMgZmFsc2UgKHNraXAgdXBkYXRlKSBpZiBFVGFncyBtYXRjaCwgdHJ1ZSAocHJvY2VlZCB0byB1cGRhdGUpIGlmIEVUYWdzIGRpZmZlcgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRG9tYWluRXhpc3RzUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewoKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb250ZXh0Py5JbnN0YW5jZT8uRGF0YSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAgLy8gSWYgbm8gZGF0YSwgYXNzdW1lIGRvbWFpbiBkb2Vzbid0IGV4aXN0CgogICAgICAgICAgICB2YXIgZG9tYWluRXhpc3RzID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmRvbWFpbkV4aXN0czsKCiAgICAgICAgICAgIGlmIChkb21haW5FeGlzdHMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgIC8vIElmIG5vIGNoZWNrIHJlc3VsdCwgYXNzdW1lIGRvbWFpbiBkb2Vzbid0IGV4aXN0CgogICAgICAgICAgICByZXR1cm4gZG9tYWluRXhpc3RzID09IHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7ICAvLyBPbiBlcnJvciwgYXNzdW1lIGRvbWFpbiBkb2Vzbid0IGV4aXN0CiAgICAgICAgfQogICAgICAgIC8vICAgICB0cnkKICAgICAgICAvLyAgICAgewogICAgICAgIC8vICAgICAgICAgaWYgKGNvbnRleHQ/Lkluc3RhbmNlPy5EYXRhID09IG51bGwpCiAgICAgICAgLy8gICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAvLyAgICAgICAgIHZhciBkb21haW5FeGlzdHMgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZG9tYWluRXhpc3RzOwoKICAgICAgICAvLyAgICAgICAgIGlmIChkb21haW5FeGlzdHMgPT0gbnVsbCB8fCBkb21haW5FeGlzdHMgIT0gdHJ1ZSkKICAgICAgICAvLyAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgIC8vICAgICAgICAgLy8gR2V0IEVUYWcgdmFsdWVzCiAgICAgICAgLy8gICAgICAgICAvLyBpbnN0YW5jZUVUYWc6IGZyb20gR2V0SW5zdGFuY2VEYXRhVGFzayByZXNwb25zZSAoY3VycmVudCBpbnN0YW5jZSBFVGFnKQogICAgICAgIC8vICAgICAgICAgLy8gZVRhZzogZnJvbSB0cmFuc2l0aW9uIGNhbGwgKHNlbnQgRVRhZykKICAgICAgICAvLyAgICAgICAgIHZhciBpbnN0YW5jZUVUYWcgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuaW5zdGFuY2VFVGFnPy5Ub1N0cmluZygpOwogICAgICAgIC8vICAgICAgICAgdmFyIHNlbnRFVGFnID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmVUYWc/LlRvU3RyaW5nKCk7CgogICAgICAgIC8vICAgICAgICAgLy8gSWYgbm8gRVRhZ3MgcHJvdmlkZWQsIHByb2NlZWQgdG8gdXBkYXRlIChjb25zZXJ2YXRpdmUgYXBwcm9hY2gpCiAgICAgICAgLy8gICAgICAgICBpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkoaW5zdGFuY2VFVGFnKSB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShzZW50RVRhZykpCiAgICAgICAgLy8gICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgIC8vICAgICAgICAgLy8gSWYgRVRhZ3MgbWF0Y2gsIHNraXAgdXBkYXRlIChyZXR1cm4gZmFsc2UgLSBkb24ndCBnbyB0byB1cGRhdGUgc3RhdGUpCiAgICAgICAgLy8gICAgICAgICBpZiAoaW5zdGFuY2VFVGFnID09IHNlbnRFVGFnKQogICAgICAgIC8vICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgLy8gICAgICAgICAvLyBJZiBFVGFncyBkaWZmZXIsIHByb2NlZWQgdG8gdXBkYXRlIChyZXR1cm4gdHJ1ZSAtIGdvIHRvIHVwZGF0ZSBzdGF0ZSkKICAgICAgICAvLyAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIC8vICAgICB9CiAgICAgICAgLy8gICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgLy8gICAgIHsKICAgICAgICAvLyAgICAgICAgIC8vIE9uIGVycm9yLCBwcm9jZWVkIHRvIHVwZGF0ZSAoY29uc2VydmF0aXZlIGFwcHJvYWNoKQogICAgICAgIC8vICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgLy8gICAgIH0KICAgIH0KfQoKCgo=" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + }, + { + "key": "domain-not-exists", + "target": "register", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Domain Not Exists" + }, + { + "language": "tr-TR", + "label": "Otomatik - Domain Mevcut Değil" + } + ], + "schema": null, + "rule": { + "location": "./src/DomainNotExistsRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIERvbWFpbiBOb3QgRXhpc3RzIFJ1bGUgLSBDaGVja3MgaWYgZG9tYWluIGRvZXMgbm90IGV4aXN0IGluIHdvcmtmbG93IGluc3RhbmNlCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBEb21haW5Ob3RFeGlzdHNSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAgLy8gSWYgbm8gZGF0YSwgYXNzdW1lIGRvbWFpbiBkb2Vzbid0IGV4aXN0CgogICAgICAgICAgICB2YXIgZG9tYWluRXhpc3RzID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmRvbWFpbkV4aXN0czsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChkb21haW5FeGlzdHMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAgLy8gSWYgbm8gY2hlY2sgcmVzdWx0LCBhc3N1bWUgZG9tYWluIGRvZXNuJ3QgZXhpc3QKCiAgICAgICAgICAgIHJldHVybiBkb21haW5FeGlzdHMgPT0gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIE9uIGVycm9yLCBhc3N1bWUgZG9tYWluIGRvZXNuJ3QgZXhpc3QKICAgICAgICB9CiAgICB9Cn0KCgoK" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "register", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Register Domain" + }, + { + "language": "tr-TR", + "label": "Domain Kaydet" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "register-domain-lifecycle", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/RegisterDomainLifecycleMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gUmVnaXN0ZXIgRG9tYWluIExpZmVjeWNsZSBNYXBwaW5nIC0gU3RhcnRzIGRvbWFpbiB3b3JrZmxvdyBpbnN0YW5jZSB3aXRoIGRvbWFpbiBuYW1lIGFzIGtleSB1c2luZyBTdGFydFRhc2sKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFJlZ2lzdGVyRG9tYWluTGlmZWN5Y2xlTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzdGFydFRhc2sgPSB0YXNrIGFzIFN0YXJ0VGFzazsKICAgICAgICAgICAgaWYgKHN0YXJ0VGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgU3RhcnRUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBkb21haW5OYW1lID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9tYWluTmFtZTsKICAgICAgICAgICAgdmFyIGJhc2VVcmwgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5iYXNlVXJsOwogICAgICAgICAgICB2YXIgaGVhbHRoVXJsID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uaGVhbHRoVXJsOwogICAgICAgICAgICB2YXIgYXBwSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5hcHBJZDsKCiAgICAgICAgICAgIC8vIFNldCBpbnN0YW5jZSBrZXkgdG8gZG9tYWluTmFtZQogICAgICAgICAgICAvLyBUaGlzIGVuc3VyZXMgZWFjaCBkb21haW4gaGFzIGl0cyBvd24gd29ya2Zsb3cgaW5zdGFuY2UKICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShkb21haW5OYW1lPy5Ub1N0cmluZygpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RhcnRUYXNrLlNldEtleShkb21haW5OYW1lLlRvU3RyaW5nKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBQcmVwYXJlIGluaXRpYWxpemF0aW9uIGRhdGEKICAgICAgICAgICAgLy8gUGFzcyBkb21haW4gaW5mb3JtYXRpb24gdG8gZG9tYWluIHdvcmtmbG93IChzY2hlbWEgY29tcGxpYW50KQogICAgICAgICAgICBzdGFydFRhc2suU2V0Qm9keShuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZG9tYWluTmFtZSA9IGRvbWFpbk5hbWUsCiAgICAgICAgICAgICAgICBiYXNlVXJsID0gYmFzZVVybCwKICAgICAgICAgICAgICAgIGhlYWx0aFVybCA9IGhlYWx0aFVybCwKICAgICAgICAgICAgICAgIGFwcElkID0gYXBwSWQKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJyZWdpc3Rlci1kb21haW4tbGlmZWN5Y2xlLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gU3RhcnRUYXNrIHJldHVybnMgaW5zdGFuY2VJZCBvbiBzdWNjZXNzCiAgICAgICAgICAgIGlmIChjb250ZXh0LkJvZHk/LmlzU3VjY2VzcyA9PSB0cnVlKQogICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJkb21haW4tbGlmZWN5Y2xlLXN0YXJ0ZWQiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5SZWdpc3RyYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gPSAicmVnaXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbkxpZmVjeWNsZVN0YXJ0ZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9ICJET01BSU5fTElGRUNZQ0xFX1dPUktGTE9XX1NUQVJURUQiCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImxpZmVjeWNsZSIsICJzdGFydGVkIiwgInN0YXJ0IiwgInN1Y2Nlc3MiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1saWZlY3ljbGUtc3RhcnQtZmFpbGVkIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5SZWdpc3RyYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uID0gInJlZ2lzdGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkZhaWxlZCB0byByZWdpc3RlciBkb21haW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IGNvbnRleHQuQm9keT8uc3RhdHVzQ29kZSA/PyA1MDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpc3RlcmVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluTGlmZWN5Y2xlU3RhcnRlZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGNvbnRleHQuQm9keT8uZXJyb3JNZXNzYWdlID8/ICJGYWlsZWQgdG8gc3RhcnQgZG9tYWluIGxpZmVjeWNsZSB3b3JrZmxvdyIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImRvbWFpbiIsICJsaWZlY3ljbGUiLCAic3RhcnQiLCAiZXJyb3IiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1saWZlY3ljbGUtc3RhcnQtZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb21haW5MaWZlY3ljbGVTdGFydGVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRXhjZXB0aW9uIGR1cmluZyBkb21haW4gbGlmZWN5Y2xlIHN0YXJ0IiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgIGRvbWFpblJlZ2lzdHJhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gPSAicmVnaXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJFeGNlcHRpb24gZHVyaW5nIGRvbWFpbiByZWdpc3RyYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJkb21haW4iLCAibGlmZWN5Y2xlIiwgImV4Y2VwdGlvbiIsICJlcnJvciIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "register-success", + "target": "upsert-redis", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Registration Success" + }, + { + "language": "tr-TR", + "label": "Otomatik - Kayıt Başarılı" + } + ], + "schema": null, + "rule": { + "location": "./src/RegisterSuccessRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFJlZ2lzdGVyIFN1Y2Nlc3MgUnVsZSAtIENoZWNrcyBpZiBkb21haW4gcmVnaXN0cmF0aW9uIHdhcyBzdWNjZXNzZnVsCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBSZWdpc3RlclN1Y2Nlc3NSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBkb21haW5SZWdpc3RyYXRpb24gPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZG9tYWluUmVnaXN0cmF0aW9uOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGRvbWFpblJlZ2lzdHJhdGlvbiA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgcmVnaXN0cmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCBvcGVyYXRpb24gaXMgInJlZ2lzdGVyIgogICAgICAgICAgICByZXR1cm4gZG9tYWluUmVnaXN0cmF0aW9uLnN1Y2Nlc3MgPT0gdHJ1ZSAmJiAKICAgICAgICAgICAgICAgICAgIGRvbWFpblJlZ2lzdHJhdGlvbi5vcGVyYXRpb24/LlRvU3RyaW5nKCkgPT0gInJlZ2lzdGVyIjsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "update", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Update Domain" + }, + { + "language": "tr-TR", + "label": "Domain Güncelle" + } + ], + "view": null, + "subFlow": null, + "onEntries": [ + { + "order": 1, + "task": { + "key": "update-domain-lifecycle", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/UpdateDomainLifecycleMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVXBkYXRlIERvbWFpbiBMaWZlY3ljbGUgTWFwcGluZyAtIFRyaWdnZXJzIHVwZGF0ZSB0cmFuc2l0aW9uIGluIGV4aXN0aW5nIGRvbWFpbiB3b3JrZmxvdyBpbnN0YW5jZSB1c2luZyBEaXJlY3RUcmlnZ2VyVGFzawovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgVXBkYXRlRG9tYWluTGlmZWN5Y2xlTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBkaXJlY3RUcmlnZ2VyVGFzayA9IHRhc2sgYXMgRGlyZWN0VHJpZ2dlclRhc2s7CiAgICAgICAgICAgIGlmIChkaXJlY3RUcmlnZ2VyVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgRGlyZWN0VHJpZ2dlclRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGRvbWFpbk5hbWUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb21haW5OYW1lOwogICAgICAgICAgICB2YXIgYmFzZVVybCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmJhc2VVcmw7CiAgICAgICAgICAgIHZhciBoZWFsdGhVcmwgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5oZWFsdGhVcmw7CiAgICAgICAgICAgIHZhciBhcHBJZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFwcElkOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gR2V0IEVUYWcgZnJvbSBpbnN0YW5jZSBkYXRhIChmcm9tIGNoZWNrLWRvbWFpbi1leGlzdHMgcmVzcG9uc2UpCiAgICAgICAgICAgIHZhciBlVGFnID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uaW5zdGFuY2VFVGFnPy5Ub1N0cmluZygpID8/IAogICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZVRhZz8uVG9TdHJpbmcoKTsKCiAgICAgICAgICAgIC8vIFNldCBpbnN0YW5jZSBrZXkgdG8gZG9tYWluTmFtZQogICAgICAgICAgICAvLyBUaGlzIHdpbGwgZmluZCB0aGUgZXhpc3RpbmcgZG9tYWluIHdvcmtmbG93IGluc3RhbmNlCiAgICAgICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkoZG9tYWluTmFtZT8uVG9TdHJpbmcoKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldEtleShkb21haW5OYW1lLlRvU3RyaW5nKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBTZXQgdHJhbnNpdGlvbiBuYW1lIChhbHJlYWR5IGluIGNvbmZpZywgYnV0IGNhbiBiZSBzZXQgZXhwbGljaXRseSkKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0VHJhbnNpdGlvbk5hbWUoInVwZGF0ZSIpOwoKICAgICAgICAgICAgLy8gUHJlcGFyZSB1cGRhdGUgZGF0YQogICAgICAgICAgICAvLyBQYXNzIHVwZGF0ZWQgZG9tYWluIGluZm9ybWF0aW9uIHRvIGRvbWFpbiB3b3JrZmxvdyAoc2NoZW1hIGNvbXBsaWFudCkKICAgICAgICAgICAgLy8gSW5jbHVkZSBFVGFnIGZvciBvcHRpbWlzdGljIGNvbmN1cnJlbmN5IGNvbnRyb2wKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0Qm9keShuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZG9tYWluTmFtZSA9IGRvbWFpbk5hbWUsCiAgICAgICAgICAgICAgICBiYXNlVXJsID0gYmFzZVVybCwKICAgICAgICAgICAgICAgIGhlYWx0aFVybCA9IGhlYWx0aFVybCwKICAgICAgICAgICAgICAgIGFwcElkID0gYXBwSWQKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJ1cGRhdGUtZG9tYWluLWxpZmVjeWNsZS1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIERpcmVjdFRyaWdnZXJUYXNrIHJldHVybnMgc3VjY2VzcyBzdGF0dXMKICAgICAgICAgICAgaWYgKGNvbnRleHQuQm9keT8uaXNTdWNjZXNzID09IHRydWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAiZG9tYWluLWxpZmVjeWNsZS11cGRhdGUtdHJpZ2dlcmVkIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBkb21haW5MaWZlY3ljbGVVcGRhdGVUcmlnZ2VyZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gIkRPTUFJTl9MSUZFQ1lDTEVfVVBEQVRFX1RSSUdHRVJFRCIsCiAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5SZWdpc3RyYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gPSAidXBkYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImxpZmVjeWNsZSIsICJ1cGRhdGUiLCAidHJpZ2dlcmVkIiwgImRpcmVjdC10cmlnZ2VyIiwgInN1Y2Nlc3MiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1saWZlY3ljbGUtdXBkYXRlLWZhaWxlZCIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluTGlmZWN5Y2xlVXBkYXRlVHJpZ2dlcmVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gY29udGV4dC5Cb2R5Py5lcnJvck1lc3NhZ2UgPz8gIkZhaWxlZCB0byB0cmlnZ2VyIGRvbWFpbiBsaWZlY3ljbGUgdXBkYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcmVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5SZWdpc3RyYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uID0gInVwZGF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJGYWlsZWQgdG8gdXBkYXRlIGNhY2hlIGRvbWFpbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImxpZmVjeWNsZSIsICJ1cGRhdGUiLCAiZGlyZWN0LXRyaWdnZXIiLCAiZXJyb3IiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1saWZlY3ljbGUtdXBkYXRlLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZG9tYWluTGlmZWN5Y2xlVXBkYXRlVHJpZ2dlcmVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRXhjZXB0aW9uIGR1cmluZyBkb21haW4gbGlmZWN5Y2xlIHVwZGF0ZSB0cmlnZ2VyIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgZG9tYWluUmVnaXN0cmF0aW9uID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbiA9ICJ1cGRhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJFeGNlcHRpb24gZHVyaW5nIGRvbWFpbiB1cGRhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJkb21haW4iLCAibGlmZWN5Y2xlIiwgInVwZGF0ZSIsICJleGNlcHRpb24iLCAiZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" + } + } + ], + "onExits": [], + "transitions": [ + { + "key": "update-success", + "target": "upsert-redis", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Update Success" + }, + { + "language": "tr-TR", + "label": "Otomatik - Güncelleme Başarılı" + } + ], + "schema": null, + "rule": { + "location": "./src/UpdateSuccessRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFVwZGF0ZSBTdWNjZXNzIFJ1bGUgLSBDaGVja3MgaWYgZG9tYWluIHVwZGF0ZSB3YXMgc3VjY2Vzc2Z1bAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgVXBkYXRlU3VjY2Vzc1J1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb250ZXh0Py5JbnN0YW5jZT8uRGF0YSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgdmFyIGRvbWFpblJlZ2lzdHJhdGlvbiA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5kb21haW5SZWdpc3RyYXRpb247CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoZG9tYWluUmVnaXN0cmF0aW9uID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgICAgICAvLyBDaGVjayBpZiB1cGRhdGUgd2FzIHN1Y2Nlc3NmdWwgYW5kIG9wZXJhdGlvbiBpcyAidXBkYXRlIgogICAgICAgICAgICByZXR1cm4gZG9tYWluUmVnaXN0cmF0aW9uLnN1Y2Nlc3MgPT0gdHJ1ZSAmJiAKICAgICAgICAgICAgICAgICAgIGRvbWFpblJlZ2lzdHJhdGlvbi5vcGVyYXRpb24/LlRvU3RyaW5nKCkgPT0gInVwZGF0ZSI7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "check-domain-need-update", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Update Domain" + }, + { + "language": "tr-TR", + "label": "Domain Güncelle" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "domain-need-update", + "target": "update", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Domain Not Match Send To Update" + }, + { + "language": "tr-TR", + "label": "Otomatik - Domain Eşleşmedi Update e Gönder" + } + ], + "schema": null, + "rule": { + "location": "./src/CheckDomainDontMatchRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBDaGVja0RvbWFpbkRvbnRNYXRjaFJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIEdldCBpbmNvbWluZyB2YWx1ZXMgZnJvbSByZXF1ZXN0CiAgICAgICAgICAgIHZhciBpbmNvbWluZ0hlYWx0aFVybCA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5oZWFsdGhVcmw/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBpbmNvbWluZ0FwcElkID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmFwcElkPy5Ub1N0cmluZygpOwogICAgICAgICAgICB2YXIgaW5jb21pbmdCYXNlVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmJhc2VVcmw/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIC8vIEdldCBleGlzdGluZyB2YWx1ZXMgZnJvbSBkb21haW4gY2hlY2sgcmVzcG9uc2UKICAgICAgICAgICAgdmFyIGV4aXN0aW5nSGVhbHRoVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmV4aXN0aW5nSGVhbHRoVXJsPy5Ub1N0cmluZygpOwogICAgICAgICAgICB2YXIgZXhpc3RpbmdBcHBJZCA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5leGlzdGluZ0FwcElkPy5Ub1N0cmluZygpOwogICAgICAgICAgICB2YXIgZXhpc3RpbmdCYXNlVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmV4aXN0aW5nQmFzZVVybD8uVG9TdHJpbmcoKTsKCiAgICAgICAgICAgIC8vIElmIGVpdGhlciBpbmNvbWluZyB2YWx1ZSBpcyBtaXNzaW5nL251bGwsIHByb2NlZWQgdG8gdXBkYXRlCiAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShpbmNvbWluZ0hlYWx0aFVybCkgfHwgc3RyaW5nLklzTnVsbE9yRW1wdHkoaW5jb21pbmdBcHBJZCkKICAgICAgICAgICAgfHwgc3RyaW5nLklzTnVsbE9yRW1wdHkoaW5jb21pbmdCYXNlVXJsKSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgLy8gSWYgZWl0aGVyIGV4aXN0aW5nIHZhbHVlIGlzIG1pc3NpbmcvbnVsbCwgcHJvY2VlZCB0byB1cGRhdGUKICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGV4aXN0aW5nSGVhbHRoVXJsKSB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShleGlzdGluZ0FwcElkKQogICAgICAgICAgICB8fHN0cmluZy5Jc051bGxPckVtcHR5KGV4aXN0aW5nQmFzZVVybCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgIC8vIElmIGVpdGhlciB2YWx1ZSBkaWZmZXJzLCBwcm9jZWVkIHRvIHVwZGF0ZQogICAgICAgICAgICBpZiAoaW5jb21pbmdIZWFsdGhVcmwuRXF1YWxzKGV4aXN0aW5nSGVhbHRoVXJsLCBTdHJpbmdDb21wYXJpc29uLk9yZGluYWxJZ25vcmVDYXNlKSAmJgogICAgICAgICAgICAgICAgaW5jb21pbmdBcHBJZC5FcXVhbHMoZXhpc3RpbmdBcHBJZCwgU3RyaW5nQ29tcGFyaXNvbi5PcmRpbmFsSWdub3JlQ2FzZSkmJgogICAgICAgICAgICAgICAgaW5jb21pbmdCYXNlVXJsLkVxdWFscyhleGlzdGluZ0Jhc2VVcmwsIFN0cmluZ0NvbXBhcmlzb24uT3JkaW5hbElnbm9yZUNhc2UpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBHbyB0byBjb21wbGV0ZWQKCiAgICAgICAgICAgIC8vIEdvIHRvIHVwZGF0ZQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gR28gdG8gdXBkYXRlIHN0YXRlCiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIE9uIGVycm9yLCBwcm9jZWVkIHRvIHVwZGF0ZSAoY29uc2VydmF0aXZlIGFwcHJvYWNoKQogICAgICAgIH0KICAgIH0KfQoKCgo=" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + }, + { + "key": "domain-dont-need-update", + "target": "completed", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Domain Match Send To Completed" + }, + { + "language": "tr-TR", + "label": "Otomatik - Domain Eşleşti Flowu Bitir" + } + ], + "schema": null, + "rule": { + "location": "./src/CheckDomainMatchRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBDaGVja0RvbWFpbk1hdGNoUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gR2V0IGluY29taW5nIHZhbHVlcyBmcm9tIHJlcXVlc3QKICAgICAgICAgICAgdmFyIGluY29taW5nSGVhbHRoVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmhlYWx0aFVybD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgdmFyIGluY29taW5nQXBwSWQgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuYXBwSWQ/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBpbmNvbWluZ0Jhc2VVcmwgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuYmFzZVVybD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgLy8gR2V0IGV4aXN0aW5nIHZhbHVlcyBmcm9tIGRvbWFpbiBjaGVjayByZXNwb25zZQogICAgICAgICAgICB2YXIgZXhpc3RpbmdIZWFsdGhVcmwgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZXhpc3RpbmdIZWFsdGhVcmw/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBleGlzdGluZ0FwcElkID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmV4aXN0aW5nQXBwSWQ/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBleGlzdGluZ0Jhc2VVcmwgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZXhpc3RpbmdCYXNlVXJsPy5Ub1N0cmluZygpOwoKICAgICAgICAgICAgLy8gSWYgZWl0aGVyIGluY29taW5nIHZhbHVlIGlzIG1pc3NpbmcvbnVsbCwgZG9uJ3Qgc2tpcCB0byBjb21wbGV0ZWQKICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGluY29taW5nSGVhbHRoVXJsKSB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShpbmNvbWluZ0FwcElkKQogICAgICAgICAgICB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShpbmNvbWluZ0Jhc2VVcmwpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgLy8gSWYgZWl0aGVyIGV4aXN0aW5nIHZhbHVlIGlzIG1pc3NpbmcvbnVsbCwgZG9uJ3Qgc2tpcCB0byBjb21wbGV0ZWQKICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGV4aXN0aW5nSGVhbHRoVXJsKSB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShleGlzdGluZ0FwcElkKQogICAgICAgICAgICB8fHN0cmluZy5Jc051bGxPckVtcHR5KGV4aXN0aW5nQmFzZVVybCkpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgICAgICAvLyBJZiBib3RoIHZhbHVlcyBtYXRjaCwgc2tpcCB0byBjb21wbGV0ZWQKICAgICAgICAgICAgaWYgKGluY29taW5nSGVhbHRoVXJsLkVxdWFscyhleGlzdGluZ0hlYWx0aFVybCwgU3RyaW5nQ29tcGFyaXNvbi5PcmRpbmFsSWdub3JlQ2FzZSkgJiYKICAgICAgICAgICAgICAgIGluY29taW5nQXBwSWQuRXF1YWxzKGV4aXN0aW5nQXBwSWQsIFN0cmluZ0NvbXBhcmlzb24uT3JkaW5hbElnbm9yZUNhc2UpJiYKICAgICAgICAgICAgICAgIGluY29taW5nQmFzZVVybC5FcXVhbHMoZXhpc3RpbmdCYXNlVXJsLCBTdHJpbmdDb21wYXJpc29uLk9yZGluYWxJZ25vcmVDYXNlKSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBHbyB0byBjb21wbGV0ZWQKCiAgICAgICAgICAgIC8vIFZhbHVlcyBkb24ndCBtYXRjaCwgZ28gdG8gdXBkYXRlCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsgIC8vIE9uIGVycm9yLCBkb24ndCBza2lwIHRvIGNvbXBsZXRlZAogICAgICAgIH0KICAgIH0KfQoKCgo=" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "upsert-redis", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Upsert Redis" + }, + { + "language": "tr-TR", + "label": "Redis'e Kaydet" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "upsert-success", + "target": "check-health-url", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Redis Success" + }, + { + "language": "tr-TR", + "label": "Otomatik - Redis Başarılı" + } + ], + "schema": null, + "rule": { + "location": "./src/UpsertSuccessRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFVwc2VydCBTdWNjZXNzIFJ1bGUgLSBDaGVja3MgaWYgZG9tYWluIHJlZ2lzdHJhdGlvbi91cGRhdGUgd2FzIHN1Y2Nlc3NmdWwKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFVwc2VydFN1Y2Nlc3NSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBkb21haW5SZWdpc3RyYXRpb24gPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZG9tYWluUmVnaXN0cmF0aW9uOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGRvbWFpblJlZ2lzdHJhdGlvbiA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgcmV0dXJuIGRvbWFpblJlZ2lzdHJhdGlvbi5zdWNjZXNzID09IHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9CgoKCg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + }, + { + "key": "upsert-failure", + "target": "error", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Redis Failure" + }, + { + "language": "tr-TR", + "label": "Otomatik - Redis Hatası" + } + ], + "schema": null, + "rule": { + "location": "./src/UpsertFailureRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFVwc2VydCBGYWlsdXJlIFJ1bGUgLSBDaGVja3MgaWYgZG9tYWluIHJlZ2lzdHJhdGlvbi91cGRhdGUgZmFpbGVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBVcHNlcnRGYWlsdXJlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNvbnRleHQ/Lkluc3RhbmNlPy5EYXRhID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIElmIG5vIGRhdGEsIGNvbnNpZGVyIGl0IGEgZmFpbHVyZQoKICAgICAgICAgICAgdmFyIGRvbWFpblJlZ2lzdHJhdGlvbiA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5kb21haW5SZWdpc3RyYXRpb247CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoZG9tYWluUmVnaXN0cmF0aW9uID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIElmIG5vIHJlZ2lzdHJhdGlvbiByZXN1bHQsIGNvbnNpZGVyIGl0IGEgZmFpbHVyZQoKICAgICAgICAgICAgcmV0dXJuIGRvbWFpblJlZ2lzdHJhdGlvbi5zdWNjZXNzID09IGZhbHNlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7ICAvLyBPbiBlcnJvciwgY29uc2lkZXIgaXQgYSBmYWlsdXJlCiAgICAgICAgfQogICAgfQp9CgoKCg==" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "check-health-url", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Check Health URL" + }, + { + "language": "tr-TR", + "label": "Sağlık URL'sini Kontrol Et" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "trigger-health-check", + "target": "schedule-health-check", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Trigger Health Check" + }, + { + "language": "tr-TR", + "label": "Otomatik - Sağlık Kontrolünü Tetikle" + } + ], + "schema": null, + "rule": { + "location": "./src/ShouldTriggerHealthCheckRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFNob3VsZCBUcmlnZ2VyIEhlYWx0aCBDaGVjayBSdWxlIC0gQ2hlY2tzIGlmIGhlYWx0aCBjaGVjayB3b3JrZmxvdyBzaG91bGQgYmUgdHJpZ2dlcmVkCi8vLyBSZXR1cm5zIHRydWUgaWYgaGVhbHRoVXJsIGV4aXN0cyBBTkQgKG5ldyBkb21haW4gT1IgaGVhbHRoVXJsIGNoYW5nZWQpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBTaG91bGRUcmlnZ2VySGVhbHRoQ2hlY2tSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + }, + { + "key": "skip-health-check", + "target": "completed", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Skip Health Check" + }, + { + "language": "tr-TR", + "label": "Otomatik - Sağlık Kontrolünü Atla" + } + ], + "schema": null, + "rule": { + "location": "./src/SkipHealthCheckRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFNraXAgSGVhbHRoIENoZWNrIFJ1bGUgLSBDaGVja3MgaWYgaGVhbHRoIGNoZWNrIHNob3VsZCBiZSBza2lwcGVkCi8vLyBSZXR1cm5zIHRydWUgaWYgaGVhbHRoVXJsIGlzIG1pc3NpbmcgT1IgKGV4aXN0aW5nIGRvbWFpbiBBTkQgaGVhbHRoVXJsIGRpZG4ndCBjaGFuZ2UpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBTa2lwSGVhbHRoQ2hlY2tSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7ICAvLyBPbiBlcnJvciwgc2tpcAogICAgICAgIH0KICAgIH0KfQoK" + }, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "schedule-health-check", + "stateType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Schedule Health Check" + }, + { + "language": "tr-TR", + "label": "Sağlık Kontrolü Planla" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "health-check-triggered", + "target": "completed", + "triggerType": 2, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Health Check Triggered" + }, + { + "language": "tr-TR", + "label": "Otomatik - Sağlık Kontrolü Tetiklendi" + } + ], + "schema": null, + "timer": { + "location": "./src/ScheduleHealthCheckTimerMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zLlRpbWVyOwoKLy8vIDxzdW1tYXJ5PgovLy8gU2NoZWR1bGUgSGVhbHRoIENoZWNrIFRpbWVyIE1hcHBpbmcgLSBSZXR1cm5zIHRpbWVyIHNjaGVkdWxlIGZvciAzMCBzZWNvbmRzIGRlbGF5Ci8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBTY2hlZHVsZUhlYWx0aENoZWNrVGltZXJNYXBwaW5nIDogSVRpbWVyTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxUaW1lclNjaGVkdWxlPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFJldHVybiB0aW1lciBzY2hlZHVsZSBmb3IgMzAgc2Vjb25kcyBmcm9tIG5vdwogICAgICAgICAgICByZXR1cm4gVGltZXJTY2hlZHVsZS5Gcm9tRGF0ZVRpbWUoRGF0ZVRpbWUuVXRjTm93LkFkZFNlY29uZHMoMzApKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIC8vIEZhbGxiYWNrIHRvIDMwIHNlY29uZHMgb24gZXJyb3IKICAgICAgICAgICAgcmV0dXJuIFRpbWVyU2NoZWR1bGUuRnJvbURhdGVUaW1lKERhdGVUaW1lLlV0Y05vdy5BZGRTZWNvbmRzKDMwKSk7CiAgICAgICAgfQogICAgfQp9Cgo=" + }, + "view": null, + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "schedule-health-check", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/ScheduleHealthCheckMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gU2NoZWR1bGUgSGVhbHRoIENoZWNrIE1hcHBpbmcgLSBUcmlnZ2VycyBkb21haW4taGVhbHRoLWNoZWNrIHdvcmtmbG93IGFzIHN1YnByb2Nlc3MKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFNjaGVkdWxlSGVhbHRoQ2hlY2tNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHN1YlByb2Nlc3NUYXNrID0gdGFzayBhcyBTdWJQcm9jZXNzVGFzazsKICAgICAgICAgICAgaWYgKHN1YlByb2Nlc3NUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYSBTdWJQcm9jZXNzVGFzayIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgZG9tYWluTmFtZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmRvbWFpbk5hbWU7CiAgICAgICAgICAgIHZhciBkb21haW5EYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9tYWluRGF0YTsKICAgICAgICAgICAgdmFyIGhlYWx0aFVybCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmhlYWx0aFVybDsKCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBzdWJwcm9jZXNzCiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldEtleSgiZG9tYWluLWhlYWx0aC1jaGVjayIpOwogICAgICAgICAgICBzdWJQcm9jZXNzVGFzay5TZXRWZXJzaW9uKCIxLjAuMCIpOwoKICAgICAgICAgICAgLy8gUHJlcGFyZSBzdWJwcm9jZXNzIGluaXRpYWxpemF0aW9uIGRhdGEKICAgICAgICAgICAgLy8gUGFzcyBkb21haW4gaW5mb3JtYXRpb24gdG8gaGVhbHRoIGNoZWNrIHdvcmtmbG93CiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldEJvZHkobmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRvbWFpbk5hbWUgPSBkb21haW5OYW1lLAogICAgICAgICAgICAgICAgaGVhbHRoVXJsID0gaGVhbHRoVXJsID8/IGRvbWFpbkRhdGE/LmhlYWx0aFVybCwKICAgICAgICAgICAgICAgIGRvbWFpbkRhdGEgPSBkb21haW5EYXRhCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAic2NoZWR1bGUtaGVhbHRoLWNoZWNrLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gU3ViUHJvY2VzcyBpcyBmaXJlLWFuZC1mb3JnZXQKICAgICAgICAgICAgLy8gSnVzdCB0cmFjayB0aGF0IGl0IHdhcyBpbml0aWF0ZWQKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiaGVhbHRoLWNoZWNrLXRyaWdnZXJlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaGVhbHRoQ2hlY2tUcmlnZ2VyZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgIHRyaWdnZXJlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9ICJIRUFMVEhfQ0hFQ0tfU1VCUFJPQ0VTU19MQVVOQ0hFRCIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImhlYWx0aC1jaGVjayIsICJ0cmlnZ2VyZWQiLCAic3VicHJvY2VzcyIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJoZWFsdGgtY2hlY2stdHJpZ2dlci1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGhlYWx0aENoZWNrVHJpZ2dlcmVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRXhjZXB0aW9uIGR1cmluZyBoZWFsdGggY2hlY2sgdHJpZ2dlciIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JEZXNjcmlwdGlvbiA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcmVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImhlYWx0aC1jaGVjayIsICJleGNlcHRpb24iLCAiZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0K" + } + } + ] + } + ] + }, + { + "key": "completed", + "stateType": 3, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Completed" + }, + { + "language": "tr-TR", + "label": "Tamamlandı" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + }, + { + "key": "error", + "stateType": 3, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Error" + }, + { + "language": "tr-TR", + "label": "Hata" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + } + ] + } +} \ No newline at end of file diff --git a/core/Workflows/discovery/domain-workflow.json b/core/Workflows/discovery/domain-workflow.json new file mode 100644 index 0000000..0d5e926 --- /dev/null +++ b/core/Workflows/discovery/domain-workflow.json @@ -0,0 +1,102 @@ +{ + "key": "domain", + "flow": "sys-flows", + "flowVersion": "1.0.0", + "domain": "core", + "version": "1.0.0", + "tags": [ + "domain", + "lifecycle", + "registration" + ], + "attributes": { + "type": "F", + "timeout": null, + "labels": [ + { + "language": "en-US", + "label": "Domain Lifecycle Workflow" + }, + { + "language": "tr-TR", + "label": "Domain Yaşam Döngüsü İş Akışı" + } + ], + "functions": [], + "features": [], + "extensions": [], + "sharedTransitions": [], + "startTransition": { + "key": "start-domain", + "target": "domain-registered", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Start Domain" + }, + { + "language": "tr-TR", + "label": "Domain'i Başlat" + } + ], + "schema": { + "key": "domain-update", + "version": "1.0.0", + "domain": "core", + "flow": "sys-schemas" + }, + "onExecutionTasks": [] + }, + "states": [ + { + "key": "domain-registered", + "stateType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Domain Registered" + }, + { + "language": "tr-TR", + "label": "Domain Kayıtlı" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "update", + "target": "domain-registered", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto - Update" + }, + { + "language": "tr-TR", + "label": "Otomatik - Güncelle" + } + ], + "schema": { + "key": "domain-update", + "version": "1.0.0", + "domain": "core", + "flow": "sys-schemas" + }, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/core/Workflows/discovery/src/AggregateResultsMapping.csx b/core/Workflows/discovery/src/AggregateResultsMapping.csx new file mode 100644 index 0000000..a42c086 --- /dev/null +++ b/core/Workflows/discovery/src/AggregateResultsMapping.csx @@ -0,0 +1,55 @@ +using System.Threading.Tasks; +using System.Collections.Generic; +using BBT.Workflow.Scripting; + +/// +/// Aggregate Results Mapping - Combines results from current page +/// +public class AggregateResultsMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + // No input handling needed + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // Get results from context + var healthyDomains = context.Instance?.Data?.HealthyDomains as List ?? new List(); + var notHealthyDomains = context.Instance?.Data?.NotHealthyDomains as List ?? new List(); + + // Aggregate results (already combined in CheckDomainHealthMapping) + return new ScriptResponse + { + Key = "to-check-pagination", + Data = new + { + HealthyDomains = healthyDomains, + NotHealthyDomains = notHealthyDomains, + totalHealthy = healthyDomains.Count, + totalNotHealthy = notHealthyDomains.Count, + aggregatedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "aggregate", "results", "success" } + }; + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "aggregate-error", + Data = new + { + error = "Exception during result aggregation", + errorDescription = ex.Message, + aggregatedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "aggregate", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/CheckDomainDontMatchRule.csx b/core/Workflows/discovery/src/CheckDomainDontMatchRule.csx new file mode 100644 index 0000000..8141937 --- /dev/null +++ b/core/Workflows/discovery/src/CheckDomainDontMatchRule.csx @@ -0,0 +1,46 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +public class CheckDomainDontMatchRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + // Get incoming values from request + var incomingHealthUrl = context.Instance.Data.healthUrl?.ToString(); + var incomingAppId = context.Instance.Data.appId?.ToString(); + var incomingBaseUrl = context.Instance.Data.baseUrl?.ToString(); + // Get existing values from domain check response + var existingHealthUrl = context.Instance.Data.existingHealthUrl?.ToString(); + var existingAppId = context.Instance.Data.existingAppId?.ToString(); + var existingBaseUrl = context.Instance.Data.existingBaseUrl?.ToString(); + + // If either incoming value is missing/null, proceed to update + if (string.IsNullOrEmpty(incomingHealthUrl) || string.IsNullOrEmpty(incomingAppId) + || string.IsNullOrEmpty(incomingBaseUrl)) + return true; + + // If either existing value is missing/null, proceed to update + if (string.IsNullOrEmpty(existingHealthUrl) || string.IsNullOrEmpty(existingAppId) + ||string.IsNullOrEmpty(existingBaseUrl)) + return true; + + // If either value differs, proceed to update + if (incomingHealthUrl.Equals(existingHealthUrl, StringComparison.OrdinalIgnoreCase) && + incomingAppId.Equals(existingAppId, StringComparison.OrdinalIgnoreCase)&& + incomingBaseUrl.Equals(existingBaseUrl, StringComparison.OrdinalIgnoreCase)) + return false; // Go to completed + + // Go to update + return true; // Go to update state + } + catch (Exception) + { + return true; // On error, proceed to update (conservative approach) + } + } +} + + + diff --git a/core/Workflows/discovery/src/CheckDomainExistsMapping.csx b/core/Workflows/discovery/src/CheckDomainExistsMapping.csx new file mode 100644 index 0000000..9440e9b --- /dev/null +++ b/core/Workflows/discovery/src/CheckDomainExistsMapping.csx @@ -0,0 +1,149 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting.Functions; +/// +/// Check Domain Exists Mapping - Queries domain workflow instance for existence using DaprServiceTask +/// Endpoint: /api/v1/discovery/workflows/domain/instances/{domainName}/functions/data +/// +public class CheckDomainExistsMapping :ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + string? appId = GetConfigValue("OrchestrationApi:AppId"); + string? daprAppId = GetConfigValue("DAPR_APP_ID"); + + var daprServiceTask= task as DaprServiceTask; + if (daprServiceTask == null) + { + throw new InvalidOperationException("Task must be a DaprServiceTask"); + } + LogInformation("AppId ariyorum dapr:"+daprAppId); + LogInformation("AppId ariyorum exec set:"+appId); + daprServiceTask.SetAppId(daprAppId); + var domainName = context.Instance?.Data?.domainName; + + // Replace {domainName} placeholder in methodName + // MethodName format: /api/v1/discovery/workflows/domain/instances/{domainName}/functions/data + if (!string.IsNullOrEmpty(domainName?.ToString())) + { + var methodName = daprServiceTask.MethodName?.Replace("{domainName}", domainName.ToString()) ?? + $"/api/v1/discovery/workflows/domain/instances/{domainName}/functions/data"; + daprServiceTask.SetMethodName(methodName); + } + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "check-domain-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // Workflow Instance Data API returns: + // - 200 OK with data (including etag) if instance exists + // - 404 Not Found if instance doesn't exist + var statusCode = context.Body?.statusCode ?? 500; + var responseData = context.Body; + + // Domain workflow instance exists (200 OK with data) + if (statusCode == 200 && responseData != null) + { + // Extract etag from response body (root level, lowercase) + // Response format: { "data": { "appId": "...", "healthUrl": "...", "domainName": "...", "baseUrl": "..." }, "etag": "...", "extensions": {} } + var eTag = responseData.data?.etag?.ToString(); + + // Extract healthUrl and appId from existing domain data + // Domain data structure: direct properties in data object (no underscore prefix) + var existingHealthUrl = responseData.data?.data?.healthUrl?.ToString(); + var existingBaseUrl = responseData.data?.data?.baseUrl?.ToString(); + var existingAppId = responseData.data?.data?.appId?.ToString(); + + return new ScriptResponse + { + Key = "domain-exists", + Data = new + { + domainExists = true, + existingDomain = responseData, + instanceETag = eTag, + existingHealthUrl = existingHealthUrl, + existingBaseUrl=existingBaseUrl, + existingAppId = existingAppId, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "exists", "workflow", "instance", "found" } + }; + } + // Domain workflow instance not found (404 Not Found) + else if (statusCode == 404) + { + return new ScriptResponse + { + Key = "domain-not-exists", + Data = new + { + domainExists = false, + existingDomain = (object?)null, + instanceETag = (string?)null, + existingHealthUrl = (string?)null, + existingAppId = (string?)null, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "not-exists", "workflow", "instance", "not-found" } + }; + } + // Unexpected status code + else + { + return new ScriptResponse + { + Key = "domain-check-exception", + Data = new + { + domainExists = false, + existingDomain = (object?)null, + instanceETag = (string?)null, + existingHealthUrl = (string?)null, + existingAppId = (string?)null, + error = "Unexpected status code during domain instance check", + statusCode = statusCode, + check=responseData.data, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "exception", "error" } + }; + } + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "domain-check-exception", + Data = new + { + domainExists = false, + existingDomain = (object?)null, + instanceETag = (string?)null, + existingHealthUrl = (string?)null, + existingAppId = (string?)null, + error = "Exception during domain instance check", + errorDescription = ex.Message, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/CheckDomainHealthMapping.csx b/core/Workflows/discovery/src/CheckDomainHealthMapping.csx new file mode 100644 index 0000000..1f5529b --- /dev/null +++ b/core/Workflows/discovery/src/CheckDomainHealthMapping.csx @@ -0,0 +1,157 @@ +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Check Domain Health Mapping - Checks health for one domain at a time (sequential processing) +/// +public class CheckDomainHealthMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var httpTask = task as HttpTask; + if (httpTask == null) + { + throw new InvalidOperationException("Task must be an HttpTask"); + } + + // Get current domain from pendingDomains array using currentDomainIndex + var pendingDomains = context.Instance?.Data?.pendingDomains as List; + var currentDomainIndex = Convert.ToInt32(context.Instance?.Data?.currentDomainIndex ?? 0); + + if (pendingDomains == null || currentDomainIndex >= pendingDomains.Count) + { + return Task.FromResult(new ScriptResponse + { + Key = "page-complete", + Data = new { error = "No more domains to process" } + }); + } + + // Get current domain + var currentDomain = pendingDomains[currentDomainIndex] as Dictionary; + if (currentDomain == null) + { + return Task.FromResult(new ScriptResponse + { + Key = "page-complete", + Data = new { error = "Invalid domain data" } + }); + } + + var healthUrl = currentDomain.ContainsKey("healthUrl") ? currentDomain["healthUrl"]?.ToString() : null; + + if (string.IsNullOrEmpty(healthUrl)) + { + return Task.FromResult(new ScriptResponse + { + Key = "health-check-error", + Data = new { error = "Health URL is missing" } + }); + } + + // Set the health URL for the HTTP request + httpTask.SetUrl(healthUrl); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "health-check-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + var statusCode = context.Body?.statusCode ?? 500; + var pendingDomains = context.Instance?.Data?.pendingDomains as List ?? new List(); + var currentDomainIndex = Convert.ToInt32(context.Instance?.Data?.currentDomainIndex ?? 0); + var healthyDomains = context.Instance?.Data?.HealthyDomains as List ?? new List(); + var notHealthyDomains = context.Instance?.Data?.NotHealthyDomains as List ?? new List(); + + // Get current domain + if (currentDomainIndex >= pendingDomains.Count) + { + return new ScriptResponse + { + Key = "page-complete", + Data = new + { + HealthyDomains = healthyDomains, + NotHealthyDomains = notHealthyDomains, + processedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", "complete" } + }; + } + + var currentDomain = pendingDomains[currentDomainIndex] as Dictionary; + var domainName = currentDomain?.ContainsKey("domainName") == true ? currentDomain["domainName"]?.ToString() : null; + + // Determine health status based on HTTP status code + // 200 = healthy, otherwise unhealthy + bool isHealthy = statusCode == 200; + + // Add to appropriate list + if (isHealthy) + { + if (!healthyDomains.Contains(domainName)) + { + healthyDomains.Add(domainName); + } + } + else + { + if (!notHealthyDomains.Contains(domainName)) + { + notHealthyDomains.Add(domainName); + } + } + + // Increment index for next domain + var nextIndex = currentDomainIndex + 1; + var hasMoreDomains = nextIndex < pendingDomains.Count; + + return new ScriptResponse + { + Key = hasMoreDomains ? "has-more-domains" : "page-complete", + Data = new + { + currentDomainIndex = nextIndex, + HealthyDomains = healthyDomains, + NotHealthyDomains = notHealthyDomains, + isHealthy = isHealthy, + domainName = domainName, + statusCode = statusCode, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", isHealthy ? "healthy" : "unhealthy", hasMoreDomains ? "continue" : "complete" } + }; + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "health-check-error", + Data = new + { + error = "Exception during health check", + errorDescription = ex.Message, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/CheckDomainMatchRule.csx b/core/Workflows/discovery/src/CheckDomainMatchRule.csx new file mode 100644 index 0000000..4a4699d --- /dev/null +++ b/core/Workflows/discovery/src/CheckDomainMatchRule.csx @@ -0,0 +1,46 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +public class CheckDomainMatchRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + // Get incoming values from request + var incomingHealthUrl = context.Instance.Data.healthUrl?.ToString(); + var incomingAppId = context.Instance.Data.appId?.ToString(); + var incomingBaseUrl = context.Instance.Data.baseUrl?.ToString(); + // Get existing values from domain check response + var existingHealthUrl = context.Instance.Data.existingHealthUrl?.ToString(); + var existingAppId = context.Instance.Data.existingAppId?.ToString(); + var existingBaseUrl = context.Instance.Data.existingBaseUrl?.ToString(); + + // If either incoming value is missing/null, don't skip to completed + if (string.IsNullOrEmpty(incomingHealthUrl) || string.IsNullOrEmpty(incomingAppId) + || string.IsNullOrEmpty(incomingBaseUrl)) + return false; + + // If either existing value is missing/null, don't skip to completed + if (string.IsNullOrEmpty(existingHealthUrl) || string.IsNullOrEmpty(existingAppId) + ||string.IsNullOrEmpty(existingBaseUrl)) + return false; + + // If both values match, skip to completed + if (incomingHealthUrl.Equals(existingHealthUrl, StringComparison.OrdinalIgnoreCase) && + incomingAppId.Equals(existingAppId, StringComparison.OrdinalIgnoreCase)&& + incomingBaseUrl.Equals(existingBaseUrl, StringComparison.OrdinalIgnoreCase)) + return true; // Go to completed + + // Values don't match, go to update + return false; + } + catch (Exception) + { + return false; // On error, don't skip to completed + } + } +} + + + diff --git a/core/Workflows/discovery/src/CheckHealthEndpointMapping.csx b/core/Workflows/discovery/src/CheckHealthEndpointMapping.csx new file mode 100644 index 0000000..1005a2f --- /dev/null +++ b/core/Workflows/discovery/src/CheckHealthEndpointMapping.csx @@ -0,0 +1,151 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Check Health Endpoint Mapping - Performs HTTP GET to health endpoint and determines health status +/// +public class CheckHealthEndpointMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var httpTask = task as HttpTask; + if (httpTask == null) + { + throw new InvalidOperationException("Task must be an HttpTask"); + } + + var fullHealthUrl = context.Instance?.Data?.fullHealthUrl; + + if (string.IsNullOrEmpty(fullHealthUrl)) + { + return Task.FromResult(new ScriptResponse + { + Key = "health-check-error", + Data = new { error = "Health URL is missing" } + }); + } + + // Set the health URL for the HTTP request + httpTask.SetUrl(fullHealthUrl); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "health-check-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + var statusCode = context.Body?.statusCode ?? 500; + var responseData = context.Body; + + // Determine health status based on HTTP status code + // 200-299: Healthy + // 300-399: Degraded (redirects, etc.) + // 400-599: Unhealthy + // Timeout or connection error: Unhealthy + + string healthStatus = null; + bool isHealthy = false; + bool checkPassed = false; + + if (statusCode >= 200 && statusCode < 300) + { + healthStatus = "Healthy"; + isHealthy = true; + checkPassed = true; + } + else if (statusCode >= 300 && statusCode < 400) + { + healthStatus = "Degraded"; + isHealthy = false; + checkPassed = false; + } + else if (statusCode >= 400) + { + healthStatus = "Unhealthy"; + isHealthy = false; + checkPassed = false; + } + else + { + // Timeout or connection error + healthStatus = "Unhealthy"; + isHealthy = false; + checkPassed = false; + } + + if (checkPassed) + { + return new ScriptResponse + { + Key = "health-check-passed", + Data = new + { + healthCheck = new + { + status = healthStatus, + isHealthy = isHealthy, + statusCode = statusCode, + responseData = responseData, + checkedAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "health-check", "passed", "healthy", "success" } + }; + } + else + { + return new ScriptResponse + { + Key = "health-check-failed", + Data = new + { + healthCheck = new + { + status = healthStatus, + isHealthy = isHealthy, + statusCode = statusCode, + error = $"Health check failed with status code {statusCode}", + responseData = responseData, + checkedAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "health-check", "failed", "unhealthy", "error" } + }; + } + } + catch (Exception ex) + { + // Timeout or connection error + return new ScriptResponse + { + Key = "health-check-failed", + Data = new + { + healthCheck = new + { + status = "Unhealthy", + isHealthy = false, + error = "Exception during health check", + errorDescription = ex.Message, + checkedAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "health-check", "failed", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/CheckPaginationRule.csx b/core/Workflows/discovery/src/CheckPaginationRule.csx new file mode 100644 index 0000000..2732645 --- /dev/null +++ b/core/Workflows/discovery/src/CheckPaginationRule.csx @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Check Pagination Rule - Checks if next link exists in response +/// +public class CheckPaginationRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var nextPageUrl = context.Instance.Data.nextPageUrl?.ToString(); + + // Return true if next link is not null/empty + return !string.IsNullOrEmpty(nextPageUrl); + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/DomainExistsRule.csx b/core/Workflows/discovery/src/DomainExistsRule.csx new file mode 100644 index 0000000..31a0e39 --- /dev/null +++ b/core/Workflows/discovery/src/DomainExistsRule.csx @@ -0,0 +1,66 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Domain Exists Rule - Checks if domain already exists in workflow instance +/// Also checks ETag to determine if update is needed +/// Returns false (skip update) if ETags match, true (proceed to update) if ETags differ +/// +public class DomainExistsRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + + try + { + if (context?.Instance?.Data == null) + return false; // If no data, assume domain doesn't exist + + var domainExists = context.Instance.Data.domainExists; + + if (domainExists == null) + return false; // If no check result, assume domain doesn't exist + + return domainExists == true; + } + catch (Exception) + { + return false; // On error, assume domain doesn't exist + } + // try + // { + // if (context?.Instance?.Data == null) + // return false; + + // var domainExists = context.Instance.Data.domainExists; + + // if (domainExists == null || domainExists != true) + // return false; + + // // Get ETag values + // // instanceETag: from GetInstanceDataTask response (current instance ETag) + // // eTag: from transition call (sent ETag) + // var instanceETag = context.Instance.Data.instanceETag?.ToString(); + // var sentETag = context.Instance.Data.eTag?.ToString(); + + // // If no ETags provided, proceed to update (conservative approach) + // if (string.IsNullOrEmpty(instanceETag) || string.IsNullOrEmpty(sentETag)) + // return true; + + // // If ETags match, skip update (return false - don't go to update state) + // if (instanceETag == sentETag) + // return false; + + // // If ETags differ, proceed to update (return true - go to update state) + // return true; + // } + // catch (Exception) + // { + // // On error, proceed to update (conservative approach) + // return true; + // } + } +} + + + diff --git a/core/Workflows/discovery/src/DomainNotExistsRule.csx b/core/Workflows/discovery/src/DomainNotExistsRule.csx new file mode 100644 index 0000000..8fa5274 --- /dev/null +++ b/core/Workflows/discovery/src/DomainNotExistsRule.csx @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Domain Not Exists Rule - Checks if domain does not exist in workflow instance +/// +public class DomainNotExistsRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return true; // If no data, assume domain doesn't exist + + var domainExists = context.Instance.Data.domainExists; + + if (domainExists == null) + return true; // If no check result, assume domain doesn't exist + + return domainExists == false; + } + catch (Exception) + { + return true; // On error, assume domain doesn't exist + } + } +} + + + diff --git a/core/Workflows/discovery/src/DomainsFetchedRule.csx b/core/Workflows/discovery/src/DomainsFetchedRule.csx new file mode 100644 index 0000000..9fd5472 --- /dev/null +++ b/core/Workflows/discovery/src/DomainsFetchedRule.csx @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Domains Fetched Rule - Checks if domains were successfully fetched +/// +public class DomainsFetchedRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + // Always return true - mapping handles the logic via Key + return true; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/FetchDomainsListMapping.csx b/core/Workflows/discovery/src/FetchDomainsListMapping.csx new file mode 100644 index 0000000..37bd7ce --- /dev/null +++ b/core/Workflows/discovery/src/FetchDomainsListMapping.csx @@ -0,0 +1,103 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting.Functions; +/// +/// Fetch Domains List Mapping - Fetches domain list from API endpoint +/// +public class FetchDomainsListMapping :ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var appId = GetConfigValue("OrchestrationApi:AppId"); + var httpTask = task as HttpTask; + if (httpTask == null) + { + throw new InvalidOperationException("Task must be an HttpTask"); + } + + // Get URL from context (could be initial URL or next page URL) + var url = context.Instance?.Data?.currentPageUrl?.ToString() ?? + context.Instance?.Data?.nextPageUrl?.ToString() ?? + "{{discoveryBaseUrl}}/api/v1/discovery/workflows/domain/functions/data?Page=1&PageSize=10"; + + // Set the URL for the HTTP request + httpTask.SetUrl(url); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "fetch-domains-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + var statusCode = context.Body?.statusCode ?? 500; + var responseData = context.Body; + + // Successful response (200 OK) + if (statusCode >= 200 && statusCode < 300 && responseData != null) + { + // Extract items and links from response + var items = responseData.items; + var links = responseData.links; + var nextUrl = links?.next?.ToString(); + + return new ScriptResponse + { + Key = "domains-fetched", + Data = new + { + items = items, + links = links, + nextPageUrl = nextUrl, + currentPageUrl = context.Instance?.Data?.currentPageUrl, + fetchedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "fetch", "success", "api" } + }; + } + // Error response + else + { + return new ScriptResponse + { + Key = "fetch-failed", + Data = new + { + error = "Failed to fetch domains list", + statusCode = statusCode, + responseData = responseData, + fetchedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "fetch", "error", "failed" } + }; + } + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "fetch-failed", + Data = new + { + error = "Exception during domain list fetch", + errorDescription = ex.Message, + fetchedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "fetch", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/FetchFailedRule.csx b/core/Workflows/discovery/src/FetchFailedRule.csx new file mode 100644 index 0000000..a3a2f5a --- /dev/null +++ b/core/Workflows/discovery/src/FetchFailedRule.csx @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Fetch Failed Rule - Checks if fetch failed +/// +public class FetchFailedRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + // Always return true - mapping handles the logic via Key + return true; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/FetchNextPageMapping.csx b/core/Workflows/discovery/src/FetchNextPageMapping.csx new file mode 100644 index 0000000..d212d91 --- /dev/null +++ b/core/Workflows/discovery/src/FetchNextPageMapping.csx @@ -0,0 +1,110 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Fetch Next Page Mapping - Fetches next page using next URL from response +/// +public class FetchNextPageMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var httpTask = task as HttpTask; + if (httpTask == null) + { + throw new InvalidOperationException("Task must be an HttpTask"); + } + + // Get next page URL from context + var nextPageUrl = context.Instance?.Data?.nextPageUrl?.ToString(); + + if (string.IsNullOrEmpty(nextPageUrl)) + { + return Task.FromResult(new ScriptResponse + { + Key = "no-next-page", + Data = new { error = "Next page URL is missing" } + }); + } + + // Set the next page URL for the HTTP request + httpTask.SetUrl(nextPageUrl); + + // Update currentPageUrl + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "fetch-next-page-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + var statusCode = context.Body?.statusCode ?? 500; + var responseData = context.Body; + + // Successful response (200 OK) + if (statusCode >= 200 && statusCode < 300 && responseData != null) + { + // Extract items and links from response + var items = responseData.items; + var links = responseData.links; + var nextUrl = links?.next?.ToString(); + + return new ScriptResponse + { + Key = "next-page-fetched", + Data = new + { + items = items, + links = links, + nextPageUrl = nextUrl, + currentPageUrl = context.Instance?.Data?.nextPageUrl, + fetchedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "fetch", "pagination", "success" } + }; + } + // Error response + else + { + return new ScriptResponse + { + Key = "fetch-next-page-failed", + Data = new + { + error = "Failed to fetch next page", + statusCode = statusCode, + responseData = responseData, + fetchedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "fetch", "pagination", "error" } + }; + } + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "fetch-next-page-failed", + Data = new + { + error = "Exception during next page fetch", + errorDescription = ex.Message, + fetchedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "fetch", "pagination", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/GetDomainHealthUrlMapping.csx b/core/Workflows/discovery/src/GetDomainHealthUrlMapping.csx new file mode 100644 index 0000000..a17174f --- /dev/null +++ b/core/Workflows/discovery/src/GetDomainHealthUrlMapping.csx @@ -0,0 +1,174 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting.Functions; +/// +/// Get Domain Health URL Mapping - Queries Redis for domain and extracts health URL +/// +public class GetDomainHealthUrlMapping :ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var httpTask = task as HttpTask; + //DAPR_HTTP_PORT + var daprHttpPort = GetConfigValue("DAPR_HTTP_PORT"); + if (httpTask == null) + { + throw new InvalidOperationException("Task must be an HttpTask"); + } + + var domainName = context.Instance?.Data?.domainName; + var daprStateStore = GetConfigValue("DAPR_STATE_STORE_NAME"); + string url="http://localhost:"+daprHttpPort+"/v1.0/state/"+daprStateStore+"/domain:"+domainName; + httpTask.SetUrl(url); + // // Replace {domainName} placeholder in URL + // if (httpTask.Url != null) + // { + // httpTask.SetUrl(httpTask.Url.Replace("{domainName}", domainName?.ToString() ?? "")); + // } + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "get-health-url-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // Dapr State Store API returns: + // - 200 OK with value if key exists + // - 204 No Content if key doesn't exist + // - 404 Not Found if key doesn't exist (alternative) + var statusCode = context.Body?.statusCode ?? 500; + var responseData = context.Body; + + // Domain exists (200 OK with data) + if (statusCode == 200 && responseData != null) + { + var baseUrl = responseData.baseUrl; + var healthUrl = responseData.healthUrl; + + // Construct full health URL + string fullHealthUrl = null; + if (!string.IsNullOrEmpty(healthUrl)) + { + // If healthUrl is absolute, use it directly + if (healthUrl.StartsWith("http://") || healthUrl.StartsWith("https://")) + { + fullHealthUrl = healthUrl; + } + // If healthUrl is relative, combine with baseUrl + else if (!string.IsNullOrEmpty(baseUrl)) + { + var baseUrlTrimmed = baseUrl.TrimEnd('/'); + var healthUrlTrimmed = healthUrl.TrimStart('/'); + fullHealthUrl = $"{baseUrlTrimmed}/{healthUrlTrimmed}"; + } + else + { + // Health URL provided but no base URL + return new ScriptResponse + { + Key = "health-url-missing", + Data = new + { + healthUrlRetrieved = false, + error = "Health URL found but base URL is missing", + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", "url-missing", "error" } + }; + } + } + else + { + // Health URL not found in domain data + return new ScriptResponse + { + Key = "health-url-missing", + Data = new + { + healthUrlRetrieved = false, + error = "Health URL not found in domain data", + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", "url-missing", "error" } + }; + } + + return new ScriptResponse + { + Key = "health-url-retrieved", + Data = new + { + healthUrlRetrieved = true, + fullHealthUrl = fullHealthUrl, + baseUrl = baseUrl, + healthUrl = healthUrl, + domainData = responseData, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", "url-retrieved", "success" } + }; + } + // Domain not found (204 No Content or 404 Not Found) + else if (statusCode == 204 || statusCode == 404) + { + return new ScriptResponse + { + Key = "health-url-missing", + Data = new + { + healthUrlRetrieved = false, + error = "Domain not found in Redis", + statusCode = statusCode, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", "url-missing", "not-found" } + }; + } + // Unexpected status code + else + { + return new ScriptResponse + { + Key = "health-url-error", + Data = new + { + healthUrlRetrieved = false, + error = "Unexpected status code during domain lookup", + statusCode = statusCode, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", "error", "exception" } + }; + } + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "health-url-exception", + Data = new + { + healthUrlRetrieved = false, + error = "Exception during health URL retrieval", + errorDescription = ex.Message, + checkedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/HasMoreDomainsRule.csx b/core/Workflows/discovery/src/HasMoreDomainsRule.csx new file mode 100644 index 0000000..057dca0 --- /dev/null +++ b/core/Workflows/discovery/src/HasMoreDomainsRule.csx @@ -0,0 +1,32 @@ +using System.Threading.Tasks; +using System.Collections.Generic; +using BBT.Workflow.Scripting; + +/// +/// Has More Domains Rule - Checks if there are more domains to process in current page +/// +public class HasMoreDomainsRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var pendingDomains = context.Instance.Data.pendingDomains as List; + var currentDomainIndex = Convert.ToInt32(context.Instance.Data.currentDomainIndex ?? 0); + + if (pendingDomains == null) + return false; + + // Check if there are more domains to process + return currentDomainIndex < pendingDomains.Count; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/HealthCheckFailedRule.csx b/core/Workflows/discovery/src/HealthCheckFailedRule.csx new file mode 100644 index 0000000..c78effb --- /dev/null +++ b/core/Workflows/discovery/src/HealthCheckFailedRule.csx @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Health Check Failed Rule - Checks if health check failed +/// +public class HealthCheckFailedRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return true; // If no data, consider it failed + + var healthCheck = context.Instance.Data.healthCheck; + + if (healthCheck == null) + return true; // If no health check result, consider it failed + + var isHealthy = healthCheck.isHealthy; + if (isHealthy == null) + return true; // If health status unknown, consider it failed + + return isHealthy == false; + } + catch (Exception) + { + return true; // On error, consider it failed + } + } +} + diff --git a/core/Workflows/discovery/src/HealthCheckPassedRule.csx b/core/Workflows/discovery/src/HealthCheckPassedRule.csx new file mode 100644 index 0000000..05e895d --- /dev/null +++ b/core/Workflows/discovery/src/HealthCheckPassedRule.csx @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Health Check Passed Rule - Checks if health check passed +/// +public class HealthCheckPassedRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var healthCheck = context.Instance.Data.healthCheck; + + if (healthCheck == null) + return false; + + var isHealthy = healthCheck.isHealthy; + if (isHealthy == null) + return false; + + return isHealthy == true; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/HealthCheckScheduledRule.csx b/core/Workflows/discovery/src/HealthCheckScheduledRule.csx new file mode 100644 index 0000000..0911ec8 --- /dev/null +++ b/core/Workflows/discovery/src/HealthCheckScheduledRule.csx @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Health Check Scheduled Rule - Checks if health check was successfully scheduled +/// +public class HealthCheckScheduledRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var healthCheckSchedule = context.Instance.Data.healthCheckSchedule; + + if (healthCheckSchedule == null) + return false; + + return healthCheckSchedule.success == true && healthCheckSchedule.scheduled == true; + } + catch (Exception) + { + return false; + } + } +} + + + diff --git a/core/Workflows/discovery/src/HealthCheckTriggeredRule.csx b/core/Workflows/discovery/src/HealthCheckTriggeredRule.csx new file mode 100644 index 0000000..3959a06 --- /dev/null +++ b/core/Workflows/discovery/src/HealthCheckTriggeredRule.csx @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Health Check Triggered Rule - Checks if health check workflow was successfully triggered +/// Returns true if healthCheckTriggered == true +/// +public class HealthCheckTriggeredRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var healthCheckTriggered = context.Instance.Data.healthCheckTriggered; + return healthCheckTriggered == true; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/HealthStatusUpdateSuccessRule.csx b/core/Workflows/discovery/src/HealthStatusUpdateSuccessRule.csx new file mode 100644 index 0000000..19fbe18 --- /dev/null +++ b/core/Workflows/discovery/src/HealthStatusUpdateSuccessRule.csx @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Health Status Update Success Rule - Checks if health status update was successful +/// +public class HealthStatusUpdateSuccessRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var healthStatusUpdate = context.Instance.Data.healthStatusUpdate; + + if (healthStatusUpdate == null) + return false; + + // Check if update was successful + return healthStatusUpdate.success == true; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/HealthUrlMissingRule.csx b/core/Workflows/discovery/src/HealthUrlMissingRule.csx new file mode 100644 index 0000000..65af4cb --- /dev/null +++ b/core/Workflows/discovery/src/HealthUrlMissingRule.csx @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Health URL Missing Rule - Checks if health URL retrieval failed +/// +public class HealthUrlMissingRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return true; // If no data, consider it missing + + var healthUrlRetrieved = context.Instance.Data.healthUrlRetrieved; + + if (healthUrlRetrieved == null) + return true; // If no retrieval result, consider it missing + + return healthUrlRetrieved == false; + } + catch (Exception) + { + return true; // On error, consider it missing + } + } +} + diff --git a/core/Workflows/discovery/src/HealthUrlRetrievedRule.csx b/core/Workflows/discovery/src/HealthUrlRetrievedRule.csx new file mode 100644 index 0000000..c7bdc31 --- /dev/null +++ b/core/Workflows/discovery/src/HealthUrlRetrievedRule.csx @@ -0,0 +1,29 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Health URL Retrieved Rule - Checks if health URL was successfully retrieved +/// +public class HealthUrlRetrievedRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var healthUrlRetrieved = context.Instance.Data.healthUrlRetrieved; + + if (healthUrlRetrieved == null) + return false; + + return healthUrlRetrieved == true; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/InitialTransitionRule.csx b/core/Workflows/discovery/src/InitialTransitionRule.csx new file mode 100644 index 0000000..b8e7cfb --- /dev/null +++ b/core/Workflows/discovery/src/InitialTransitionRule.csx @@ -0,0 +1,25 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Initial Transition Rule - Always allows transition from initial state +/// This rule always returns true to allow automatic transition from initial state +/// +public class InitialTransitionRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + // Always allow transition from initial state + // Initial state is the entry point, so transition should always proceed + return true; + } + catch (Exception) + { + // On error, still allow transition to prevent workflow from getting stuck + return true; + } + } +} + diff --git a/core/Workflows/discovery/src/MarkUnhealthyRule.csx b/core/Workflows/discovery/src/MarkUnhealthyRule.csx new file mode 100644 index 0000000..70bdd8a --- /dev/null +++ b/core/Workflows/discovery/src/MarkUnhealthyRule.csx @@ -0,0 +1,45 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Mark Unhealthy Rule - Checks if domain should be marked as unhealthy +/// This rule checks if health URL is missing or health check failed +/// +public class MarkUnhealthyRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return true; // If no data, consider it unhealthy + + // Check if health URL retrieval failed + var healthUrlRetrieved = context.Instance.Data.healthUrlRetrieved; + if (healthUrlRetrieved == false) + return true; + + // Check if health check failed + var healthCheck = context.Instance.Data.healthCheck; + if (healthCheck != null) + { + var isHealthy = healthCheck.isHealthy; + if (isHealthy == false) + return true; + } + + // Check if markUnhealthy flag is explicitly set + var markUnhealthy = context.Instance.Data.markUnhealthy; + if (markUnhealthy == true) + return true; + + // If none of the unhealthy conditions are met, don't transition + return false; + } + catch (Exception) + { + return true; // On error, consider it unhealthy + } + } +} + diff --git a/core/Workflows/discovery/src/NextPageFetchedRule.csx b/core/Workflows/discovery/src/NextPageFetchedRule.csx new file mode 100644 index 0000000..42840a8 --- /dev/null +++ b/core/Workflows/discovery/src/NextPageFetchedRule.csx @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Next Page Fetched Rule - Checks if next page was successfully fetched +/// +public class NextPageFetchedRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + // Always return true - mapping handles the logic via Key + return true; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/NoDomainsRule.csx b/core/Workflows/discovery/src/NoDomainsRule.csx new file mode 100644 index 0000000..5851e4d --- /dev/null +++ b/core/Workflows/discovery/src/NoDomainsRule.csx @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using System.Collections.Generic; +using BBT.Workflow.Scripting; + +/// +/// No Domains Rule - Checks if no domains to process +/// +public class NoDomainsRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return true; + + var pendingDomains = context.Instance.Data.pendingDomains as List; + return pendingDomains == null || pendingDomains.Count == 0; + } + catch (Exception) + { + return true; + } + } +} + diff --git a/core/Workflows/discovery/src/NoNextRule.csx b/core/Workflows/discovery/src/NoNextRule.csx new file mode 100644 index 0000000..c963272 --- /dev/null +++ b/core/Workflows/discovery/src/NoNextRule.csx @@ -0,0 +1,25 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// No Next Rule - Checks if there is no next page (opposite of CheckPaginationRule) +/// +public class NoNextRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return true; + + var nextPageUrl = context.Instance.Data.nextPageUrl?.ToString(); + return string.IsNullOrEmpty(nextPageUrl); + } + catch (Exception) + { + return true; + } + } +} + diff --git a/core/Workflows/discovery/src/PageCompleteRule.csx b/core/Workflows/discovery/src/PageCompleteRule.csx new file mode 100644 index 0000000..e809777 --- /dev/null +++ b/core/Workflows/discovery/src/PageCompleteRule.csx @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using System.Collections.Generic; +using BBT.Workflow.Scripting; + +/// +/// Page Complete Rule - Checks if current page processing is complete +/// +public class PageCompleteRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var pendingDomains = context.Instance.Data.pendingDomains as List; + var currentDomainIndex = Convert.ToInt32(context.Instance.Data.currentDomainIndex ?? 0); + + if (pendingDomains == null) + return true; + + return currentDomainIndex >= pendingDomains.Count; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/ProcessPageMapping.csx b/core/Workflows/discovery/src/ProcessPageMapping.csx new file mode 100644 index 0000000..0474f3d --- /dev/null +++ b/core/Workflows/discovery/src/ProcessPageMapping.csx @@ -0,0 +1,103 @@ +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using BBT.Workflow.Scripting; + +/// +/// Process Page Mapping - Extracts domains from page items and creates pendingDomains queue +/// +public class ProcessPageMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + // No input handling needed for this mapping + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + var items = context.Instance?.Data?.items; + + if (items == null) + { + return new ScriptResponse + { + Key = "no-domains", + Data = new + { + pendingDomains = new List(), + processedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "process", "empty" } + }; + } + + // Initialize result lists if first page + var healthyDomains = context.Instance?.Data?.HealthyDomains as List ?? new List(); + var notHealthyDomains = context.Instance?.Data?.NotHealthyDomains as List ?? new List(); + + // Extract domains from items array + var pendingDomains = new List(); + + // Iterate through items and extract domainName and healthUrl + if (items is IEnumerable itemsEnumerable) + { + foreach (var item in itemsEnumerable) + { + if (item is Dictionary itemDict) + { + var data = itemDict.ContainsKey("data") ? itemDict["data"] : null; + if (data is Dictionary dataDict) + { + var domainName = dataDict.ContainsKey("domainName") ? dataDict["domainName"]?.ToString() : null; + var healthUrl = dataDict.ContainsKey("healthUrl") ? dataDict["healthUrl"]?.ToString() : null; + + if (!string.IsNullOrEmpty(domainName) && !string.IsNullOrEmpty(healthUrl)) + { + pendingDomains.Add(new Dictionary + { + { "domainName", domainName }, + { "healthUrl", healthUrl } + }); + } + } + } + } + } + + // Initialize currentDomainIndex + var currentDomainIndex = 0; + + return new ScriptResponse + { + Key = pendingDomains.Count > 0 ? "to-check-health" : "no-domains", + Data = new + { + pendingDomains = pendingDomains, + currentDomainIndex = currentDomainIndex, + HealthyDomains = healthyDomains, + NotHealthyDomains = notHealthyDomains, + processedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "process", "success" } + }; + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "process-page-error", + Data = new + { + error = "Exception during page processing", + errorDescription = ex.Message, + processedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "process", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/RegisterDomainLifecycleMapping.csx b/core/Workflows/discovery/src/RegisterDomainLifecycleMapping.csx new file mode 100644 index 0000000..28f4889 --- /dev/null +++ b/core/Workflows/discovery/src/RegisterDomainLifecycleMapping.csx @@ -0,0 +1,128 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Register Domain Lifecycle Mapping - Starts domain workflow instance with domain name as key using StartTask +/// +public class RegisterDomainLifecycleMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var startTask = task as StartTask; + if (startTask == null) + { + throw new InvalidOperationException("Task must be a StartTask"); + } + + var domainName = context.Instance?.Data?.domainName; + var baseUrl = context.Instance?.Data?.baseUrl; + var healthUrl = context.Instance?.Data?.healthUrl; + var appId = context.Instance?.Data?.appId; + + // Set instance key to domainName + // This ensures each domain has its own workflow instance + if (!string.IsNullOrEmpty(domainName?.ToString())) + { + startTask.SetKey(domainName.ToString()); + } + + // Prepare initialization data + // Pass domain information to domain workflow (schema compliant) + startTask.SetBody(new + { + domainName = domainName, + baseUrl = baseUrl, + healthUrl = healthUrl, + appId = appId + }); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "register-domain-lifecycle-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // StartTask returns instanceId on success + if (context.Body?.isSuccess == true) + { + + return new ScriptResponse + { + Key = "domain-lifecycle-started", + Data = new + { + domainRegistration = new + { + success = true, + operation = "register", + registeredAt = DateTime.UtcNow + }, + domainLifecycleStarted = true, + startedAt = DateTime.UtcNow, + status = "DOMAIN_LIFECYCLE_WORKFLOW_STARTED" + }, + Tags = new[] { "domain", "lifecycle", "started", "start", "success" } + }; + } + else + { + return new ScriptResponse + { + Key = "domain-lifecycle-start-failed", + Data = new + { + domainRegistration = new + { + success = false, + operation = "register", + error = "Failed to register domain", + statusCode = context.Body?.statusCode ?? 500, + registeredAt = DateTime.UtcNow + }, + domainLifecycleStarted = false, + error = context.Body?.errorMessage ?? "Failed to start domain lifecycle workflow", + startedAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "lifecycle", "start", "error" } + }; + } + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "domain-lifecycle-start-exception", + Data = new + { + domainLifecycleStarted = false, + error = "Exception during domain lifecycle start", + errorDescription = ex.Message, + startedAt = DateTime.UtcNow, + domainRegistration = new + { + success = false, + operation = "register", + error = "Exception during domain registration", + errorDescription = ex.Message, + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "lifecycle", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/RegisterDomainMapping.csx b/core/Workflows/discovery/src/RegisterDomainMapping.csx new file mode 100644 index 0000000..dbe6a50 --- /dev/null +++ b/core/Workflows/discovery/src/RegisterDomainMapping.csx @@ -0,0 +1,130 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting.Functions; +/// +/// Register Domain Mapping - Creates new domain in Redis +/// +public class RegisterDomainMapping :ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var httpTask = task as HttpTask; + if (httpTask == null) + { + throw new InvalidOperationException("Task must be an HttpTask"); + } + + var domainName = context.Instance?.Data?.domainName; + var baseUrl = context.Instance?.Data?.baseUrl; + var healthUrl = context.Instance?.Data?.healthUrl; + var appId = context.Instance?.Data?.appId; + // var flows = context.Instance?.Data?.flows; + var daprHttpPort = GetConfigValue("DAPR_HTTP_PORT"); + var daprStateStore = GetConfigValue("DAPR_STATE_STORE_NAME"); + string url="http://localhost:"+daprHttpPort+"/v1.0/state/"+daprStateStore; + httpTask.SetUrl(url); + // Prepare domain data for Dapr State Store API + // Dapr State Store expects array of state items + var stateItem = new + { + key = $"domain:{domainName}", + value = new + { + name = domainName, + baseUrl = baseUrl, + healthUrl = healthUrl, + appId = appId, + isHealthy = true, + updatedAt = DateTime.UtcNow.ToString("o"), + // flows = flows ?? new { } + } + }; + + // Set body for HTTP POST request + httpTask.SetBody(new[] { stateItem }); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "register-domain-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // Dapr State Store API returns 204 No Content on success + // Check HTTP status code from context + var statusCode = context.Body?.statusCode ?? 500; + var isSuccess = statusCode >= 200 && statusCode < 300; + + // Successful registration (204 No Content is success for state store) + if (isSuccess || statusCode == 204) + { + return new ScriptResponse + { + Key = "domain-registered", + Data = new + { + domainRegistration = new + { + success = true, + operation = "register", + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "registered", "redis", "success" } + }; + } + // Registration failed + else + { + return new ScriptResponse + { + Key = "domain-registration-failed", + Data = new + { + domainRegistration = new + { + success = false, + operation = "register", + error = "Failed to register domain", + statusCode = statusCode, + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "registration-failed", "redis", "error" } + }; + } + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "domain-registration-exception", + Data = new + { + domainRegistration = new + { + success = false, + operation = "register", + error = "Exception during domain registration", + errorDescription = ex.Message, + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/RegisterSuccessRule.csx b/core/Workflows/discovery/src/RegisterSuccessRule.csx new file mode 100644 index 0000000..4c7438b --- /dev/null +++ b/core/Workflows/discovery/src/RegisterSuccessRule.csx @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Register Success Rule - Checks if domain registration was successful +/// +public class RegisterSuccessRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var domainRegistration = context.Instance.Data.domainRegistration; + + if (domainRegistration == null) + return false; + + // Check if registration was successful and operation is "register" + return domainRegistration.success == true && + domainRegistration.operation?.ToString() == "register"; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/ScheduleHealthCheckMapping.csx b/core/Workflows/discovery/src/ScheduleHealthCheckMapping.csx new file mode 100644 index 0000000..877b20e --- /dev/null +++ b/core/Workflows/discovery/src/ScheduleHealthCheckMapping.csx @@ -0,0 +1,83 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Schedule Health Check Mapping - Triggers domain-health-check workflow as subprocess +/// +public class ScheduleHealthCheckMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var subProcessTask = task as SubProcessTask; + if (subProcessTask == null) + { + throw new InvalidOperationException("Task must be a SubProcessTask"); + } + + var domainName = context.Instance?.Data?.domainName; + var domainData = context.Instance?.Data?.domainData; + var healthUrl = context.Instance?.Data?.healthUrl; + + // Configure subprocess + subProcessTask.SetKey("domain-health-check"); + subProcessTask.SetVersion("1.0.0"); + + // Prepare subprocess initialization data + // Pass domain information to health check workflow + subProcessTask.SetBody(new + { + domainName = domainName, + healthUrl = healthUrl ?? domainData?.healthUrl, + domainData = domainData + }); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "schedule-health-check-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // SubProcess is fire-and-forget + // Just track that it was initiated + return new ScriptResponse + { + Key = "health-check-triggered", + Data = new + { + healthCheckTriggered = true, + triggeredAt = DateTime.UtcNow, + status = "HEALTH_CHECK_SUBPROCESS_LAUNCHED" + }, + Tags = new[] { "domain", "health-check", "triggered", "subprocess", "success" } + }; + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "health-check-trigger-exception", + Data = new + { + healthCheckTriggered = false, + error = "Exception during health check trigger", + errorDescription = ex.Message, + triggeredAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "health-check", "exception", "error" } + }; + } + } +} diff --git a/core/Workflows/discovery/src/ScheduleHealthCheckTimerMapping.csx b/core/Workflows/discovery/src/ScheduleHealthCheckTimerMapping.csx new file mode 100644 index 0000000..ed54628 --- /dev/null +++ b/core/Workflows/discovery/src/ScheduleHealthCheckTimerMapping.csx @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions.Timer; + +/// +/// Schedule Health Check Timer Mapping - Returns timer schedule for 30 seconds delay +/// +public class ScheduleHealthCheckTimerMapping : ITimerMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + // Return timer schedule for 30 seconds from now + return TimerSchedule.FromDateTime(DateTime.UtcNow.AddSeconds(30)); + } + catch (Exception) + { + // Fallback to 30 seconds on error + return TimerSchedule.FromDateTime(DateTime.UtcNow.AddSeconds(30)); + } + } +} + diff --git a/core/Workflows/discovery/src/ScheduleNextRunMapping.csx b/core/Workflows/discovery/src/ScheduleNextRunMapping.csx new file mode 100644 index 0000000..d11974f --- /dev/null +++ b/core/Workflows/discovery/src/ScheduleNextRunMapping.csx @@ -0,0 +1,71 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Schedule Next Run Mapping - Triggers domain-health-check workflow as subprocess for next execution +/// +public class ScheduleNextRunMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var subProcessTask = task as SubProcessTask; + if (subProcessTask == null) + { + throw new InvalidOperationException("Task must be a SubProcessTask"); + } + + // Configure subprocess to trigger the same workflow + subProcessTask.SetKey("domain-health-check"); + subProcessTask.SetVersion("1.0.0"); + + // Prepare subprocess initialization data (empty for scheduled run) + subProcessTask.SetBody(new { }); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "schedule-next-run-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // SubProcess is fire-and-forget, so we just return success + return new ScriptResponse + { + Key = "scheduled", + Data = new + { + scheduledAt = DateTime.UtcNow, + nextRunIn = "1 hour" + }, + Tags = new[] { "domain", "schedule", "health-check", "success" } + }; + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "schedule-next-run-error", + Data = new + { + error = "Exception during scheduling", + errorDescription = ex.Message, + scheduledAt = DateTime.UtcNow + }, + Tags = new[] { "domain", "schedule", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/ScheduleNextRunTimerMapping.csx b/core/Workflows/discovery/src/ScheduleNextRunTimerMapping.csx new file mode 100644 index 0000000..c50a31c --- /dev/null +++ b/core/Workflows/discovery/src/ScheduleNextRunTimerMapping.csx @@ -0,0 +1,24 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions.Timer; + +/// +/// Schedule Next Run Timer Mapping - Returns timer schedule for 1 hour delay +/// +public class ScheduleNextRunTimerMapping : ITimerMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + // Return timer schedule for 1 hour from now + return TimerSchedule.FromDateTime(DateTime.UtcNow.AddMinutes(3)); + } + catch (Exception) + { + // Fallback to 1 hour on error + return TimerSchedule.FromDateTime(DateTime.UtcNow.AddMinutes(3)); + } + } +} + diff --git a/core/Workflows/discovery/src/ScheduledRule.csx b/core/Workflows/discovery/src/ScheduledRule.csx new file mode 100644 index 0000000..8674615 --- /dev/null +++ b/core/Workflows/discovery/src/ScheduledRule.csx @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Scheduled Rule - Checks if next run was scheduled +/// +public class ScheduledRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + // Always return true - mapping handles the logic via Key + return true; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/ShouldTriggerHealthCheckRule.csx b/core/Workflows/discovery/src/ShouldTriggerHealthCheckRule.csx new file mode 100644 index 0000000..4c76aef --- /dev/null +++ b/core/Workflows/discovery/src/ShouldTriggerHealthCheckRule.csx @@ -0,0 +1,22 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Should Trigger Health Check Rule - Checks if health check workflow should be triggered +/// Returns true if healthUrl exists AND (new domain OR healthUrl changed) +/// +public class ShouldTriggerHealthCheckRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + return false; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/SkipHealthCheckRule.csx b/core/Workflows/discovery/src/SkipHealthCheckRule.csx new file mode 100644 index 0000000..8e3787c --- /dev/null +++ b/core/Workflows/discovery/src/SkipHealthCheckRule.csx @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Skip Health Check Rule - Checks if health check should be skipped +/// Returns true if healthUrl is missing OR (existing domain AND healthUrl didn't change) +/// +public class SkipHealthCheckRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + + return true; + } + catch (Exception) + { + return true; // On error, skip + } + } +} + diff --git a/core/Workflows/discovery/src/ToCheckHealthRule.csx b/core/Workflows/discovery/src/ToCheckHealthRule.csx new file mode 100644 index 0000000..2f5ae1b --- /dev/null +++ b/core/Workflows/discovery/src/ToCheckHealthRule.csx @@ -0,0 +1,26 @@ +using System.Threading.Tasks; +using System.Collections.Generic; +using BBT.Workflow.Scripting; + +/// +/// To Check Health Rule - Checks if should proceed to health check +/// +public class ToCheckHealthRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var pendingDomains = context.Instance.Data.pendingDomains as List; + return pendingDomains != null && pendingDomains.Count > 0; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/ToCheckPaginationRule.csx b/core/Workflows/discovery/src/ToCheckPaginationRule.csx new file mode 100644 index 0000000..c4649b7 --- /dev/null +++ b/core/Workflows/discovery/src/ToCheckPaginationRule.csx @@ -0,0 +1,21 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// To Check Pagination Rule - Always allows transition to pagination check +/// +public class ToCheckPaginationRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + return true; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/UpdateDomainLifecycleMapping.csx b/core/Workflows/discovery/src/UpdateDomainLifecycleMapping.csx new file mode 100644 index 0000000..6cfa4a0 --- /dev/null +++ b/core/Workflows/discovery/src/UpdateDomainLifecycleMapping.csx @@ -0,0 +1,135 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Update Domain Lifecycle Mapping - Triggers update transition in existing domain workflow instance using DirectTriggerTask +/// +public class UpdateDomainLifecycleMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var directTriggerTask = task as DirectTriggerTask; + if (directTriggerTask == null) + { + throw new InvalidOperationException("Task must be a DirectTriggerTask"); + } + + var domainName = context.Instance?.Data?.domainName; + var baseUrl = context.Instance?.Data?.baseUrl; + var healthUrl = context.Instance?.Data?.healthUrl; + var appId = context.Instance?.Data?.appId; + + // Get ETag from instance data (from check-domain-exists response) + var eTag = context.Instance?.Data?.instanceETag?.ToString() ?? + context.Instance?.Data?.eTag?.ToString(); + + // Set instance key to domainName + // This will find the existing domain workflow instance + if (!string.IsNullOrEmpty(domainName?.ToString())) + { + directTriggerTask.SetKey(domainName.ToString()); + } + + // Set transition name (already in config, but can be set explicitly) + directTriggerTask.SetTransitionName("update"); + + // Prepare update data + // Pass updated domain information to domain workflow (schema compliant) + // Include ETag for optimistic concurrency control + directTriggerTask.SetBody(new + { + domainName = domainName, + baseUrl = baseUrl, + healthUrl = healthUrl, + appId = appId + }); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "update-domain-lifecycle-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // DirectTriggerTask returns success status + if (context.Body?.isSuccess == true) + { + return new ScriptResponse + { + Key = "domain-lifecycle-update-triggered", + Data = new + { + domainLifecycleUpdateTriggered = true, + triggeredAt = DateTime.UtcNow, + status = "DOMAIN_LIFECYCLE_UPDATE_TRIGGERED", + domainRegistration = new + { + success = true, + operation = "update", + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "lifecycle", "update", "triggered", "direct-trigger", "success" } + }; + } + else + { + return new ScriptResponse + { + Key = "domain-lifecycle-update-failed", + Data = new + { + domainLifecycleUpdateTriggered = false, + error = context.Body?.errorMessage ?? "Failed to trigger domain lifecycle update", + triggeredAt = DateTime.UtcNow, + domainRegistration = new + { + success = false, + operation = "update", + error = "Failed to update cache domain", + statusCode = context.Body?.statusCode ?? 500, + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "lifecycle", "update", "direct-trigger", "error" } + }; + } + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "domain-lifecycle-update-exception", + Data = new + { + domainLifecycleUpdateTriggered = false, + error = "Exception during domain lifecycle update trigger", + errorDescription = ex.Message, + triggeredAt = DateTime.UtcNow, + domainRegistration = new + { + success = false, + operation = "update", + error = "Exception during domain update", + errorDescription = ex.Message, + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "lifecycle", "update", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/UpdateDomainMapping.csx b/core/Workflows/discovery/src/UpdateDomainMapping.csx new file mode 100644 index 0000000..69c49cd --- /dev/null +++ b/core/Workflows/discovery/src/UpdateDomainMapping.csx @@ -0,0 +1,130 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting.Functions; +/// +/// Register Domain Mapping - Creates new domain in Redis +/// +public class RegisterDomainMapping :ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var httpTask = task as HttpTask; + if (httpTask == null) + { + throw new InvalidOperationException("Task must be an HttpTask"); + } + + var domainName = context.Instance?.Data?.domainName; + var baseUrl = context.Instance?.Data?.baseUrl; + var healthUrl = context.Instance?.Data?.healthUrl; + var appId = context.Instance?.Data?.appId; + // var flows = context.Instance?.Data?.flows; + var daprHttpPort = GetConfigValue("DAPR_HTTP_PORT"); + var daprStateStore = GetConfigValue("DAPR_STATE_STORE_NAME"); + string url="http://localhost:"+daprHttpPort+"/v1.0/state/"+daprStateStore; + httpTask.SetUrl(url); + // Prepare domain data for Dapr State Store API + // Dapr State Store expects array of state items + var stateItem = new + { + key = $"domain:{domainName}", + value = new + { + name = domainName, + baseUrl = baseUrl, + healthUrl = healthUrl, + appId = appId, + isHealthy = true, + updatedAt = DateTime.UtcNow.ToString("o"), + // flows = flows ?? new { } + } + }; + + // Set body for HTTP POST request + httpTask.SetBody(new[] { stateItem }); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "register-domain-update-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // Dapr State Store API returns 204 No Content on success + // Check HTTP status code from context + var statusCode = context.Body?.statusCode ?? 500; + var isSuccess = statusCode >= 200 && statusCode < 300; + + // Successful registration (204 No Content is success for state store) + if (isSuccess || statusCode == 204) + { + return new ScriptResponse + { + Key = "domain-cache-updated", + Data = new + { + domainRegistration = new + { + success = true, + operation = "update", + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "registered", "redis", "success" } + }; + } + // Registration failed + else + { + return new ScriptResponse + { + Key = "domain-cache-update-failed", + Data = new + { + domainRegistration = new + { + success = false, + operation = "update", + error = "Failed to update cache domain", + statusCode = statusCode, + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "update-failed", "redis", "error" } + }; + } + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "domain-update-exception", + Data = new + { + domainRegistration = new + { + success = false, + operation = "update", + error = "Exception during domain update", + errorDescription = ex.Message, + registeredAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/UpdateHealthStatusMapping.csx b/core/Workflows/discovery/src/UpdateHealthStatusMapping.csx new file mode 100644 index 0000000..b98600e --- /dev/null +++ b/core/Workflows/discovery/src/UpdateHealthStatusMapping.csx @@ -0,0 +1,171 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting.Functions; +/// +/// Update Health Status Mapping - Updates health status in Redis, preserving other fields +/// +public class UpdateHealthStatusMapping :ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + try + { + var httpTask = task as HttpTask; + if (httpTask == null) + { + throw new InvalidOperationException("Task must be an HttpTask"); + } + + var domainName = context.Instance?.Data?.domainName; + var domainData = context.Instance?.Data?.domainData; + var healthCheck = context.Instance?.Data?.healthCheck; + + // Determine health status + bool isHealthy = false; + if (healthCheck != null) + { + isHealthy = healthCheck.isHealthy == true; + } + // If no healthCheck data but we have domainData, mark as unhealthy + // This happens when health URL is missing or health check couldn't be performed + else if (domainData != null) + { + isHealthy = false; + } + // If no healthCheck and no domainData, check if we're explicitly marking as unhealthy + else if (context.Instance?.Data?.markUnhealthy == true) + { + isHealthy = false; + } + + // Merge existing domain data with health status update + var updateData = new Dictionary(); + + // Copy existing domain data to preserve all fields + if (domainData != null) + { + if (domainData.name != null) updateData["name"] = domainData.name; + if (domainData.baseUrl != null) updateData["baseUrl"] = domainData.baseUrl; + if (domainData.healthUrl != null) updateData["healthUrl"] = domainData.healthUrl; + if (domainData.appId != null) updateData["appId"] = domainData.appId; + if (domainData.flows != null) updateData["flows"] = domainData.flows; + // Preserve any other fields that might exist + foreach (var prop in domainData.GetType().GetProperties()) + { + var propName = prop.Name; + if (propName != "isHealthy" && propName != "updatedAt" && + propName != "name" && propName != "baseUrl" && + propName != "healthUrl" && propName != "appId" && propName != "flows") + { + var value = prop.GetValue(domainData); + if (value != null) + { + updateData[propName] = value; + } + } + } + } + + // Update only health-related fields + updateData["isHealthy"] = isHealthy; + updateData["updatedAt"] = DateTime.UtcNow.ToString("o"); + + // Ensure name is set + if (domainName != null) + { + updateData["name"] = domainName; + } + + // Prepare state item for Dapr State Store API + var stateItem = new + { + key = $"domain:{domainName}", + value = updateData + }; + + // Set body for HTTP POST request + httpTask.SetBody(new[] { stateItem }); + var daprHttpPort = GetConfigValue("DAPR_HTTP_PORT"); + var daprStateStore = GetConfigValue("DAPR_STATE_STORE_NAME"); + string url="http://localhost:"+daprHttpPort+"/v1.0/state/"+daprStateStore; + httpTask.SetUrl(url); + + return Task.FromResult(new ScriptResponse()); + } + catch (Exception ex) + { + return Task.FromResult(new ScriptResponse + { + Key = "update-health-status-error", + Data = new { error = ex.Message } + }); + } + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + // Dapr State Store API returns 204 No Content on success + var statusCode = context.Body?.statusCode ?? 500; + var isSuccess = statusCode >= 200 && statusCode < 300; + + // Successful update (204 No Content is success for state store) + if (isSuccess || statusCode == 204) + { + return new ScriptResponse + { + Key = "health-status-updated", + Data = new + { + healthStatusUpdate = new + { + success = true, + updatedAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "health-check", "updated", "redis", "success" } + }; + } + // Update failed + else + { + return new ScriptResponse + { + Key = "health-status-update-failed", + Data = new + { + healthStatusUpdate = new + { + success = false, + error = "Failed to update health status", + statusCode = statusCode, + updatedAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "health-check", "update-failed", "redis", "error" } + }; + } + } + catch (Exception ex) + { + return new ScriptResponse + { + Key = "health-status-update-exception", + Data = new + { + healthStatusUpdate = new + { + success = false, + error = "Exception during health status update", + errorDescription = ex.Message, + updatedAt = DateTime.UtcNow + } + }, + Tags = new[] { "domain", "health-check", "exception", "error" } + }; + } + } +} + diff --git a/core/Workflows/discovery/src/UpdateSuccessRule.csx b/core/Workflows/discovery/src/UpdateSuccessRule.csx new file mode 100644 index 0000000..b8858c6 --- /dev/null +++ b/core/Workflows/discovery/src/UpdateSuccessRule.csx @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Update Success Rule - Checks if domain update was successful +/// +public class UpdateSuccessRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var domainRegistration = context.Instance.Data.domainRegistration; + + if (domainRegistration == null) + return false; + + // Check if update was successful and operation is "update" + return domainRegistration.success == true && + domainRegistration.operation?.ToString() == "update"; + } + catch (Exception) + { + return false; + } + } +} + diff --git a/core/Workflows/discovery/src/UpsertFailureRule.csx b/core/Workflows/discovery/src/UpsertFailureRule.csx new file mode 100644 index 0000000..5f8d50c --- /dev/null +++ b/core/Workflows/discovery/src/UpsertFailureRule.csx @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Upsert Failure Rule - Checks if domain registration/update failed +/// +public class UpsertFailureRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return true; // If no data, consider it a failure + + var domainRegistration = context.Instance.Data.domainRegistration; + + if (domainRegistration == null) + return true; // If no registration result, consider it a failure + + return domainRegistration.success == false; + } + catch (Exception) + { + return true; // On error, consider it a failure + } + } +} + + + diff --git a/core/Workflows/discovery/src/UpsertSuccessRule.csx b/core/Workflows/discovery/src/UpsertSuccessRule.csx new file mode 100644 index 0000000..4753318 --- /dev/null +++ b/core/Workflows/discovery/src/UpsertSuccessRule.csx @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Upsert Success Rule - Checks if domain registration/update was successful +/// +public class UpsertSuccessRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + try + { + if (context?.Instance?.Data == null) + return false; + + var domainRegistration = context.Instance.Data.domainRegistration; + + if (domainRegistration == null) + return false; + + return domainRegistration.success == true; + } + catch (Exception) + { + return false; + } + } +} + + + diff --git a/core/Workflows/error-boundary/.meta/test-error-boundary-flow.diagram.json b/core/Workflows/error-boundary/.meta/test-error-boundary-flow.diagram.json new file mode 100644 index 0000000..f861ecb --- /dev/null +++ b/core/Workflows/error-boundary/.meta/test-error-boundary-flow.diagram.json @@ -0,0 +1,32 @@ +{ + "nodePos": { + "idle": { + "x": 420, + "y": 340 + }, + "conflict-handled": { + "x": 1200, + "y": 40 + }, + "not-found-handled": { + "x": 1220, + "y": 280 + }, + "validation-handled": { + "x": 1200, + "y": 460 + }, + "failure-handled": { + "x": 1180, + "y": 640 + }, + "error-sink": { + "x": 100, + "y": 100 + }, + "__start__": { + "x": 100, + "y": 340 + } + } +} \ No newline at end of file diff --git a/core/Workflows/error-boundary/src/Trigger400Mapping.csx b/core/Workflows/error-boundary/src/Trigger400Mapping.csx new file mode 100644 index 0000000..850847c --- /dev/null +++ b/core/Workflows/error-boundary/src/Trigger400Mapping.csx @@ -0,0 +1,46 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; + +/// +/// Trigger400Mapping - Starts a workflow that has schema validation with an empty body. +/// Missing required fields cause the runtime to return 400 Validation, +/// caught by errorCode "Task:400". +/// +public class Trigger400Mapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + var startTask = task as StartTask; + if (startTask == null) + throw new InvalidOperationException("Task must be a StartTask"); + + startTask.SetDomain("core"); + startTask.SetFlow("account-opening-workflow"); + startTask.SetKey(Guid.NewGuid().ToString()); + startTask.SetSync(false); + // Empty body → schema required fields are missing → Validation 400 + startTask.SetBody(new { }); + + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + return new ScriptResponse + { + Key = "trigger-400-handled", + Data = new + { + validationTestResult = new + { + errorCode = "Task:400", + action = "Ignore", + handledAt = DateTime.UtcNow + } + }, + Tags = new[] { "error-boundary-test", "validation", "400" } + }; + } +} diff --git a/core/Workflows/error-boundary/src/Trigger404Mapping.csx b/core/Workflows/error-boundary/src/Trigger404Mapping.csx new file mode 100644 index 0000000..cfcc9d3 --- /dev/null +++ b/core/Workflows/error-boundary/src/Trigger404Mapping.csx @@ -0,0 +1,43 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; + +/// +/// Trigger404Mapping - Retrieves a deliberately nonexistent instance (dead UUID). +/// The runtime returns 404 NotFound, caught by errorCode "Task:404". +/// +public class Trigger404Mapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + var getTask = task as GetInstanceDataTask; + if (getTask == null) + throw new InvalidOperationException("Task must be a GetInstanceDataTask"); + + getTask.SetDomain("core"); + getTask.SetFlow("task-test-subflow"); + // Nonexistent instance → 404 NotFound + getTask.SetInstance("00000000-dead-beef-0000-000000000000"); + + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + return new ScriptResponse + { + Key = "trigger-404-handled", + Data = new + { + notFoundTestResult = new + { + errorCode = "Task:404", + action = "Ignore", + handledAt = DateTime.UtcNow + } + }, + Tags = new[] { "error-boundary-test", "not-found", "404" } + }; + } +} \ No newline at end of file diff --git a/core/Workflows/error-boundary/src/Trigger409Mapping.csx b/core/Workflows/error-boundary/src/Trigger409Mapping.csx new file mode 100644 index 0000000..7d47389 --- /dev/null +++ b/core/Workflows/error-boundary/src/Trigger409Mapping.csx @@ -0,0 +1,45 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; + +/// +/// Trigger409Mapping - Starts a workflow instance with a fixed key. +/// On the second call the runtime returns 409 Conflict, which the +/// task-level ErrorBoundary catches via errorCode "Task:409". +/// +public class Trigger409Mapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + var startTask = task as StartTask; + if (startTask == null) + throw new InvalidOperationException("Task must be a StartTask"); + + startTask.SetDomain("core"); + startTask.SetFlow("task-test-subflow"); + startTask.SetKey("fixed-eb-409-key"); + startTask.SetSync(false); + startTask.SetBody(new { source = "error-boundary-409-test" }); + + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + return new ScriptResponse + { + Key = "trigger-409-handled", + Data = new + { + conflictTestResult = new + { + errorCode = "Task:409", + action = "Ignore", + handledAt = DateTime.UtcNow + } + }, + Tags = new[] { "error-boundary-test", "conflict", "409" } + }; + } +} diff --git a/core/Workflows/error-boundary/src/Trigger500Mapping.csx b/core/Workflows/error-boundary/src/Trigger500Mapping.csx new file mode 100644 index 0000000..bc83137 --- /dev/null +++ b/core/Workflows/error-boundary/src/Trigger500Mapping.csx @@ -0,0 +1,48 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; + +/// +/// Trigger500Mapping - Triggers a nonexistent transition on a nil-UUID instance. +/// The runtime returns 500 Failure (invalid state/transition), +/// caught by errorCode "Task:500". A wildcard fallback aborts to "error-sink". +/// +public class Trigger500Mapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + var directTrigger = task as DirectTriggerTask; + if (directTrigger == null) + throw new InvalidOperationException("Task must be a DirectTriggerTask"); + + directTrigger.SetDomain("core"); + directTrigger.SetFlow("task-test-subflow"); + directTrigger.SetTransitionName("nonexistent-transition"); + // Nil UUID → instance not found or invalid state → 500 + directTrigger.SetInstance("00000000-0000-0000-0000-000000000000"); + directTrigger.SetKey(Guid.NewGuid().ToString()); + directTrigger.SetSync(false); + directTrigger.SetBody(new { source = "error-boundary-500-test" }); + + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + return new ScriptResponse + { + Key = "trigger-500-handled", + Data = new + { + failureTestResult = new + { + errorCode = "Task:500", + action = "Ignore", + handledAt = DateTime.UtcNow + } + }, + Tags = new[] { "error-boundary-test", "failure", "500" } + }; + } +} \ No newline at end of file diff --git a/core/Workflows/error-boundary/test-error-boundary-flow.http b/core/Workflows/error-boundary/test-error-boundary-flow.http new file mode 100644 index 0000000..0bfcd63 --- /dev/null +++ b/core/Workflows/error-boundary/test-error-boundary-flow.http @@ -0,0 +1,87 @@ +### ============================================================== +### Test Error Boundary Flow - HTTP Test File +### ============================================================== +### Her transition organik olarak farklı bir statusCode üretir: +### trigger-409 → StartTask + fixed key → 409 Conflict → Ignore +### trigger-404 → GetInstanceData + dead UUID → 404 NotFound → Ignore +### trigger-400 → StartTask + empty body → 400 Validation → Ignore +### trigger-500 → DirectTrigger + nil UUID → 500 Failure → Ignore / Abort→error-sink +### +### Debug için MapLocalResultToInvocationResult'a breakpoint koy ve +### TaskExecutionEngine'deki errorCode match mantığını adım adım izle. +### ============================================================== + +@baseUrl = http://localhost:4201 +@apiVersion = 1 +@domain = core +@workflow = test-error-boundary-flow +@instanceKey = eb-flow-test-{{$timestamp}} + +### ============================================================== +### STEP 1: Start instance → idle state +### ============================================================== + +POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start +Content-Type: application/json + +{ + "key": "{{instanceKey}}", + "tags": ["error-boundary-test", "statuscode-test"] +} + +### ============================================================== +### STEP 2: Get current state +### ============================================================== + +GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state + +### ============================================================== +### SCENARIO A: trigger-409 — Conflict +### Önce task-test-subflow "fixed-eb-409-key" ile başlatılmış olmalı. +### İkinci tetiklemede 409 üretilir; Task:409 → Ignore → conflict-handled +### ============================================================== + +PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/trigger-409 +Content-Type: application/json + +{} + +### ============================================================== +### SCENARIO B: trigger-404 — Not Found +### Dead UUID (00000000-dead-beef-...) ile GetInstanceData çağrılır. +### 404 üretilir; Task:404 → Ignore → not-found-handled +### ============================================================== + +PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/trigger-404 +Content-Type: application/json + +{} + +### ============================================================== +### SCENARIO C: trigger-400 — Validation +### account-opening-workflow'a boş body ile StartTask çağrılır. +### 400 üretilir; Task:400 → Ignore → validation-handled +### ============================================================== + +PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/trigger-400 +Content-Type: application/json + +{} + +### ============================================================== +### SCENARIO D: trigger-500 — Failure +### Nil UUID instance üzerinde geçersiz transition tetiklenir. +### 500 üretilir; Task:500 → Ignore (logOnly) → failure-handled +### Eğer Task:500 match etmezse wildcard (*) → Abort → error-sink +### ============================================================== + +PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/trigger-500 +Content-Type: application/json + +{} + +### ============================================================== +### MONITORING: Final instance data +### ============================================================== + +GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data diff --git a/core/Workflows/error-boundary/test-error-boundary-flow.json b/core/Workflows/error-boundary/test-error-boundary-flow.json new file mode 100644 index 0000000..dbaebb6 --- /dev/null +++ b/core/Workflows/error-boundary/test-error-boundary-flow.json @@ -0,0 +1,391 @@ +{ + "key": "test-error-boundary-flow", + "flow": "sys-flows", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "error-boundary", + "test", + "statuscode", + "trigger-task", + "conflict", + "not-found", + "validation", + "failure" + ], + "attributes": { + "type": "F", + "timeout": null, + "labels": [ + { + "language": "en-US", + "label": "Test Error Boundary Flow" + }, + { + "language": "tr-TR", + "label": "ErrorBoundary Test Akışı" + } + ], + "functions": [], + "features": [], + "extensions": [], + "sharedTransitions": [], + "errorBoundary": { + "onError": [ + { + "action": 5, + "priority": 1000, + "logOnly": true + } + ] + }, + "startTransition": { + "key": "start", + "target": "idle", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Start" + }, + { + "language": "tr-TR", + "label": "Başlat" + } + ], + "onExecutionTasks": [] + }, + "states": [ + { + "key": "idle", + "stateType": 1, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Idle - Select Test Scenario" + }, + { + "language": "tr-TR", + "label": "Beklemede - Test Senaryosu Seçin" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "trigger-409", + "target": "conflict-handled", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test Conflict (409)" + }, + { + "language": "tr-TR", + "label": "Çakışma Testi (409)" + } + ], + "schema": null, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "test-start-workflow", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/Trigger409Mapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUcmlnZ2VyNDA5TWFwcGluZyAtIFN0YXJ0cyBhIHdvcmtmbG93IGluc3RhbmNlIHdpdGggYSBmaXhlZCBrZXkuCi8vLyBPbiB0aGUgc2Vjb25kIGNhbGwgdGhlIHJ1bnRpbWUgcmV0dXJucyA0MDkgQ29uZmxpY3QsIHdoaWNoIHRoZQovLy8gdGFzay1sZXZlbCBFcnJvckJvdW5kYXJ5IGNhdGNoZXMgdmlhIGVycm9yQ29kZSAiVGFzazo0MDkiLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgVHJpZ2dlcjQwOU1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIHN0YXJ0VGFzayA9IHRhc2sgYXMgU3RhcnRUYXNrOwogICAgICAgIGlmIChzdGFydFRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIFN0YXJ0VGFzayIpOwoKICAgICAgICBzdGFydFRhc2suU2V0RG9tYWluKCJjb3JlIik7CiAgICAgICAgc3RhcnRUYXNrLlNldEZsb3coInRhc2stdGVzdC1zdWJmbG93Iik7CiAgICAgICAgc3RhcnRUYXNrLlNldEtleSgiZml4ZWQtZWItNDA5LWtleSIpOwogICAgICAgIHN0YXJ0VGFzay5TZXRTeW5jKGZhbHNlKTsKICAgICAgICBzdGFydFRhc2suU2V0Qm9keShuZXcgeyBzb3VyY2UgPSAiZXJyb3ItYm91bmRhcnktNDA5LXRlc3QiIH0pOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInRyaWdnZXItNDA5LWhhbmRsZWQiLAogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbmZsaWN0VGVzdFJlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9ICJUYXNrOjQwOSIsCiAgICAgICAgICAgICAgICAgICAgYWN0aW9uID0gIklnbm9yZSIsCiAgICAgICAgICAgICAgICAgICAgaGFuZGxlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJlcnJvci1ib3VuZGFyeS10ZXN0IiwgImNvbmZsaWN0IiwgIjQwOSIgfQogICAgICAgIH07CiAgICB9Cn0K" + }, + "errorBoundary": { + "onError": [ + { + "action": 3, + "errorCodes": [ + "409" + ], + "priority": 1, + "logOnly": true + } + ] + } + } + ] + }, + { + "key": "trigger-404", + "target": "not-found-handled", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test Not Found (404)" + }, + { + "language": "tr-TR", + "label": "Bulunamadı Testi (404)" + } + ], + "schema": null, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "test-get-instance-data", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/Trigger404Mapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUcmlnZ2VyNDA0TWFwcGluZyAtIFJldHJpZXZlcyBhIGRlbGliZXJhdGVseSBub25leGlzdGVudCBpbnN0YW5jZSAoZGVhZCBVVUlEKS4KLy8vIFRoZSBydW50aW1lIHJldHVybnMgNDA0IE5vdEZvdW5kLCBjYXVnaHQgYnkgZXJyb3JDb2RlICJUYXNrOjQwNCIuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBUcmlnZ2VyNDA0TWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgZ2V0VGFzayA9IHRhc2sgYXMgR2V0SW5zdGFuY2VEYXRhVGFzazsKICAgICAgICBpZiAoZ2V0VGFzayA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgR2V0SW5zdGFuY2VEYXRhVGFzayIpOwoKICAgICAgICBnZXRUYXNrLlNldERvbWFpbigiY29yZSIpOwogICAgICAgIGdldFRhc2suU2V0RmxvdygidGFzay10ZXN0LXN1YmZsb3ciKTsKICAgICAgICAvLyBOb25leGlzdGVudCBpbnN0YW5jZSDihpIgNDA0IE5vdEZvdW5kCiAgICAgICAgZ2V0VGFzay5TZXRJbnN0YW5jZSgiMDAwMDAwMDAtZGVhZC1iZWVmLTAwMDAtMDAwMDAwMDAwMDAwIik7CgogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBLZXkgPSAidHJpZ2dlci00MDQtaGFuZGxlZCIsCiAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbm90Rm91bmRUZXN0UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gIlRhc2s6NDA0IiwKICAgICAgICAgICAgICAgICAgICBhY3Rpb24gPSAiSWdub3JlIiwKICAgICAgICAgICAgICAgICAgICBoYW5kbGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImVycm9yLWJvdW5kYXJ5LXRlc3QiLCAibm90LWZvdW5kIiwgIjQwNCIgfQogICAgICAgIH07CiAgICB9Cn0=" + }, + "errorBoundary": { + "onError": [ + { + "action": 1, + "errorCodes": [ + "404" + ], + "priority": 1, + "retryPolicy": { + "maxRetries": 3, + "initialDelay": "PT2S", + "backoffType": 1, + "backoffMultiplier": 2, + "maxDelay": "PT6S" + } + } + ] + } + } + ] + }, + { + "key": "trigger-400", + "target": "validation-handled", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test Validation (400)" + }, + { + "language": "tr-TR", + "label": "Doğrulama Testi (400)" + } + ], + "schema": null, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "test-start-workflow", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/Trigger400Mapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUcmlnZ2VyNDAwTWFwcGluZyAtIFN0YXJ0cyBhIHdvcmtmbG93IHRoYXQgaGFzIHNjaGVtYSB2YWxpZGF0aW9uIHdpdGggYW4gZW1wdHkgYm9keS4KLy8vIE1pc3NpbmcgcmVxdWlyZWQgZmllbGRzIGNhdXNlIHRoZSBydW50aW1lIHRvIHJldHVybiA0MDAgVmFsaWRhdGlvbiwKLy8vIGNhdWdodCBieSBlcnJvckNvZGUgIlRhc2s6NDAwIi4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFRyaWdnZXI0MDBNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBzdGFydFRhc2sgPSB0YXNrIGFzIFN0YXJ0VGFzazsKICAgICAgICBpZiAoc3RhcnRUYXNrID09IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYSBTdGFydFRhc2siKTsKCiAgICAgICAgc3RhcnRUYXNrLlNldERvbWFpbigiY29yZSIpOwogICAgICAgIHN0YXJ0VGFzay5TZXRGbG93KCJhY2NvdW50LW9wZW5pbmctd29ya2Zsb3ciKTsKICAgICAgICBzdGFydFRhc2suU2V0S2V5KEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCkpOwogICAgICAgIHN0YXJ0VGFzay5TZXRTeW5jKGZhbHNlKTsKICAgICAgICAvLyBFbXB0eSBib2R5IOKGkiBzY2hlbWEgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nIOKGkiBWYWxpZGF0aW9uIDQwMAogICAgICAgIHN0YXJ0VGFzay5TZXRCb2R5KG5ldyB7IH0pOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInRyaWdnZXItNDAwLWhhbmRsZWQiLAogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhbGlkYXRpb25UZXN0UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gIlRhc2s6NDAwIiwKICAgICAgICAgICAgICAgICAgICBhY3Rpb24gPSAiSWdub3JlIiwKICAgICAgICAgICAgICAgICAgICBoYW5kbGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImVycm9yLWJvdW5kYXJ5LXRlc3QiLCAidmFsaWRhdGlvbiIsICI0MDAiIH0KICAgICAgICB9OwogICAgfQp9Cg==" + }, + "errorBoundary": { + "onError": [ + { + "action": 0, + "errorCodes": [ + "400" + ], + "priority": 1, + "logOnly": true + } + ] + } + } + ] + }, + { + "key": "trigger-500", + "target": "failure-handled", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Test Failure (500)" + }, + { + "language": "tr-TR", + "label": "Hata Testi (500)" + } + ], + "schema": null, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "test-direct-transition", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/Trigger500Mapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUcmlnZ2VyNTAwTWFwcGluZyAtIFRyaWdnZXJzIGEgbm9uZXhpc3RlbnQgdHJhbnNpdGlvbiBvbiBhIG5pbC1VVUlEIGluc3RhbmNlLgovLy8gVGhlIHJ1bnRpbWUgcmV0dXJucyA1MDAgRmFpbHVyZSAoaW52YWxpZCBzdGF0ZS90cmFuc2l0aW9uKSwKLy8vIGNhdWdodCBieSBlcnJvckNvZGUgIlRhc2s6NTAwIi4gQSB3aWxkY2FyZCBmYWxsYmFjayBhYm9ydHMgdG8gImVycm9yLXNpbmsiLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgVHJpZ2dlcjUwME1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIGRpcmVjdFRyaWdnZXIgPSB0YXNrIGFzIERpcmVjdFRyaWdnZXJUYXNrOwogICAgICAgIGlmIChkaXJlY3RUcmlnZ2VyID09IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYSBEaXJlY3RUcmlnZ2VyVGFzayIpOwoKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldERvbWFpbigiY29yZSIpOwogICAgICAgIGRpcmVjdFRyaWdnZXIuU2V0RmxvdygidGFzay10ZXN0LXN1YmZsb3ciKTsKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldFRyYW5zaXRpb25OYW1lKCJub25leGlzdGVudC10cmFuc2l0aW9uIik7CiAgICAgICAgLy8gTmlsIFVVSUQg4oaSIGluc3RhbmNlIG5vdCBmb3VuZCBvciBpbnZhbGlkIHN0YXRlIOKGkiA1MDAKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldEluc3RhbmNlKCIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAiKTsKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldEtleShHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpKTsKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldFN5bmMoZmFsc2UpOwogICAgICAgIGRpcmVjdFRyaWdnZXIuU2V0Qm9keShuZXcgeyBzb3VyY2UgPSAiZXJyb3ItYm91bmRhcnktNTAwLXRlc3QiIH0pOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInRyaWdnZXItNTAwLWhhbmRsZWQiLAogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZhaWx1cmVUZXN0UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gIlRhc2s6NTAwIiwKICAgICAgICAgICAgICAgICAgICBhY3Rpb24gPSAiSWdub3JlIiwKICAgICAgICAgICAgICAgICAgICBoYW5kbGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImVycm9yLWJvdW5kYXJ5LXRlc3QiLCAiZmFpbHVyZSIsICI1MDAiIH0KICAgICAgICB9OwogICAgfQp9" + }, + "errorBoundary": { + "onError": [ + { + "action": 3, + "errorCodes": [ + "500" + ], + "priority": 1, + "logOnly": true + }, + { + "action": 0, + "errorCodes": [ + "*" + ], + "priority": 999 + } + ] + } + } + ] + } + ] + }, + { + "key": "conflict-handled", + "stateType": 3, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Conflict Handled (409)" + }, + { + "language": "tr-TR", + "label": "Çakışma Yakalandı (409)" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + }, + { + "key": "not-found-handled", + "stateType": 3, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Not Found Handled (404)" + }, + { + "language": "tr-TR", + "label": "Bulunamadı Yakalandı (404)" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + }, + { + "key": "validation-handled", + "stateType": 3, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Validation Handled (400)" + }, + { + "language": "tr-TR", + "label": "Doğrulama Yakalandı (400)" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + }, + { + "key": "failure-handled", + "stateType": 3, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Failure Handled (500)" + }, + { + "language": "tr-TR", + "label": "Hata Yakalandı (500)" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + }, + { + "key": "error-sink", + "stateType": 3, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Error Sink (Unhandled)" + }, + { + "language": "tr-TR", + "label": "Hata Havuzu (Yakalanmadı)" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + } + ] + } +} \ No newline at end of file diff --git a/core/Workflows/morph-touch/absence-entry.json b/core/Workflows/morph-touch/absence-entry.json new file mode 100644 index 0000000..b3b148f --- /dev/null +++ b/core/Workflows/morph-touch/absence-entry.json @@ -0,0 +1,146 @@ +{ + "key": "absence-entry", + "flow": "sys-flows", + "domain": "core", + "version": "1.0.0", + "flowVersion": "1.0.0", + "tags": [ + "new" + ], + "attributes": { + "type": "S", + "labels": [ + { + "label": "Absence Entry", + "language": "en-US" + }, + { + "label": "Yokluk Kaydı", + "language": "tr-TR" + } + ], + "functions": [], + "features": [], + "extensions": [], + "cancel": { + "key": "cancel", + "target": "cancelled", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "label": "Cancel", + "language": "en-US" + }, + { + "label": "İptal Et", + "language": "tr-TR" + } + ] + }, + "startTransition": { + "key": "start", + "target": "complete", + "versionStrategy": "Major", + "triggerType": 0, + "labels": [ + { + "label": "Start", + "language": "en-US" + }, + { + "label": "Başla", + "language": "tr-TR" + } + ], + "onExecutionTasks": [] + }, + "states": [ + { + "key": "complete", + "stateType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "label": "Complete", + "language": "en-US" + }, + { + "label": "Tamamlandı", + "language": "tr-TR" + } + ], + "transitions": [ + { + "key": "update", + "target": "complete", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "label": "Update", + "language": "en-US" + }, + { + "label": "Güncelle", + "language": "tr-TR" + } + ] + }, + { + "key": "start-transfer", + "target": "complete", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "label": "Start Transfer", + "language": "en-US" + }, + { + "label": "Transferi Başlat", + "language": "tr-TR" + } + ], + "rule": { + "location": "./src/CanStartTransferMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIENvbmRpdGlvbiBmb3IgY2hlY2stdGltZTogc3RhdGU9YWN0aXZlIC0+IGNyZWF0ZS1yb29tLWFuZC10cmlnZ2VyLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgQ2FuU3RhcnRUcmFuc2Zlck1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgYWJzZW5jZVR5cGUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5hYnNlbmNlVHlwZT8uVG9TdHJpbmcoKT8uVHJpbSgpOwogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQoYWJzZW5jZVR5cGUgPT0gInBlcnNvbmVsLWxlYXZlIik7CiAgICB9Cn0=" + }, + "onExecutionTasks": [ + { + "order": 1, + "task": { + "domain": "core", + "flow": "sys-tasks", + "key": "start-transfer-from-absence-entry", + "version": "1.0.0" + }, + "mapping": { + "location": "./src/StartTransferFromAbsenceEntryMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CgovLy8gPHN1bW1hcnk+Ci8vLyBNYXBwaW5nIGZvciBzdGFydC10cmFuc2Zlci1mcm9tLWFic2VuY2UtZW50cnkgU3RhcnRUYXNrIChUeXBlIDExKS4KLy8vIENvbmRpdGlvbmFsbHkgc3RhcnRzIGEgcmV6ZXJ2YXRpb24tdHJhbnNmZXIgc3ViZmxvdyB3aGVuIGFic2VuY2VUeXBlIGlzIHBlcnNvbmFsLWxlYXZlLgovLy8gRGV0ZXJtaW5lcyB0cmFuc2ZlciB0eXBlOiBhbm51YWwtbGVhdmUgKGVuZERhdGVUaW1lIHByZXNlbnQpIG9yIHRlcm1pbmF0aW9uIChlbmREYXRlVGltZSBudWxsKS4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFN0YXJ0VHJhbnNmZXJGcm9tQWJzZW5jZUVudHJ5TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgc3RhcnRUYXNrID0gdGFzayBhcyBTdGFydFRhc2s7CiAgICAgICAgaWYgKHN0YXJ0VGFzayA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgU3RhcnRUYXNrIik7CgogICAgICAgIHZhciBkYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKICAgICAgICBpZiAoZGF0YSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSB7IERhdGEgPSBuZXcgeyBza2lwcGVkID0gdHJ1ZSwgcmVhc29uID0gIm5vLWluc3RhbmNlLWRhdGEiIH0gfSk7CgogICAgICAgIHZhciBhYnNlbmNlVHlwZSA9IEdldFN0cmluZyhkYXRhLCAiYWJzZW5jZVR5cGUiKTsKICAgICAgICBpZiAoYWJzZW5jZVR5cGUgIT0gInBlcnNvbmFsLWxlYXZlIikKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UgeyBEYXRhID0gbmV3IHsgc2tpcHBlZCA9IHRydWUsIHJlYXNvbiA9ICJub3QtcGVyc29uYWwtbGVhdmUiIH0gfSk7CgogICAgICAgIHZhciBhZHZpc29yID0gR2V0U3RyaW5nKGRhdGEsICJhZHZpc29yIik7CiAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGFkdmlzb3IpKQogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSB7IERhdGEgPSBuZXcgeyBza2lwcGVkID0gdHJ1ZSwgcmVhc29uID0gIm5vLWFkdmlzb3IiIH0gfSk7CgogICAgICAgIHZhciBzdGFydERhdGVUaW1lID0gR2V0U3RyaW5nKGRhdGEsICJzdGFydERhdGVUaW1lIik7CiAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KHN0YXJ0RGF0ZVRpbWUpKQogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSB7IERhdGEgPSBuZXcgeyBza2lwcGVkID0gdHJ1ZSwgcmVhc29uID0gIm5vLXN0YXJ0RGF0ZVRpbWUiIH0gfSk7CgogICAgICAgIHZhciBlbmREYXRlVGltZSA9IEdldFN0cmluZyhkYXRhLCAiZW5kRGF0ZVRpbWUiKTsKCiAgICAgICAgdmFyIGFkdmlzb3JUeXBlID0gRXh0cmFjdEFkdmlzb3JUeXBlKGFkdmlzb3IpOwogICAgICAgIHZhciB0cmFuc2ZlclR5cGUgPSBzdHJpbmcuSXNOdWxsT3JFbXB0eShlbmREYXRlVGltZSkgPyAidGVybWluYXRpb24iIDogImFubnVhbC1sZWF2ZSI7CgogICAgICAgIHZhciBzYWZlU3RhcnQgPSBzdGFydERhdGVUaW1lLlJlcGxhY2UoIjoiLCAiLSIpOwogICAgICAgIHZhciB0cmFuc2ZlcktleSA9ICQidHJhbnNmZXItbGVhdmUte2Fkdmlzb3J9LXtzYWZlU3RhcnR9IjsKCiAgICAgICAgc3RhcnRUYXNrLlNldERvbWFpbigidG91Y2giKTsKICAgICAgICBzdGFydFRhc2suU2V0RmxvdygicmV6ZXJ2YXRpb24tdHJhbnNmZXIiKTsKICAgICAgICBzdGFydFRhc2suU2V0S2V5KHRyYW5zZmVyS2V5KTsKCiAgICAgICAgdmFyIGJvZHkgPSBuZXcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD4KICAgICAgICB7CiAgICAgICAgICAgIFsic291cmNlQWR2aXNvcklkIl0gPSBhZHZpc29yLAogICAgICAgICAgICBbImFkdmlzb3JUeXBlIl0gPSBhZHZpc29yVHlwZSwKICAgICAgICAgICAgWyJzdGFydERhdGUiXSA9IHN0YXJ0RGF0ZVRpbWUKICAgICAgICB9OwogICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkoZW5kRGF0ZVRpbWUpKQogICAgICAgICAgICBib2R5WyJlbmREYXRlIl0gPSBlbmREYXRlVGltZTsKCiAgICAgICAgc3RhcnRUYXNrLlNldEJvZHkoYm9keSk7CgogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBEYXRhID0gbmV3IHsgc2tpcHBlZCA9IGZhbHNlLCB0cmFuc2ZlclR5cGUsIHRyYW5zZmVyS2V5IH0KICAgICAgICB9KTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdHJpbmcgRXh0cmFjdEFkdmlzb3JUeXBlKHN0cmluZyBhZHZpc29yKQogICAgewogICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShhZHZpc29yKSkgcmV0dXJuIG51bGw7CiAgICAgICAgdmFyIHBhcnRzID0gYWR2aXNvci5TcGxpdCgnLicpOwogICAgICAgIGlmIChwYXJ0cy5MZW5ndGggPj0gMykKICAgICAgICAgICAgcmV0dXJuIHBhcnRzWzFdOwogICAgICAgIGlmIChwYXJ0cy5MZW5ndGggPT0gMikKICAgICAgICAgICAgcmV0dXJuIHBhcnRzWzBdOwogICAgICAgIHJldHVybiBhZHZpc29yOwogICAgfQoKICAgIHByaXZhdGUgc3RyaW5nIEdldFN0cmluZyhkeW5hbWljIG9iaiwgc3RyaW5nIG5hbWUpCiAgICB7CiAgICAgICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChIYXNQcm9wZXJ0eShvYmosIG5hbWUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgdiA9IEdldFByb3BlcnR5VmFsdWUob2JqLCBuYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiB2Py5Ub1N0cmluZygpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNhdGNoIHsgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9" + } + } + ] + } + ] + }, + { + "key": "cancelled", + "stateType": 3, + "versionStrategy": "Minor", + "labels": [ + { + "label": "Cancelled", + "language": "en-US" + }, + { + "label": "İptal Edildi", + "language": "tr-TR" + } + ] + } + ], + "subFlowType": "S", + "timeout": null + } +} \ No newline at end of file diff --git a/core/Workflows/morph-touch/src/CanStartTransferMapping.csx b/core/Workflows/morph-touch/src/CanStartTransferMapping.csx new file mode 100644 index 0000000..c7a1348 --- /dev/null +++ b/core/Workflows/morph-touch/src/CanStartTransferMapping.csx @@ -0,0 +1,14 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Condition for check-time: state=active -> create-room-and-trigger. +/// +public class CanStartTransferMapping : ScriptBase, IConditionMapping +{ + public Task Handler(ScriptContext context) + { + var absenceType = context.Instance?.Data?.absenceType?.ToString()?.Trim(); + return Task.FromResult(absenceType == "personel-leave"); + } +} \ No newline at end of file diff --git a/core/Workflows/morph-touch/src/StartTransferFromAbsenceEntryMapping.csx b/core/Workflows/morph-touch/src/StartTransferFromAbsenceEntryMapping.csx new file mode 100644 index 0000000..c5fe260 --- /dev/null +++ b/core/Workflows/morph-touch/src/StartTransferFromAbsenceEntryMapping.csx @@ -0,0 +1,94 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Mapping for start-transfer-from-absence-entry StartTask (Type 11). +/// Conditionally starts a rezervation-transfer subflow when absenceType is personal-leave. +/// Determines transfer type: annual-leave (endDateTime present) or termination (endDateTime null). +/// +public class StartTransferFromAbsenceEntryMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + var startTask = task as StartTask; + if (startTask == null) + throw new InvalidOperationException("Task must be a StartTask"); + + var data = context.Instance?.Data; + if (data == null) + return Task.FromResult(new ScriptResponse { Data = new { skipped = true, reason = "no-instance-data" } }); + + var absenceType = GetString(data, "absenceType"); + if (absenceType != "personal-leave") + return Task.FromResult(new ScriptResponse { Data = new { skipped = true, reason = "not-personal-leave" } }); + + var advisor = GetString(data, "advisor"); + if (string.IsNullOrEmpty(advisor)) + return Task.FromResult(new ScriptResponse { Data = new { skipped = true, reason = "no-advisor" } }); + + var startDateTime = GetString(data, "startDateTime"); + if (string.IsNullOrEmpty(startDateTime)) + return Task.FromResult(new ScriptResponse { Data = new { skipped = true, reason = "no-startDateTime" } }); + + var endDateTime = GetString(data, "endDateTime"); + + var advisorType = ExtractAdvisorType(advisor); + var transferType = string.IsNullOrEmpty(endDateTime) ? "termination" : "annual-leave"; + + var safeStart = startDateTime.Replace(":", "-"); + var transferKey = $"transfer-leave-{advisor}-{safeStart}"; + + startTask.SetDomain("touch"); + startTask.SetFlow("rezervation-transfer"); + startTask.SetKey(transferKey); + + var body = new System.Collections.Generic.Dictionary + { + ["sourceAdvisorId"] = advisor, + ["advisorType"] = advisorType, + ["startDate"] = startDateTime + }; + if (!string.IsNullOrEmpty(endDateTime)) + body["endDate"] = endDateTime; + + startTask.SetBody(body); + + return Task.FromResult(new ScriptResponse + { + Data = new { skipped = false, transferType, transferKey } + }); + } + + public Task OutputHandler(ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + private string ExtractAdvisorType(string advisor) + { + if (string.IsNullOrEmpty(advisor)) return null; + var parts = advisor.Split('.'); + if (parts.Length >= 3) + return parts[1]; + if (parts.Length == 2) + return parts[0]; + return advisor; + } + + private string GetString(dynamic obj, string name) + { + if (obj == null) return null; + try + { + if (HasProperty(obj, name)) + { + var v = GetPropertyValue(obj, name); + return v?.ToString(); + } + } + catch { } + return null; + } +} \ No newline at end of file diff --git a/core/Workflows/self-loop-repro/self-loop-repro-workflow.json b/core/Workflows/self-loop-repro/self-loop-repro-workflow.json new file mode 100644 index 0000000..704ea73 --- /dev/null +++ b/core/Workflows/self-loop-repro/self-loop-repro-workflow.json @@ -0,0 +1,252 @@ +{ + "key": "self-loop-repro-workflow", + "flow": "sys-flows", + "flowVersion": "1.0.0", + "domain": "core", + "version": "1.0.0", + "tags": [ + "self-loop-repro", + "auto-transition", + "target-self", + "rule-invalidation", + "repro" + ], + "attributes": { + "type": "F", + "timeout": null, + "labels": [ + { + "language": "en-US", + "label": "Self-Loop Rule Invalidation Repro Workflow" + }, + { + "language": "tr-TR", + "label": "Self-Loop Kural Geçersizleştirme Repro Akışı" + } + ], + "functions": [], + "features": [], + "extensions": [], + "sharedTransitions": [], + "startTransition": { + "key": "start", + "target": "entry-state", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Start" + }, + { + "language": "tr-TR", + "label": "Başlat" + } + ], + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/StartMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTdGFydCBNYXBwaW5nIC0gTWluaW1hbCBpbml0IGZvciBzZWxmLWxvb3AgcmVwcm8gd29ya2Zsb3cKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFN0YXJ0TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInN0YXJ0ZWQiLAogICAgICAgICAgICBEYXRhID0gbmV3IHsgCiAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csIAogICAgICAgICAgICAgICAgcmVwcm8gPSAic2VsZi1sb29wLXJ1bGUtaW52YWxpZGF0aW9uIiwKICAgICAgICAgICAgICAgIGNvbmRpdGlvbiA9IDEKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9Cn0K" + } + } + ] + }, + "states": [ + { + "key": "entry-state", + "stateType": 1, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Entry State" + }, + { + "language": "tr-TR", + "label": "Giriş Durumu" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "go-to-loop", + "target": "loop-state", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Go to Loop State" + }, + { + "language": "tr-TR", + "label": "Döngü Durumuna Git" + } + ], + "schema": null, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "loop-state", + "stateType": 2, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Loop State (auto target $self + onExecutionTask -> rule invalidated, no 2nd loop)" + }, + { + "language": "tr-TR", + "label": "Döngü Durumu (auto target $self + onExecutionTask -> kural geçersiz, 2. döngü yok)" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [ + { + "key": "auto-self-loop", + "target": "$self", + "triggerType": 1, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Auto Self-Loop (rule invalidated after onExecutionTask)" + }, + { + "language": "tr-TR", + "label": "Otomatik Self-Loop (onExecutionTask sonrası kural geçersiz)" + } + ], + "schema": null, + "rule": { + "location": "./src/AlwaysTrueRule.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkIChyZXBybzogaW52YWxpZGF0ZWQgd2hlbiBvbkV4ZWN1dGlvblRhc2sgdGFyZ2V0IGlzIHNlbGYpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEuY29uZGl0aW9uID09IDE7CiAgICB9Cn0K" + }, + "timer": null, + "view": null, + "onExecutionTasks": [ + { + "order": 1, + "task": { + "key": "script-task", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/SelfLoopOnExecutionMapping.csx", + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTZWxmLWxvb3AgYXV0byB0cmFuc2l0aW9uIG9uRXhlY3V0aW9uVGFzayAtIHRhcmdldCBpcyBzYW1lIHN0YXRlICgkc2VsZikuCi8vLyBSZXByb2R1Y2VzIGNhc2Ugd2hlcmUgdGhpcyBpbnZhbGlkYXRlcyB0aGUgcnVsZSBzbyB0aGUgc3RhdGUgZG9lcyBub3QgbG9vcCBhIHNlY29uZCB0aW1lLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgU2VsZkxvb3BPbkV4ZWN1dGlvbk1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICB7CiAgICAgICAgICAgIEtleSA9ICJzZWxmLWxvb3AtdGFzay1kb25lIiwKICAgICAgICAgICAgRGF0YSA9IG5ldyB7IAogICAgICAgICAgICAgICAgZXhlY3V0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywgCiAgICAgICAgICAgICAgICBub3RlID0gIm9uRXhlY3V0aW9uVGFzayB0YXJnZXQgaXMgc2VsZiAtPiBydWxlIGludmFsaWRhdGVkLCBubyAybmQgbG9vcCIsCiAgICAgICAgICAgICAgICBjb25kaXRpb24gPSAwCiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQp9Cg==" + } + } + ] + }, + { + "key": "proceed", + "target": "completed", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Proceed" + }, + { + "language": "tr-TR", + "label": "Devam Et" + } + ], + "schema": null, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [] + }, + { + "key": "reject", + "target": "cancelled", + "triggerType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Cancel" + }, + { + "language": "tr-TR", + "label": "İptal" + } + ], + "schema": null, + "rule": null, + "timer": null, + "view": null, + "onExecutionTasks": [] + } + ] + }, + { + "key": "completed", + "stateType": 3, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Completed" + }, + { + "language": "tr-TR", + "label": "Tamamlandı" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + }, + { + "key": "cancelled", + "stateType": 3, + "subType": 0, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Cancelled" + }, + { + "language": "tr-TR", + "label": "İptal Edildi" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [], + "transitions": [] + } + ] + } +} \ No newline at end of file diff --git a/core/Workflows/self-loop-repro/self-loop-repro.http b/core/Workflows/self-loop-repro/self-loop-repro.http new file mode 100644 index 0000000..21b9e84 --- /dev/null +++ b/core/Workflows/self-loop-repro/self-loop-repro.http @@ -0,0 +1,54 @@ +### Self-Loop Rule Invalidation Repro +### Case: Instance start -> manual transition -> target state has 1 auto (target $self) + 2 manual transitions. +### Auto transition's onExecutionTask also targets self -> rule invalidated -> state does NOT loop 2nd time. + +@baseUrl = http://localhost:4201 +@apiVersion = 1 +@domain = core +@workflow = self-loop-repro-workflow +@instanceKey = self-loop-repro-{{$timestamp}} + +### Step 1: Start workflow instance +POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start +Content-Type: application/json + +{ + "key": "{{instanceKey}}", + "tags": ["self-loop-repro", "repro"], + "attributes": {} +} + +### Step 2: Get current state (should be "entry-state") +GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state +Accept: application/json + +### Step 3: Execute manual transition (entry-state -> loop-state) +PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/go-to-loop +Content-Type: application/json + +{} + +### Step 4: Get state after manual transition +### Expected: "loop-state". Auto transition (target $self) runs once; onExecutionTask makes rule invalid -> no 2nd loop. +GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state +Accept: application/json + +### Step 5: Get instance data (verify self-loop task ran once) +GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data +Accept: application/json + +### Step 6a: Proceed (manual) -> completed +PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/proceed +Content-Type: application/json + +{} + +### Step 6b: Or cancel (manual) -> cancelled +# PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/cancel +# Content-Type: application/json +# +# {} + +### Step 7: Final state +GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state +Accept: application/json diff --git a/core/Workflows/self-loop-repro/src/AlwaysTrueRule.csx b/core/Workflows/self-loop-repro/src/AlwaysTrueRule.csx new file mode 100644 index 0000000..eccc254 --- /dev/null +++ b/core/Workflows/self-loop-repro/src/AlwaysTrueRule.csx @@ -0,0 +1,13 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; + +/// +/// Always True Rule - Used for auto transitions that should always proceed (repro: invalidated when onExecutionTask target is self) +/// +public class AlwaysTrueRule : IConditionMapping +{ + public async Task Handler(ScriptContext context) + { + return context.Instance.Data.condition == 1; + } +} diff --git a/core/Workflows/self-loop-repro/src/SelfLoopOnExecutionMapping.csx b/core/Workflows/self-loop-repro/src/SelfLoopOnExecutionMapping.csx new file mode 100644 index 0000000..feff0dc --- /dev/null +++ b/core/Workflows/self-loop-repro/src/SelfLoopOnExecutionMapping.csx @@ -0,0 +1,29 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; + +/// +/// Self-loop auto transition onExecutionTask - target is same state ($self). +/// Reproduces case where this invalidates the rule so the state does not loop a second time. +/// +public class SelfLoopOnExecutionMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + return new ScriptResponse + { + Key = "self-loop-task-done", + Data = new { + executedAt = DateTime.UtcNow, + note = "onExecutionTask target is self -> rule invalidated, no 2nd loop", + condition = 0 + } + }; + } +} diff --git a/core/Workflows/self-loop-repro/src/StartMapping.csx b/core/Workflows/self-loop-repro/src/StartMapping.csx new file mode 100644 index 0000000..67e2b6d --- /dev/null +++ b/core/Workflows/self-loop-repro/src/StartMapping.csx @@ -0,0 +1,28 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; + +/// +/// Start Mapping - Minimal init for self-loop repro workflow +/// +public class StartMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + return new ScriptResponse + { + Key = "started", + Data = new { + startedAt = DateTime.UtcNow, + repro = "self-loop-rule-invalidation", + condition = 1 + } + }; + } +} diff --git a/core/Workflows/subflow-test/src/ChildSharedUpdateMapping.csx b/core/Workflows/subflow-test/src/ChildSharedUpdateMapping.csx new file mode 100644 index 0000000..d93f1eb --- /dev/null +++ b/core/Workflows/subflow-test/src/ChildSharedUpdateMapping.csx @@ -0,0 +1,57 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Child Shared Update Mapping - Processes data sent via child's shared transition (target $self). +/// Used to verify issue #425: child (subflow) can handle shared transitions while in its own subflow. +/// +public class ChildSharedUpdateMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + LogInformation("ChildSharedUpdateMapping - Processing shared transition data on child (target $self)"); + + var body = context.Body as System.Collections.Generic.IDictionary; + object m, v; + var message = body != null && body.TryGetValue("message", out m) ? m?.ToString() : null; + var value = body != null && body.TryGetValue("value", out v) ? v : null; + + return new ScriptResponse + { + Key = "child-shared-update-processed", + Data = new + { + sharedUpdateFromChild = new + { + receivedAt = DateTime.UtcNow, + message = message ?? "no message", + value = value, + workflowKey = context.Workflow?.Key, + instanceId = context.Instance?.Id, + note = "Child flow processed this while in subflow (issue #425 test)" + } + }, + Tags = new[] { "subflow-test", "shared-transition", "child", "issue-425" } + }; + } + catch (Exception ex) + { + LogError("ChildSharedUpdateMapping - Error: {0}", args: new object?[] { ex.Message }); + return new ScriptResponse + { + Key = "child-shared-update-error", + Data = new { error = ex.Message } + }; + } + } +} diff --git a/core/Workflows/subflow-test/src/ParentSharedUpdateMapping.csx b/core/Workflows/subflow-test/src/ParentSharedUpdateMapping.csx new file mode 100644 index 0000000..e03c2ef --- /dev/null +++ b/core/Workflows/subflow-test/src/ParentSharedUpdateMapping.csx @@ -0,0 +1,58 @@ +using System; +using System.Threading.Tasks; +using BBT.Workflow.Definitions; +using BBT.Workflow.Scripting; +using BBT.Workflow.Scripting.Functions; + +/// +/// Parent Shared Update Mapping - Processes data sent via parent's shared transition (target $self). +/// Used to verify issue #425: parent flow can handle shared transitions while instance is in subflow. +/// +public class ParentSharedUpdateMapping : ScriptBase, IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + return Task.FromResult(new ScriptResponse()); + } + + public async Task OutputHandler(ScriptContext context) + { + try + { + LogInformation("ParentSharedUpdateMapping - Processing shared transition data on parent (target $self)"); + + // Transition body is the PATCH request body (e.g. { "message": "...", "value": ... }) + var body = context.Body as System.Collections.Generic.IDictionary; + object m, v; + var message = body != null && body.TryGetValue("message", out m) ? m?.ToString() : null; + var value = body != null && body.TryGetValue("value", out v) ? v : null; + + return new ScriptResponse + { + Key = "parent-shared-update-processed", + Data = new + { + sharedUpdateFromParent = new + { + receivedAt = DateTime.UtcNow, + message = message ?? "no message", + value = value, + workflowKey = context.Workflow?.Key, + instanceId = context.Instance?.Id, + note = "Parent flow processed this while in subflow (issue #425 test)" + } + }, + Tags = new[] { "subflow-test", "shared-transition", "parent", "issue-425" } + }; + } + catch (Exception ex) + { + LogError("ParentSharedUpdateMapping - Error: {0}", args: new object?[] { ex.Message }); + return new ScriptResponse + { + Key = "parent-shared-update-error", + Data = new { error = ex.Message } + }; + } + } +} From 344ab4ff9fb4862a4232f5b5fd9b3f4731d2af08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tayfun=20Y=C4=B1lmaz?= Date: Wed, 15 Apr 2026 11:41:05 +0300 Subject: [PATCH 4/4] chore(core): remove legacy sample workflows and tasks Prune deprecated contract, discovery, oauth, task-test, and related example assets to reduce maintenance overhead and keep the core domain focused on currently supported flows. --- .../extension-user-session.json | 2 +- .../src/HttpDataExtensionMapping.csx | 129 - .../src/HttpTransformExtensionMapping.csx | 190 -- .../task-test/test-http-data-extension.json | 30 - .../test-http-transform-extension.json | 30 - .../multi-task-function-test.json | 2 +- .../src/FunctionValidatePoliciesMapping.csx | 2 +- .../payments/function-get-user-info.json | 2 +- .../account-details-input.json | 4 + .../discovery/domain-start-schema.json | 46 - .../discovery/domain-update-schema.json | 50 - core/Tasks/account-opening/user-session.json | 19 - .../contract/get-contract-documents.json | 27 - .../contract/notify-document-approved.json | 23 - .../Tasks/contract/notify-document-ready.json | 23 - core/Tasks/contract/render-document.json | 27 - .../contract/start-document-subprocess.json | 22 - core/Tasks/discovery/check-domain-exists.json | 23 - .../discovery/check-health-endpoint.json | 26 - core/Tasks/discovery/fetch-domains-list.json | 28 - .../discovery/get-domain-health-url.json | 26 - .../discovery/register-domain-lifecycle.json | 21 - core/Tasks/discovery/register-domain.json | 27 - .../discovery/schedule-health-check.json | 24 - .../discovery/update-domain-lifecycle.json | 22 - core/Tasks/discovery/update-domain.json | 27 - .../Tasks/discovery/update-health-status.json | 27 - .../start-transfer-from-absence-entry.json | 30 - .../oauth/check-device-registration.json | 27 - .../oauth/check-push-denied-response.json | 19 - core/Tasks/oauth/check-push-response.json | 27 - core/Tasks/oauth/generate-tokens.json | 27 - core/Tasks/oauth/register-device.json | 27 - core/Tasks/oauth/send-otp-notification.json | 28 - core/Tasks/oauth/send-push-notification.json | 27 - .../oauth/validate-authorization-code.json | 27 - core/Tasks/oauth/validate-client.json | 26 - .../oauth/validate-user-credentials.json | 27 - core/Tasks/oauth/verify-otp-code.json | 27 - .../trigger-busy-completion-task.json | 2 +- .../task-test/error-boundary-abort-task.json | 28 - .../task-test/error-boundary-ignore-task.json | 28 - .../task-test/error-boundary-retry-task.json | 28 - .../error-boundary-success-task.json | 27 - .../error-boundary-timeout-task.json | 27 - core/Tasks/task-test/test-dapr-pubsub.json | 27 - .../task-test/test-dapr-service-task.json | 24 - .../task-test/test-direct-transition.json | 23 - .../task-test/test-get-instance-data.json | 22 - core/Tasks/task-test/test-get-instances.json | 26 - core/Tasks/task-test/test-http-items.json | 27 - core/Tasks/task-test/test-http-task.json | 27 - core/Tasks/task-test/test-start-workflow.json | 22 - core/Tasks/task-test/test-subprocess.json | 24 - .../account-opening-workflow.diagram.json | 4 +- .../account-opening-workflow.http | 209 -- .../account-opening-workflow.json | 34 +- .../src/CreateBankAccountMapping.csx | 7 +- .../src/OnEntryGetInstanceDataMapping.csx | 27 + .../contract-approval-workflow.diagram.json | 40 - .../contract-document-subflow.diagram.json | 40 - .../contract/contract-approval-workflow.http | 188 -- .../contract/contract-approval-workflow.json | 526 ---- .../contract/contract-document-subflow.json | 456 ---- .../contract/src/AllApprovedRule.csx | 25 - .../contract/src/AllDocumentsReadyRule.csx | 25 - .../Workflows/contract/src/AlwaysTrueRule.csx | 14 - .../contract/src/DocumentsLoadedRule.csx | 22 - .../src/GetContractDocumentsMapping.csx | 124 - .../contract/src/HasMoreDocumentsRule.csx | 25 - .../src/IncrementApprovedCountMapping.csx | 47 - .../src/IncrementReadyCountMapping.csx | 47 - .../src/InitContractApprovalMapping.csx | 52 - .../contract/src/InitDocumentMapping.csx | 50 - .../contract/src/MoreApprovalsPendingRule.csx | 25 - .../contract/src/NoDocumentsRule.csx | 22 - .../src/NotifyDocumentApprovedMapping.csx | 108 - .../src/NotifyDocumentReadyMapping.csx | 109 - .../src/NotifyDocumentRejectedMapping.csx | 109 - .../contract/src/RenderDocumentMapping.csx | 118 - .../contract/src/RenderFailedRule.csx | 22 - .../contract/src/RenderSuccessRule.csx | 22 - .../src/StartDocumentSubprocessMapping.csx | 149 -- .../domain-health-check-workflow.json | 569 ---- .../domain-registration-workflow.json | 557 ---- core/Workflows/discovery/domain-workflow.json | 102 - .../discovery/src/AggregateResultsMapping.csx | 55 - .../src/CheckDomainDontMatchRule.csx | 46 - .../src/CheckDomainExistsMapping.csx | 149 -- .../src/CheckDomainHealthMapping.csx | 157 -- .../discovery/src/CheckDomainMatchRule.csx | 46 - .../src/CheckHealthEndpointMapping.csx | 151 -- .../discovery/src/CheckPaginationRule.csx | 27 - .../discovery/src/DomainExistsRule.csx | 66 - .../discovery/src/DomainNotExistsRule.csx | 31 - .../discovery/src/DomainsFetchedRule.csx | 22 - .../discovery/src/FetchDomainsListMapping.csx | 103 - .../discovery/src/FetchFailedRule.csx | 22 - .../discovery/src/FetchNextPageMapping.csx | 110 - .../src/GetDomainHealthUrlMapping.csx | 174 -- .../discovery/src/HasMoreDomainsRule.csx | 32 - .../discovery/src/HealthCheckFailedRule.csx | 33 - .../discovery/src/HealthCheckPassedRule.csx | 33 - .../src/HealthCheckScheduledRule.csx | 31 - .../src/HealthCheckTriggeredRule.csx | 26 - .../src/HealthStatusUpdateSuccessRule.csx | 30 - .../discovery/src/HealthUrlMissingRule.csx | 29 - .../discovery/src/HealthUrlRetrievedRule.csx | 29 - .../discovery/src/InitialTransitionRule.csx | 25 - .../discovery/src/MarkUnhealthyRule.csx | 45 - .../discovery/src/NextPageFetchedRule.csx | 22 - .../Workflows/discovery/src/NoDomainsRule.csx | 26 - core/Workflows/discovery/src/NoNextRule.csx | 25 - .../discovery/src/PageCompleteRule.csx | 31 - .../discovery/src/ProcessPageMapping.csx | 103 - .../src/RegisterDomainLifecycleMapping.csx | 128 - .../discovery/src/RegisterDomainMapping.csx | 130 - .../discovery/src/RegisterSuccessRule.csx | 31 - .../src/ScheduleHealthCheckMapping.csx | 83 - .../src/ScheduleHealthCheckTimerMapping.csx | 24 - .../discovery/src/ScheduleNextRunMapping.csx | 71 - .../src/ScheduleNextRunTimerMapping.csx | 24 - .../Workflows/discovery/src/ScheduledRule.csx | 22 - .../src/ShouldTriggerHealthCheckRule.csx | 22 - .../discovery/src/SkipHealthCheckRule.csx | 23 - .../discovery/src/ToCheckHealthRule.csx | 26 - .../discovery/src/ToCheckPaginationRule.csx | 21 - .../src/UpdateDomainLifecycleMapping.csx | 135 - .../discovery/src/UpdateDomainMapping.csx | 130 - .../src/UpdateHealthStatusMapping.csx | 171 -- .../discovery/src/UpdateSuccessRule.csx | 31 - .../discovery/src/UpsertFailureRule.csx | 31 - .../discovery/src/UpsertSuccessRule.csx | 31 - .../test-error-boundary-flow.diagram.json | 32 - .../error-boundary/src/Trigger400Mapping.csx | 46 - .../error-boundary/src/Trigger404Mapping.csx | 43 - .../error-boundary/src/Trigger409Mapping.csx | 45 - .../error-boundary/src/Trigger500Mapping.csx | 48 - .../test-error-boundary-flow.http | 87 - .../test-error-boundary-flow.json | 391 --- core/Workflows/morph-touch/absence-entry.json | 146 -- .../src/CanStartTransferMapping.csx | 14 - .../StartTransferFromAbsenceEntryMapping.csx | 94 - .../oauth/.meta/password-subflow.diagram.json | 20 - .../oauth/authorization-code-subflow.json | 177 -- .../oauth/oauth-authentication-workflow.http | 120 - .../oauth/oauth-authentication-workflow.json | 840 ------ core/Workflows/oauth/otp-mfa-subflow.json | 357 --- core/Workflows/oauth/password-subflow.json | 177 -- .../oauth/push-notification-mfa-subflow.json | 298 --- .../oauth/src/AuthorizationCodeFlowRule.csx | 10 - .../src/AuthorizationCodeSubflowMapping.csx | 23 - .../oauth/src/AuthorizationFailedRule.csx | 10 - .../oauth/src/AuthorizationSuccessRule.csx | 10 - .../src/CheckDeviceRegistrationMapping.csx | 196 -- .../src/CheckPushDeniedResponseMapping.csx | 28 - .../oauth/src/CheckPushResponseMapping.csx | 88 - .../oauth/src/ClientCredentialsFlowRule.csx | 10 - .../Workflows/oauth/src/ClientInvalidRule.csx | 50 - core/Workflows/oauth/src/ClientValidRule.csx | 50 - .../oauth/src/DeviceNotRegisteredOtpRule.csx | 10 - .../oauth/src/DeviceRegisteredPushRule.csx | 97 - .../oauth/src/DeviceRegisteredRule.csx | 10 - .../oauth/src/GenerateTokensMapping.csx | 240 -- .../oauth/src/HeaderInitialMapping.csx | 39 - core/Workflows/oauth/src/MfaFailedRule.csx | 10 - core/Workflows/oauth/src/MfaSuccessRule.csx | 10 - .../oauth/src/OtpInvalidMaxAttemptsRule.csx | 11 - .../oauth/src/OtpInvalidRetryRule.csx | 11 - .../oauth/src/OtpMfaSubflowMapping.csx | 23 - .../Workflows/oauth/src/OtpSendFailedRule.csx | 10 - core/Workflows/oauth/src/OtpSentRule.csx | 10 - core/Workflows/oauth/src/PasswordFlowRule.csx | 10 - .../oauth/src/PasswordSubflowMapping.csx | 28 - .../src/PushNotificationMfaSubflowMapping.csx | 23 - .../oauth/src/PushSendFailedRule.csx | 10 - core/Workflows/oauth/src/PushSentRule.csx | 10 - .../oauth/src/RegisterDeviceMapping.csx | 63 - .../oauth/src/SendOtpNotificationMapping.csx | 64 - .../oauth/src/SendPushNotificationMapping.csx | 71 - .../oauth/src/TokenGenerationFailedRule.csx | 10 - .../oauth/src/TokensGeneratedRule.csx | 10 - .../src/ValidateAuthorizationCodeMapping.csx | 78 - .../oauth/src/ValidateClientMapping.csx | 200 -- .../src/ValidateUserCredentialsMapping.csx | 128 - .../oauth/src/VerifyOtpCodeMapping.csx | 74 - .../payments/scheduled-payments-workflow.http | 157 -- .../self-loop-repro-workflow.json | 252 -- .../self-loop-repro/self-loop-repro.http | 54 - .../self-loop-repro/src/AlwaysTrueRule.csx | 13 - .../src/SelfLoopOnExecutionMapping.csx | 29 - .../self-loop-repro/src/StartMapping.csx | 28 - .../subflow-view-test-parent.diagram.json | 12 +- .../subflow-test/BUSY-STATE-TEST-README.md | 226 -- .../ParentInitialGetInstanceDataMapping.csx | 31 + .../subflow-view-test-parent.json | 16 +- .../subflow-test/subflow-view-test.http | 433 ---- .../error-boundary-test-workflow.diagram.json | 56 - .../.meta/task-test-subflow.diagram.json | 16 - .../.meta/task-test-workflow.diagram.json | 60 - .../task-test/error-boundary-subflow.json | 152 -- .../error-boundary-test-workflow.http | 186 -- .../error-boundary-test-workflow.json | 847 ------ .../task-test/src/AlwaysTrueRule.csx | 14 - .../task-test/src/DaprPubSubMapping.csx | 126 - .../task-test/src/DaprServiceTaskMapping.csx | 119 - .../task-test/src/DirectTransitionMapping.csx | 119 - .../src/ErrorBoundaryIgnoreMapping.csx | 54 - .../src/ErrorBoundaryInitMapping.csx | 42 - .../src/ErrorBoundaryNotifyMapping.csx | 53 - .../src/ErrorBoundaryRetryMapping.csx | 53 - .../src/ErrorBoundarySubFlowMapping.csx | 28 - .../src/ErrorBoundarySuccessMapping.csx | 53 - .../src/ErrorBoundaryTimeoutMapping.csx | 53 - .../task-test/src/ErrorRecoveryMapping.csx | 37 - .../task-test/src/GetConfigValueMapping.csx | 94 - .../task-test/src/GetInstanceDataMapping.csx | 111 - .../task-test/src/GetInstancesMapping.csx | 220 -- .../task-test/src/GetSecretAsyncMapping.csx | 94 - .../task-test/src/HttpTaskItemsMapping.csx | 119 - .../task-test/src/HttpTaskMapping.csx | 119 - .../src/InitialTransitionMapping.csx | 60 - .../task-test/src/ManualReviewMapping.csx | 49 - .../task-test/src/RollbackMapping.csx | 49 - .../task-test/src/ScriptTaskMapping.csx | 94 - .../task-test/src/StartWorkflowMapping.csx | 115 - .../task-test/src/SubFlowErrorMapping.csx | 76 - .../src/SubFlowErrorRecoveryRule.csx | 23 - .../task-test/src/SubProcessMapping.csx | 113 - .../src/TaskResponseUsageMapping.csx | 154 -- .../task-test/src/TimeoutHandlerMapping.csx | 49 - .../task-test/task-test-subflow.json | 114 - .../task-test/task-test-workflow.http | 149 -- .../task-test/task-test-workflow.json | 902 ------- docker-compose.yml | 39 + etc/dapr/config.yaml | 7 + etc/docker/config/seed/.gitkeep | 0 .../seed/account-opening-collection.json | 74 + .../config/seed/payments-collection.json | 259 ++ mockoon/migration-api.json | 2279 ----------------- 240 files changed, 504 insertions(+), 21094 deletions(-) delete mode 100644 core/Extensions/task-test/src/HttpDataExtensionMapping.csx delete mode 100644 core/Extensions/task-test/src/HttpTransformExtensionMapping.csx delete mode 100644 core/Extensions/task-test/test-http-data-extension.json delete mode 100644 core/Extensions/task-test/test-http-transform-extension.json delete mode 100644 core/Schemas/discovery/domain-start-schema.json delete mode 100644 core/Schemas/discovery/domain-update-schema.json delete mode 100644 core/Tasks/account-opening/user-session.json delete mode 100644 core/Tasks/contract/get-contract-documents.json delete mode 100644 core/Tasks/contract/notify-document-approved.json delete mode 100644 core/Tasks/contract/notify-document-ready.json delete mode 100644 core/Tasks/contract/render-document.json delete mode 100644 core/Tasks/contract/start-document-subprocess.json delete mode 100644 core/Tasks/discovery/check-domain-exists.json delete mode 100644 core/Tasks/discovery/check-health-endpoint.json delete mode 100644 core/Tasks/discovery/fetch-domains-list.json delete mode 100644 core/Tasks/discovery/get-domain-health-url.json delete mode 100644 core/Tasks/discovery/register-domain-lifecycle.json delete mode 100644 core/Tasks/discovery/register-domain.json delete mode 100644 core/Tasks/discovery/schedule-health-check.json delete mode 100644 core/Tasks/discovery/update-domain-lifecycle.json delete mode 100644 core/Tasks/discovery/update-domain.json delete mode 100644 core/Tasks/discovery/update-health-status.json delete mode 100644 core/Tasks/morph-touch/start-transfer-from-absence-entry.json delete mode 100644 core/Tasks/oauth/check-device-registration.json delete mode 100644 core/Tasks/oauth/check-push-denied-response.json delete mode 100644 core/Tasks/oauth/check-push-response.json delete mode 100644 core/Tasks/oauth/generate-tokens.json delete mode 100644 core/Tasks/oauth/register-device.json delete mode 100644 core/Tasks/oauth/send-otp-notification.json delete mode 100644 core/Tasks/oauth/send-push-notification.json delete mode 100644 core/Tasks/oauth/validate-authorization-code.json delete mode 100644 core/Tasks/oauth/validate-client.json delete mode 100644 core/Tasks/oauth/validate-user-credentials.json delete mode 100644 core/Tasks/oauth/verify-otp-code.json delete mode 100644 core/Tasks/task-test/error-boundary-abort-task.json delete mode 100644 core/Tasks/task-test/error-boundary-ignore-task.json delete mode 100644 core/Tasks/task-test/error-boundary-retry-task.json delete mode 100644 core/Tasks/task-test/error-boundary-success-task.json delete mode 100644 core/Tasks/task-test/error-boundary-timeout-task.json delete mode 100644 core/Tasks/task-test/test-dapr-pubsub.json delete mode 100644 core/Tasks/task-test/test-dapr-service-task.json delete mode 100644 core/Tasks/task-test/test-direct-transition.json delete mode 100644 core/Tasks/task-test/test-get-instance-data.json delete mode 100644 core/Tasks/task-test/test-get-instances.json delete mode 100644 core/Tasks/task-test/test-http-items.json delete mode 100644 core/Tasks/task-test/test-http-task.json delete mode 100644 core/Tasks/task-test/test-start-workflow.json delete mode 100644 core/Tasks/task-test/test-subprocess.json delete mode 100644 core/Workflows/account-opening/account-opening-workflow.http create mode 100644 core/Workflows/account-opening/src/OnEntryGetInstanceDataMapping.csx delete mode 100644 core/Workflows/contract/.meta/contract-approval-workflow.diagram.json delete mode 100644 core/Workflows/contract/.meta/contract-document-subflow.diagram.json delete mode 100644 core/Workflows/contract/contract-approval-workflow.http delete mode 100644 core/Workflows/contract/contract-approval-workflow.json delete mode 100644 core/Workflows/contract/contract-document-subflow.json delete mode 100644 core/Workflows/contract/src/AllApprovedRule.csx delete mode 100644 core/Workflows/contract/src/AllDocumentsReadyRule.csx delete mode 100644 core/Workflows/contract/src/AlwaysTrueRule.csx delete mode 100644 core/Workflows/contract/src/DocumentsLoadedRule.csx delete mode 100644 core/Workflows/contract/src/GetContractDocumentsMapping.csx delete mode 100644 core/Workflows/contract/src/HasMoreDocumentsRule.csx delete mode 100644 core/Workflows/contract/src/IncrementApprovedCountMapping.csx delete mode 100644 core/Workflows/contract/src/IncrementReadyCountMapping.csx delete mode 100644 core/Workflows/contract/src/InitContractApprovalMapping.csx delete mode 100644 core/Workflows/contract/src/InitDocumentMapping.csx delete mode 100644 core/Workflows/contract/src/MoreApprovalsPendingRule.csx delete mode 100644 core/Workflows/contract/src/NoDocumentsRule.csx delete mode 100644 core/Workflows/contract/src/NotifyDocumentApprovedMapping.csx delete mode 100644 core/Workflows/contract/src/NotifyDocumentReadyMapping.csx delete mode 100644 core/Workflows/contract/src/NotifyDocumentRejectedMapping.csx delete mode 100644 core/Workflows/contract/src/RenderDocumentMapping.csx delete mode 100644 core/Workflows/contract/src/RenderFailedRule.csx delete mode 100644 core/Workflows/contract/src/RenderSuccessRule.csx delete mode 100644 core/Workflows/contract/src/StartDocumentSubprocessMapping.csx delete mode 100644 core/Workflows/discovery/domain-health-check-workflow.json delete mode 100644 core/Workflows/discovery/domain-registration-workflow.json delete mode 100644 core/Workflows/discovery/domain-workflow.json delete mode 100644 core/Workflows/discovery/src/AggregateResultsMapping.csx delete mode 100644 core/Workflows/discovery/src/CheckDomainDontMatchRule.csx delete mode 100644 core/Workflows/discovery/src/CheckDomainExistsMapping.csx delete mode 100644 core/Workflows/discovery/src/CheckDomainHealthMapping.csx delete mode 100644 core/Workflows/discovery/src/CheckDomainMatchRule.csx delete mode 100644 core/Workflows/discovery/src/CheckHealthEndpointMapping.csx delete mode 100644 core/Workflows/discovery/src/CheckPaginationRule.csx delete mode 100644 core/Workflows/discovery/src/DomainExistsRule.csx delete mode 100644 core/Workflows/discovery/src/DomainNotExistsRule.csx delete mode 100644 core/Workflows/discovery/src/DomainsFetchedRule.csx delete mode 100644 core/Workflows/discovery/src/FetchDomainsListMapping.csx delete mode 100644 core/Workflows/discovery/src/FetchFailedRule.csx delete mode 100644 core/Workflows/discovery/src/FetchNextPageMapping.csx delete mode 100644 core/Workflows/discovery/src/GetDomainHealthUrlMapping.csx delete mode 100644 core/Workflows/discovery/src/HasMoreDomainsRule.csx delete mode 100644 core/Workflows/discovery/src/HealthCheckFailedRule.csx delete mode 100644 core/Workflows/discovery/src/HealthCheckPassedRule.csx delete mode 100644 core/Workflows/discovery/src/HealthCheckScheduledRule.csx delete mode 100644 core/Workflows/discovery/src/HealthCheckTriggeredRule.csx delete mode 100644 core/Workflows/discovery/src/HealthStatusUpdateSuccessRule.csx delete mode 100644 core/Workflows/discovery/src/HealthUrlMissingRule.csx delete mode 100644 core/Workflows/discovery/src/HealthUrlRetrievedRule.csx delete mode 100644 core/Workflows/discovery/src/InitialTransitionRule.csx delete mode 100644 core/Workflows/discovery/src/MarkUnhealthyRule.csx delete mode 100644 core/Workflows/discovery/src/NextPageFetchedRule.csx delete mode 100644 core/Workflows/discovery/src/NoDomainsRule.csx delete mode 100644 core/Workflows/discovery/src/NoNextRule.csx delete mode 100644 core/Workflows/discovery/src/PageCompleteRule.csx delete mode 100644 core/Workflows/discovery/src/ProcessPageMapping.csx delete mode 100644 core/Workflows/discovery/src/RegisterDomainLifecycleMapping.csx delete mode 100644 core/Workflows/discovery/src/RegisterDomainMapping.csx delete mode 100644 core/Workflows/discovery/src/RegisterSuccessRule.csx delete mode 100644 core/Workflows/discovery/src/ScheduleHealthCheckMapping.csx delete mode 100644 core/Workflows/discovery/src/ScheduleHealthCheckTimerMapping.csx delete mode 100644 core/Workflows/discovery/src/ScheduleNextRunMapping.csx delete mode 100644 core/Workflows/discovery/src/ScheduleNextRunTimerMapping.csx delete mode 100644 core/Workflows/discovery/src/ScheduledRule.csx delete mode 100644 core/Workflows/discovery/src/ShouldTriggerHealthCheckRule.csx delete mode 100644 core/Workflows/discovery/src/SkipHealthCheckRule.csx delete mode 100644 core/Workflows/discovery/src/ToCheckHealthRule.csx delete mode 100644 core/Workflows/discovery/src/ToCheckPaginationRule.csx delete mode 100644 core/Workflows/discovery/src/UpdateDomainLifecycleMapping.csx delete mode 100644 core/Workflows/discovery/src/UpdateDomainMapping.csx delete mode 100644 core/Workflows/discovery/src/UpdateHealthStatusMapping.csx delete mode 100644 core/Workflows/discovery/src/UpdateSuccessRule.csx delete mode 100644 core/Workflows/discovery/src/UpsertFailureRule.csx delete mode 100644 core/Workflows/discovery/src/UpsertSuccessRule.csx delete mode 100644 core/Workflows/error-boundary/.meta/test-error-boundary-flow.diagram.json delete mode 100644 core/Workflows/error-boundary/src/Trigger400Mapping.csx delete mode 100644 core/Workflows/error-boundary/src/Trigger404Mapping.csx delete mode 100644 core/Workflows/error-boundary/src/Trigger409Mapping.csx delete mode 100644 core/Workflows/error-boundary/src/Trigger500Mapping.csx delete mode 100644 core/Workflows/error-boundary/test-error-boundary-flow.http delete mode 100644 core/Workflows/error-boundary/test-error-boundary-flow.json delete mode 100644 core/Workflows/morph-touch/absence-entry.json delete mode 100644 core/Workflows/morph-touch/src/CanStartTransferMapping.csx delete mode 100644 core/Workflows/morph-touch/src/StartTransferFromAbsenceEntryMapping.csx delete mode 100644 core/Workflows/oauth/.meta/password-subflow.diagram.json delete mode 100644 core/Workflows/oauth/authorization-code-subflow.json delete mode 100644 core/Workflows/oauth/oauth-authentication-workflow.http delete mode 100644 core/Workflows/oauth/oauth-authentication-workflow.json delete mode 100644 core/Workflows/oauth/otp-mfa-subflow.json delete mode 100644 core/Workflows/oauth/password-subflow.json delete mode 100644 core/Workflows/oauth/push-notification-mfa-subflow.json delete mode 100644 core/Workflows/oauth/src/AuthorizationCodeFlowRule.csx delete mode 100644 core/Workflows/oauth/src/AuthorizationCodeSubflowMapping.csx delete mode 100644 core/Workflows/oauth/src/AuthorizationFailedRule.csx delete mode 100644 core/Workflows/oauth/src/AuthorizationSuccessRule.csx delete mode 100644 core/Workflows/oauth/src/CheckDeviceRegistrationMapping.csx delete mode 100644 core/Workflows/oauth/src/CheckPushDeniedResponseMapping.csx delete mode 100644 core/Workflows/oauth/src/CheckPushResponseMapping.csx delete mode 100644 core/Workflows/oauth/src/ClientCredentialsFlowRule.csx delete mode 100644 core/Workflows/oauth/src/ClientInvalidRule.csx delete mode 100644 core/Workflows/oauth/src/ClientValidRule.csx delete mode 100644 core/Workflows/oauth/src/DeviceNotRegisteredOtpRule.csx delete mode 100644 core/Workflows/oauth/src/DeviceRegisteredPushRule.csx delete mode 100644 core/Workflows/oauth/src/DeviceRegisteredRule.csx delete mode 100644 core/Workflows/oauth/src/GenerateTokensMapping.csx delete mode 100644 core/Workflows/oauth/src/HeaderInitialMapping.csx delete mode 100644 core/Workflows/oauth/src/MfaFailedRule.csx delete mode 100644 core/Workflows/oauth/src/MfaSuccessRule.csx delete mode 100644 core/Workflows/oauth/src/OtpInvalidMaxAttemptsRule.csx delete mode 100644 core/Workflows/oauth/src/OtpInvalidRetryRule.csx delete mode 100644 core/Workflows/oauth/src/OtpMfaSubflowMapping.csx delete mode 100644 core/Workflows/oauth/src/OtpSendFailedRule.csx delete mode 100644 core/Workflows/oauth/src/OtpSentRule.csx delete mode 100644 core/Workflows/oauth/src/PasswordFlowRule.csx delete mode 100644 core/Workflows/oauth/src/PasswordSubflowMapping.csx delete mode 100644 core/Workflows/oauth/src/PushNotificationMfaSubflowMapping.csx delete mode 100644 core/Workflows/oauth/src/PushSendFailedRule.csx delete mode 100644 core/Workflows/oauth/src/PushSentRule.csx delete mode 100644 core/Workflows/oauth/src/RegisterDeviceMapping.csx delete mode 100644 core/Workflows/oauth/src/SendOtpNotificationMapping.csx delete mode 100644 core/Workflows/oauth/src/SendPushNotificationMapping.csx delete mode 100644 core/Workflows/oauth/src/TokenGenerationFailedRule.csx delete mode 100644 core/Workflows/oauth/src/TokensGeneratedRule.csx delete mode 100644 core/Workflows/oauth/src/ValidateAuthorizationCodeMapping.csx delete mode 100644 core/Workflows/oauth/src/ValidateClientMapping.csx delete mode 100644 core/Workflows/oauth/src/ValidateUserCredentialsMapping.csx delete mode 100644 core/Workflows/oauth/src/VerifyOtpCodeMapping.csx delete mode 100644 core/Workflows/payments/scheduled-payments-workflow.http delete mode 100644 core/Workflows/self-loop-repro/self-loop-repro-workflow.json delete mode 100644 core/Workflows/self-loop-repro/self-loop-repro.http delete mode 100644 core/Workflows/self-loop-repro/src/AlwaysTrueRule.csx delete mode 100644 core/Workflows/self-loop-repro/src/SelfLoopOnExecutionMapping.csx delete mode 100644 core/Workflows/self-loop-repro/src/StartMapping.csx delete mode 100644 core/Workflows/subflow-test/BUSY-STATE-TEST-README.md create mode 100644 core/Workflows/subflow-test/src/ParentInitialGetInstanceDataMapping.csx delete mode 100644 core/Workflows/subflow-test/subflow-view-test.http delete mode 100644 core/Workflows/task-test/.meta/error-boundary-test-workflow.diagram.json delete mode 100644 core/Workflows/task-test/.meta/task-test-subflow.diagram.json delete mode 100644 core/Workflows/task-test/.meta/task-test-workflow.diagram.json delete mode 100644 core/Workflows/task-test/error-boundary-subflow.json delete mode 100644 core/Workflows/task-test/error-boundary-test-workflow.http delete mode 100644 core/Workflows/task-test/error-boundary-test-workflow.json delete mode 100644 core/Workflows/task-test/src/AlwaysTrueRule.csx delete mode 100644 core/Workflows/task-test/src/DaprPubSubMapping.csx delete mode 100644 core/Workflows/task-test/src/DaprServiceTaskMapping.csx delete mode 100644 core/Workflows/task-test/src/DirectTransitionMapping.csx delete mode 100644 core/Workflows/task-test/src/ErrorBoundaryIgnoreMapping.csx delete mode 100644 core/Workflows/task-test/src/ErrorBoundaryInitMapping.csx delete mode 100644 core/Workflows/task-test/src/ErrorBoundaryNotifyMapping.csx delete mode 100644 core/Workflows/task-test/src/ErrorBoundaryRetryMapping.csx delete mode 100644 core/Workflows/task-test/src/ErrorBoundarySubFlowMapping.csx delete mode 100644 core/Workflows/task-test/src/ErrorBoundarySuccessMapping.csx delete mode 100644 core/Workflows/task-test/src/ErrorBoundaryTimeoutMapping.csx delete mode 100644 core/Workflows/task-test/src/ErrorRecoveryMapping.csx delete mode 100644 core/Workflows/task-test/src/GetConfigValueMapping.csx delete mode 100644 core/Workflows/task-test/src/GetInstanceDataMapping.csx delete mode 100644 core/Workflows/task-test/src/GetInstancesMapping.csx delete mode 100644 core/Workflows/task-test/src/GetSecretAsyncMapping.csx delete mode 100644 core/Workflows/task-test/src/HttpTaskItemsMapping.csx delete mode 100644 core/Workflows/task-test/src/HttpTaskMapping.csx delete mode 100644 core/Workflows/task-test/src/InitialTransitionMapping.csx delete mode 100644 core/Workflows/task-test/src/ManualReviewMapping.csx delete mode 100644 core/Workflows/task-test/src/RollbackMapping.csx delete mode 100644 core/Workflows/task-test/src/ScriptTaskMapping.csx delete mode 100644 core/Workflows/task-test/src/StartWorkflowMapping.csx delete mode 100644 core/Workflows/task-test/src/SubFlowErrorMapping.csx delete mode 100644 core/Workflows/task-test/src/SubFlowErrorRecoveryRule.csx delete mode 100644 core/Workflows/task-test/src/SubProcessMapping.csx delete mode 100644 core/Workflows/task-test/src/TaskResponseUsageMapping.csx delete mode 100644 core/Workflows/task-test/src/TimeoutHandlerMapping.csx delete mode 100644 core/Workflows/task-test/task-test-subflow.json delete mode 100644 core/Workflows/task-test/task-test-workflow.http delete mode 100644 core/Workflows/task-test/task-test-workflow.json create mode 100644 docker-compose.yml create mode 100644 etc/dapr/config.yaml create mode 100644 etc/docker/config/seed/.gitkeep create mode 100644 etc/docker/config/seed/account-opening-collection.json create mode 100644 etc/docker/config/seed/payments-collection.json delete mode 100644 mockoon/migration-api.json diff --git a/core/Extensions/account-opening/extension-user-session.json b/core/Extensions/account-opening/extension-user-session.json index 746cb0c..076a005 100644 --- a/core/Extensions/account-opening/extension-user-session.json +++ b/core/Extensions/account-opening/extension-user-session.json @@ -16,7 +16,7 @@ "task": { "order": 1, "task": { - "key": "user-session", + "key": "script-task", "domain": "core", "version": "1.0.0", "flow": "sys-tasks" diff --git a/core/Extensions/task-test/src/HttpDataExtensionMapping.csx b/core/Extensions/task-test/src/HttpDataExtensionMapping.csx deleted file mode 100644 index 4dbed51..0000000 --- a/core/Extensions/task-test/src/HttpDataExtensionMapping.csx +++ /dev/null @@ -1,129 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// HTTP Data Extension Mapping - Calls HTTP task and extracts response data -/// Test case: Verify extension data in GetInstanceData -/// -public class HttpDataExtensionMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - // Prepare request body for HTTP task - var requestBody = new - { - source = "extension", - extensionName = "test-http-data-extension", - workflowId = context.Workflow.Key, - instanceId = context.Instance?.Id, - timestamp = DateTime.UtcNow, - requestType = "extension-data-fetch" - }; - - httpTask.SetBody(requestBody); - - // Set headers - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Extension-Name"] = "test-http-data-extension", - ["X-Request-Id"] = Guid.NewGuid().ToString(), - ["X-Correlation-Id"] = context.Instance.Id.ToString() - }; - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "http-extension-input-error", - Data = new { error = ex.Message } - }); - } - } - - /// - /// Extract and return the "data" field from HTTP response - /// This data will be available in GetInstanceData under "extensions" - /// - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - var statusCode = response?.statusCode ?? 500; - - // Check if HTTP request was successful - if (statusCode >= 200 && statusCode < 300) - { - // Extract the "data" field from response - var httpResponseData = response?.data; - - return new ScriptResponse - { - Key = "test-http-data-extension-success", - Data = new - { - // This is the data that will be available in extensions - httpData = httpResponseData, - extensionMetadata = new - { - extensionName = "test-http-data-extension", - executedAt = DateTime.UtcNow, - statusCode = statusCode, - success = true - } - } - }; - } - - // HTTP request failed - return new ScriptResponse - { - Key = "test-http-data-extension-failed", - Data = new - { - error = "HTTP request failed", - statusCode = statusCode, - errorMessage = response?.errorMessage ?? "Unknown error", - extensionMetadata = new - { - extensionName = "test-http-data-extension", - executedAt = DateTime.UtcNow, - success = false - } - } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "test-http-data-extension-exception", - Data = new - { - error = ex.Message, - extensionMetadata = new - { - extensionName = "test-http-data-extension", - executedAt = DateTime.UtcNow, - success = false - } - } - }; - } - } -} - diff --git a/core/Extensions/task-test/src/HttpTransformExtensionMapping.csx b/core/Extensions/task-test/src/HttpTransformExtensionMapping.csx deleted file mode 100644 index 9e934c6..0000000 --- a/core/Extensions/task-test/src/HttpTransformExtensionMapping.csx +++ /dev/null @@ -1,190 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// HTTP Transform Extension Mapping - Transforms and enriches HTTP response data -/// Test case: Verify data transformation and enrichment in extensions -/// -public class HttpTransformExtensionMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - // Prepare request body with extension context - var requestBody = new - { - source = "extension", - extensionName = "test-http-transform-extension", - workflowId = context.Workflow.Key, - instanceId = context.Instance?.Id, - timestamp = DateTime.UtcNow, - requestType = "extension-transform-test", - userData = new - { - userId = context.Instance?.Data?.testId, - session = "test-session", - operation = "transform-data" - } - }; - - httpTask.SetBody(requestBody); - - // Set headers - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Extension-Name"] = "test-http-transform-extension", - ["X-Transform-Type"] = "enrichment", - ["X-Request-Id"] = Guid.NewGuid().ToString(), - ["X-Correlation-Id"] = context.Instance.Id.ToString() - }; - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "http-transform-input-error", - Data = new { error = ex.Message } - }); - } - } - - /// - /// Transform and enrich the "data" field from HTTP response - /// - Extract original data - /// - Transform taskType to uppercase - /// - Add analytics information - /// - Enrichment with additional metadata - /// - Calculate derived values - /// - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - var statusCode = response?.statusCode ?? 500; - - // Check if HTTP request was successful - if (statusCode >= 200 && statusCode < 300) - { - // Extract original data - var originalData = response?.data; - var metadata = response?.data?.metadata; - - // Transform and enrich data - var transformedData = new - { - // Original data (transformed) - taskTypeUpper = originalData?.data?.taskType?.ToString()?.ToUpper(), - originalMessage = originalData?.data?.message, - receivedPartial = new - { - source = originalData?.data?.receivedData?.source, - extension = originalData?.data?.receivedData?.extensionName - }, - // Add derived values - processedTimestamp = DateTime.UtcNow. - AddHours(5). // Add 5 hours - ToString("O"), - customRequestId = $"TRANS-{Guid.NewGuid().ToString().Substring(0, 8).ToUpper()}", - // Add analytics - analytics = new - { - dataSizeBytes = System.Text.Encoding.UTF8.GetByteCount( - System.Text.Json.JsonSerializer.Serialize(originalData) - ), - fieldCount = 3, // taskType, message, receivedData - processingTimeMs = metadata?.responseTime, - successRate = 100.0 - }, - // Add enrichment - enrichment = new - { - category = "API_TEST", - priority = "HIGH", - tags = new[] { "transformed", "enriched", "analyzed" }, - verified = true, - enrichedAt = DateTime.UtcNow - }, - // Add validation results - validation = new - { - isValid = true, - validationErrors = new object[] { }, - validatedFields = new[] { "taskType", "message", "requestId" }, - validatedAt = DateTime.UtcNow - } - }; - - return new ScriptResponse - { - Key = "test-http-transform-extension-success", - Data = new - { - // Transformed and enriched data - transformedData = transformedData, - // Original data for reference - originalData = originalData, - // Metadata - extensionMetadata = new - { - extensionName = "test-http-transform-extension", - transformationType = "enrichment+analytics", - executedAt = DateTime.UtcNow, - statusCode = statusCode, - success = true - } - } - }; - } - - // HTTP request failed - return new ScriptResponse - { - Key = "test-http-transform-extension-failed", - Data = new - { - error = "HTTP request failed", - statusCode = statusCode, - errorMessage = response?.errorMessage ?? "Unknown error", - extensionMetadata = new - { - extensionName = "test-http-transform-extension", - executedAt = DateTime.UtcNow, - success = false - } - } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "test-http-transform-extension-exception", - Data = new - { - error = ex.Message, - extensionMetadata = new - { - extensionName = "test-http-transform-extension", - executedAt = DateTime.UtcNow, - success = false - } - } - }; - } - } -} - diff --git a/core/Extensions/task-test/test-http-data-extension.json b/core/Extensions/task-test/test-http-data-extension.json deleted file mode 100644 index 0d16c2d..0000000 --- a/core/Extensions/task-test/test-http-data-extension.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "key": "test-http-data-extension", - "version": "1.0.0", - "domain": "core", - "flow": "sys-extensions", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "http-extension", - "data-extension", - "get-instance-data" - ], - "attributes": { - "type": 2, - "scope": 1, - "task": { - "order": 1, - "task": { - "key": "test-http-items", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/HttpDataExtensionMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBIVFRQIERhdGEgRXh0ZW5zaW9uIE1hcHBpbmcgLSBDYWxscyBIVFRQIHRhc2sgYW5kIGV4dHJhY3RzIHJlc3BvbnNlIGRhdGEKLy8vIFRlc3QgY2FzZTogVmVyaWZ5IGV4dGVuc2lvbiBkYXRhIGluIEdldEluc3RhbmNlRGF0YQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgSHR0cERhdGFFeHRlbnNpb25NYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUHJlcGFyZSByZXF1ZXN0IGJvZHkgZm9yIEhUVFAgdGFzawogICAgICAgICAgICB2YXIgcmVxdWVzdEJvZHkgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc291cmNlID0gImV4dGVuc2lvbiIsCiAgICAgICAgICAgICAgICBleHRlbnNpb25OYW1lID0gInRlc3QtaHR0cC1kYXRhLWV4dGVuc2lvbiIsCiAgICAgICAgICAgICAgICB3b3JrZmxvd0lkID0gY29udGV4dC5Xb3JrZmxvdy5LZXksCiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICB0aW1lc3RhbXAgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICByZXF1ZXN0VHlwZSA9ICJleHRlbnNpb24tZGF0YS1mZXRjaCIKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGh0dHBUYXNrLlNldEJvZHkocmVxdWVzdEJvZHkpOwoKICAgICAgICAgICAgLy8gU2V0IGhlYWRlcnMKICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIHN0cmluZz8+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgICAgICBbIlgtRXh0ZW5zaW9uLU5hbWUiXSA9ICJ0ZXN0LWh0dHAtZGF0YS1leHRlbnNpb24iLAogICAgICAgICAgICAgICAgWyJYLVJlcXVlc3QtSWQiXSA9IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIlgtQ29ycmVsYXRpb24tSWQiXSA9IGNvbnRleHQuSW5zdGFuY2UuSWQuVG9TdHJpbmcoKQogICAgICAgICAgICB9OwogICAgICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKGhlYWRlcnMpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiaHR0cC1leHRlbnNpb24taW5wdXQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KCiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gRXh0cmFjdCBhbmQgcmV0dXJuIHRoZSAiZGF0YSIgZmllbGQgZnJvbSBIVFRQIHJlc3BvbnNlCiAgICAvLy8gVGhpcyBkYXRhIHdpbGwgYmUgYXZhaWxhYmxlIGluIEdldEluc3RhbmNlRGF0YSB1bmRlciAiZXh0ZW5zaW9ucyIKICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBjb250ZXh0LkJvZHk7CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gcmVzcG9uc2U/LnN0YXR1c0NvZGUgPz8gNTAwOwoKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgSFRUUCByZXF1ZXN0IHdhcyBzdWNjZXNzZnVsCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDwgMzAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IHRoZSAiZGF0YSIgZmllbGQgZnJvbSByZXNwb25zZQogICAgICAgICAgICAgICAgdmFyIGh0dHBSZXNwb25zZURhdGEgPSByZXNwb25zZT8uZGF0YTsKCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInRlc3QtaHR0cC1kYXRhLWV4dGVuc2lvbi1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRoZSBkYXRhIHRoYXQgd2lsbCBiZSBhdmFpbGFibGUgaW4gZXh0ZW5zaW9ucwogICAgICAgICAgICAgICAgICAgICAgICBodHRwRGF0YSA9IGh0dHBSZXNwb25zZURhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk1ldGFkYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk5hbWUgPSAidGVzdC1odHRwLWRhdGEtZXh0ZW5zaW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gc3RhdHVzQ29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBIVFRQIHJlcXVlc3QgZmFpbGVkCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInRlc3QtaHR0cC1kYXRhLWV4dGVuc2lvbi1mYWlsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkhUVFAgcmVxdWVzdCBmYWlsZWQiLAogICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IHJlc3BvbnNlPy5lcnJvck1lc3NhZ2UgPz8gIlVua25vd24gZXJyb3IiLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk1ldGFkYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25OYW1lID0gInRlc3QtaHR0cC1kYXRhLWV4dGVuc2lvbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWN1dGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInRlc3QtaHR0cC1kYXRhLWV4dGVuc2lvbi1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25NZXRhZGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uTmFtZSA9ICJ0ZXN0LWh0dHAtZGF0YS1leHRlbnNpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - } -} \ No newline at end of file diff --git a/core/Extensions/task-test/test-http-transform-extension.json b/core/Extensions/task-test/test-http-transform-extension.json deleted file mode 100644 index 492a686..0000000 --- a/core/Extensions/task-test/test-http-transform-extension.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "key": "test-http-transform-extension", - "version": "1.0.0", - "domain": "core", - "flow": "sys-extensions", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "http-extension", - "data-transform", - "enrichment" - ], - "attributes": { - "type": 2, - "scope": 1, - "task": { - "order": 1, - "task": { - "key": "test-http-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/HttpTransformExtensionMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBIVFRQIFRyYW5zZm9ybSBFeHRlbnNpb24gTWFwcGluZyAtIFRyYW5zZm9ybXMgYW5kIGVucmljaGVzIEhUVFAgcmVzcG9uc2UgZGF0YQovLy8gVGVzdCBjYXNlOiBWZXJpZnkgZGF0YSB0cmFuc2Zvcm1hdGlvbiBhbmQgZW5yaWNobWVudCBpbiBleHRlbnNpb25zCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBIdHRwVHJhbnNmb3JtRXh0ZW5zaW9uTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGFuIEh0dHBUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFByZXBhcmUgcmVxdWVzdCBib2R5IHdpdGggZXh0ZW5zaW9uIGNvbnRleHQKICAgICAgICAgICAgdmFyIHJlcXVlc3RCb2R5ID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNvdXJjZSA9ICJleHRlbnNpb24iLAogICAgICAgICAgICAgICAgZXh0ZW5zaW9uTmFtZSA9ICJ0ZXN0LWh0dHAtdHJhbnNmb3JtLWV4dGVuc2lvbiIsCiAgICAgICAgICAgICAgICB3b3JrZmxvd0lkID0gY29udGV4dC5Xb3JrZmxvdy5LZXksCiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICB0aW1lc3RhbXAgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICByZXF1ZXN0VHlwZSA9ICJleHRlbnNpb24tdHJhbnNmb3JtLXRlc3QiLAogICAgICAgICAgICAgICAgdXNlckRhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB1c2VySWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50ZXN0SWQsCiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiA9ICJ0ZXN0LXNlc3Npb24iLAogICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbiA9ICJ0cmFuc2Zvcm0tZGF0YSIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGh0dHBUYXNrLlNldEJvZHkocmVxdWVzdEJvZHkpOwoKICAgICAgICAgICAgLy8gU2V0IGhlYWRlcnMKICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIHN0cmluZz8+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgICAgICBbIlgtRXh0ZW5zaW9uLU5hbWUiXSA9ICJ0ZXN0LWh0dHAtdHJhbnNmb3JtLWV4dGVuc2lvbiIsCiAgICAgICAgICAgICAgICBbIlgtVHJhbnNmb3JtLVR5cGUiXSA9ICJlbnJpY2htZW50IiwKICAgICAgICAgICAgICAgIFsiWC1SZXF1ZXN0LUlkIl0gPSBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgWyJYLUNvcnJlbGF0aW9uLUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlLklkLlRvU3RyaW5nKCkKICAgICAgICAgICAgfTsKICAgICAgICAgICAgaHR0cFRhc2suU2V0SGVhZGVycyhoZWFkZXJzKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImh0dHAtdHJhbnNmb3JtLWlucHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIFRyYW5zZm9ybSBhbmQgZW5yaWNoIHRoZSAiZGF0YSIgZmllbGQgZnJvbSBIVFRQIHJlc3BvbnNlCiAgICAvLy8gLSBFeHRyYWN0IG9yaWdpbmFsIGRhdGEKICAgIC8vLyAtIFRyYW5zZm9ybSB0YXNrVHlwZSB0byB1cHBlcmNhc2UKICAgIC8vLyAtIEFkZCBhbmFseXRpY3MgaW5mb3JtYXRpb24KICAgIC8vLyAtIEVucmljaG1lbnQgd2l0aCBhZGRpdGlvbmFsIG1ldGFkYXRhCiAgICAvLy8gLSBDYWxjdWxhdGUgZGVyaXZlZCB2YWx1ZXMKICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBjb250ZXh0LkJvZHk7CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gcmVzcG9uc2U/LnN0YXR1c0NvZGUgPz8gNTAwOwoKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgSFRUUCByZXF1ZXN0IHdhcyBzdWNjZXNzZnVsCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDwgMzAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IG9yaWdpbmFsIGRhdGEKICAgICAgICAgICAgICAgIHZhciBvcmlnaW5hbERhdGEgPSByZXNwb25zZT8uZGF0YTsKICAgICAgICAgICAgICAgIHZhciBtZXRhZGF0YSA9IHJlc3BvbnNlPy5kYXRhPy5tZXRhZGF0YTsKCiAgICAgICAgICAgICAgICAvLyBUcmFuc2Zvcm0gYW5kIGVucmljaCBkYXRhCiAgICAgICAgICAgICAgICB2YXIgdHJhbnNmb3JtZWREYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luYWwgZGF0YSAodHJhbnNmb3JtZWQpCiAgICAgICAgICAgICAgICAgICAgdGFza1R5cGVVcHBlciA9IG9yaWdpbmFsRGF0YT8uZGF0YT8udGFza1R5cGU/LlRvU3RyaW5nKCk/LlRvVXBwZXIoKSwKICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbE1lc3NhZ2UgPSBvcmlnaW5hbERhdGE/LmRhdGE/Lm1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZWRQYXJ0aWFsID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzb3VyY2UgPSBvcmlnaW5hbERhdGE/LmRhdGE/LnJlY2VpdmVkRGF0YT8uc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb24gPSBvcmlnaW5hbERhdGE/LmRhdGE/LnJlY2VpdmVkRGF0YT8uZXh0ZW5zaW9uTmFtZQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGRlcml2ZWQgdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2VkVGltZXN0YW1wID0gRGF0ZVRpbWUuVXRjTm93LgogICAgICAgICAgICAgICAgICAgICAgICBBZGRIb3Vycyg1KS4gLy8gQWRkIDUgaG91cnMKICAgICAgICAgICAgICAgICAgICAgICAgVG9TdHJpbmcoIk8iKSwKICAgICAgICAgICAgICAgICAgICBjdXN0b21SZXF1ZXN0SWQgPSAkIlRSQU5TLXtHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLlN1YnN0cmluZygwLCA4KS5Ub1VwcGVyKCl9IiwKICAgICAgICAgICAgICAgICAgICAvLyBBZGQgYW5hbHl0aWNzCiAgICAgICAgICAgICAgICAgICAgYW5hbHl0aWNzID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBkYXRhU2l6ZUJ5dGVzID0gU3lzdGVtLlRleHQuRW5jb2RpbmcuVVRGOC5HZXRCeXRlQ291bnQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0uVGV4dC5Kc29uLkpzb25TZXJpYWxpemVyLlNlcmlhbGl6ZShvcmlnaW5hbERhdGEpCiAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkQ291bnQgPSAzLCAvLyB0YXNrVHlwZSwgbWVzc2FnZSwgcmVjZWl2ZWREYXRhCiAgICAgICAgICAgICAgICAgICAgICAgIHByb2Nlc3NpbmdUaW1lTXMgPSBtZXRhZGF0YT8ucmVzcG9uc2VUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzUmF0ZSA9IDEwMC4wCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAvLyBBZGQgZW5yaWNobWVudAogICAgICAgICAgICAgICAgICAgIGVucmljaG1lbnQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhdGVnb3J5ID0gIkFQSV9URVNUIiwKICAgICAgICAgICAgICAgICAgICAgICAgcHJpb3JpdHkgPSAiSElHSCIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRhZ3MgPSBuZXdbXSB7ICJ0cmFuc2Zvcm1lZCIsICJlbnJpY2hlZCIsICJhbmFseXplZCIgfSwKICAgICAgICAgICAgICAgICAgICAgICAgdmVyaWZpZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBlbnJpY2hlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdmFsaWRhdGlvbiByZXN1bHRzCiAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXNWYWxpZCA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25FcnJvcnMgPSBuZXcgb2JqZWN0W10geyB9LAogICAgICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRGaWVsZHMgPSBuZXdbXSB7ICJ0YXNrVHlwZSIsICJtZXNzYWdlIiwgInJlcXVlc3RJZCIgfSwKICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAidGVzdC1odHRwLXRyYW5zZm9ybS1leHRlbnNpb24tc3VjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gVHJhbnNmb3JtZWQgYW5kIGVucmljaGVkIGRhdGEKICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWREYXRhID0gdHJhbnNmb3JtZWREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAvLyBPcmlnaW5hbCBkYXRhIGZvciByZWZlcmVuY2UKICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxEYXRhID0gb3JpZ2luYWxEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAvLyBNZXRhZGF0YQogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25NZXRhZGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25OYW1lID0gInRlc3QtaHR0cC10cmFuc2Zvcm0tZXh0ZW5zaW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybWF0aW9uVHlwZSA9ICJlbnJpY2htZW50K2FuYWx5dGljcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gSFRUUCByZXF1ZXN0IGZhaWxlZAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJ0ZXN0LWh0dHAtdHJhbnNmb3JtLWV4dGVuc2lvbi1mYWlsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkhUVFAgcmVxdWVzdCBmYWlsZWQiLAogICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IHJlc3BvbnNlPy5lcnJvck1lc3NhZ2UgPz8gIlVua25vd24gZXJyb3IiLAogICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk1ldGFkYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25OYW1lID0gInRlc3QtaHR0cC10cmFuc2Zvcm0tZXh0ZW5zaW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAidGVzdC1odHRwLXRyYW5zZm9ybS1leHRlbnNpb24tZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgZXh0ZW5zaW9uTWV0YWRhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbk5hbWUgPSAidGVzdC1odHRwLXRyYW5zZm9ybS1leHRlbnNpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - } -} \ No newline at end of file diff --git a/core/Functions/account-opening/multi-task-function-test.json b/core/Functions/account-opening/multi-task-function-test.json index 459ba98..abbe21f 100644 --- a/core/Functions/account-opening/multi-task-function-test.json +++ b/core/Functions/account-opening/multi-task-function-test.json @@ -25,7 +25,7 @@ }, "mapping": { "location": "./src/FunctionValidatePoliciesMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGFzayAxIG1hcHBpbmcgZm9yIG11bHRpLXRhc2sgZnVuY3Rpb24gdGVzdC4KLy8vIENhbGxzIHZhbGlkYXRlLWFjY291bnQtcG9saWNpZXMgSFRUUCB0YXNrIHdpdGggaW5zdGFuY2UgZGF0YS4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEZ1bmN0aW9uVmFsaWRhdGVQb2xpY2llc01hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICBpZiAoaHR0cFRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CgogICAgICAgIHZhciB1c2VyU2Vzc2lvbiA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnVzZXJTZXNzaW9uOwogICAgICAgIHZhciBhY2NvdW50VHlwZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFjY291bnRUeXBlOwoKICAgICAgICBodHRwVGFzay5TZXRCb2R5KG5ldwogICAgICAgIHsKICAgICAgICAgICAgdXNlcklkID0gdXNlclNlc3Npb24/LnVzZXJJZCwKICAgICAgICAgICAgYWNjb3VudFR5cGUgPSBhY2NvdW50VHlwZSA/PyAiZGVtYW5kLWRlcG9zaXQiLAogICAgICAgICAgICBjdXJyZW5jeSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmN1cnJlbmN5LAogICAgICAgICAgICByZXF1ZXN0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgIH0pOwoKICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICB7CiAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgIFsiWC1JbnN0YW5jZS1JZCJdID0gY29udGV4dC5JbnN0YW5jZT8uSWQuVG9TdHJpbmcoKSwKICAgICAgICAgICAgWyJYLVJlcXVlc3QtSWQiXSA9IGNvbnRleHQuSGVhZGVycz9bIngtcmVxdWVzdC1pZCJdID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCkKICAgICAgICB9KTsKCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBLZXkgPSAicG9saWN5LWNoZWNrLXJlc3VsdCIsCiAgICAgICAgICAgIERhdGEgPSBjb250ZXh0LkJvZHkKICAgICAgICB9KTsKICAgIH0KfQo=" + "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGFzayAxIG1hcHBpbmcgZm9yIG11bHRpLXRhc2sgZnVuY3Rpb24gdGVzdC4KLy8vIENhbGxzIHZhbGlkYXRlLWFjY291bnQtcG9saWNpZXMgSFRUUCB0YXNrIHdpdGggaW5zdGFuY2UgZGF0YS4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEZ1bmN0aW9uVmFsaWRhdGVQb2xpY2llc01hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazs7OwogICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKCiAgICAgICAgdmFyIHVzZXJTZXNzaW9uID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udXNlclNlc3Npb247CiAgICAgICAgdmFyIGFjY291bnRUeXBlID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uYWNjb3VudFR5cGU7CgogICAgICAgIGh0dHBUYXNrLlNldEJvZHkobmV3CiAgICAgICAgewogICAgICAgICAgICB1c2VySWQgPSB1c2VyU2Vzc2lvbj8udXNlcklkLAogICAgICAgICAgICBhY2NvdW50VHlwZSA9IGFjY291bnRUeXBlID8/ICJkZW1hbmQtZGVwb3NpdCIsCiAgICAgICAgICAgIGN1cnJlbmN5ID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uY3VycmVuY3ksCiAgICAgICAgICAgIHJlcXVlc3RlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgfSk7CgogICAgICAgIGh0dHBUYXNrLlNldEhlYWRlcnMobmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgIHsKICAgICAgICAgICAgWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi9qc29uIiwKICAgICAgICAgICAgWyJYLUluc3RhbmNlLUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlPy5JZC5Ub1N0cmluZygpLAogICAgICAgICAgICBbIlgtUmVxdWVzdC1JZCJdID0gY29udGV4dC5IZWFkZXJzP1sieC1yZXF1ZXN0LWlkIl0gPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKQogICAgICAgIH0pOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICB7CiAgICAgICAgICAgIEtleSA9ICJwb2xpY3ktY2hlY2stcmVzdWx0IiwKICAgICAgICAgICAgRGF0YSA9IGNvbnRleHQuQm9keQogICAgICAgIH0pOwogICAgfQp9Cg==" } }, { diff --git a/core/Functions/account-opening/src/FunctionValidatePoliciesMapping.csx b/core/Functions/account-opening/src/FunctionValidatePoliciesMapping.csx index a934123..7e18a1f 100644 --- a/core/Functions/account-opening/src/FunctionValidatePoliciesMapping.csx +++ b/core/Functions/account-opening/src/FunctionValidatePoliciesMapping.csx @@ -12,7 +12,7 @@ public class FunctionValidatePoliciesMapping : IMapping { public Task InputHandler(WorkflowTask task, ScriptContext context) { - var httpTask = task as HttpTask; + var httpTask = task as HttpTask;;; if (httpTask == null) return Task.FromResult(new ScriptResponse()); diff --git a/core/Functions/payments/function-get-user-info.json b/core/Functions/payments/function-get-user-info.json index d3be39e..0d59fde 100644 --- a/core/Functions/payments/function-get-user-info.json +++ b/core/Functions/payments/function-get-user-info.json @@ -26,6 +26,6 @@ "location": "./src/GetUserInfoMapping.csx", "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIEdldFVzZXJJbmZvTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwoKICAgICAgICAgICAgdmFyIHVzZXJJZCA9IGNvbnRleHQuQm9keT8udXNlcklkOwoKICAgICAgICAgICAgLy8gVXBkYXRlIFVSTCB3aXRoIHVzZXJJZAogICAgICAgICAgICBodHRwVGFzay5TZXRVcmwoaHR0cFRhc2suVXJsLlJlcGxhY2UoInt1c2VySWR9IiwgdXNlcklkPy5Ub1N0cmluZygpID8/ICIiKSk7CgogICAgICAgICAgICAvLyBTZXQgSGVhZGVycwogICAgICAgICAgICB2YXIgaGVhZGVycyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi9qc29uIiwKICAgICAgICAgICAgICAgIFsiQWNjZXB0Il0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgICAgICBbIlgtUmVxdWVzdC1JZCJdID0gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaHR0cFRhc2suU2V0SGVhZGVycyhoZWFkZXJzKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInVzZXItaW5mby1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMDsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9IGNvbnRleHQuQm9keT8uZGF0YTsKCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDwgMzAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInVzZXItaW5mby1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB1c2VyID0gcmVzcG9uc2VEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBwaG9uZU51bWJlciA9IHJlc3BvbnNlRGF0YT8ucGhvbmVOdW1iZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIGhhc1JlZ2lzdGVyZWREZXZpY2VzID0gKChvYmplY3RbXSlyZXNwb25zZURhdGE/LnJlZ2lzdGVyZWREZXZpY2VzKS5MZW5ndGggPiAwLAogICAgICAgICAgICAgICAgICAgICAgICBsYW5ndWFnZSA9IHJlc3BvbnNlRGF0YT8ubGFuZ3VhZ2UgPz8gInRyLVRSIgogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInVzZXJzIiwgImxvb2t1cCIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJ1c2VyLWluZm8tZmFpbHVyZSIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRmFpbGVkIHRvIGdldCB1c2VyIGluZm9ybWF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gInVzZXJfaW5mb19mYWlsZWQiLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gc3RhdHVzQ29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgaGFzUmVnaXN0ZXJlZERldmljZXMgPSBmYWxzZQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInVzZXJzIiwgImxvb2t1cCIsICJmYWlsdXJlIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJ1c2VyLWluZm8tZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJJbnRlcm5hbCBwcm9jZXNzaW5nIGVycm9yIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckNvZGUgPSAicHJvY2Vzc2luZ19lcnJvciIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JEZXNjcmlwdGlvbiA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgaGFzUmVnaXN0ZXJlZERldmljZXMgPSBmYWxzZQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJ1c2VycyIsICJsb29rdXAiLCAiZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0K" } - }, + } } } \ No newline at end of file diff --git a/core/Schemas/account-opening/account-details-input.json b/core/Schemas/account-opening/account-details-input.json index 62b50a3..05e5861 100644 --- a/core/Schemas/account-opening/account-details-input.json +++ b/core/Schemas/account-opening/account-details-input.json @@ -52,6 +52,10 @@ { "const": "GBP", "description": "British Pound" + }, + { + "const": "SLV", + "description": "Solomon Islands Dollar" } ] }, diff --git a/core/Schemas/discovery/domain-start-schema.json b/core/Schemas/discovery/domain-start-schema.json deleted file mode 100644 index 6fdd921..0000000 --- a/core/Schemas/discovery/domain-start-schema.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "key": "domain-start", - "version": "1.0.0", - "domain": "core", - "flow": "sys-schemas", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "workflow", - "instance", - "lookup", - "registration" - ], - "attributes": { - "type": "workflow", - "schema": { - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://schemas.vnext.com/banking/domain-start.json", - "title": "Domain start transition Schema", - "description": "Domain start transition Schema", - "type": "object", - "required": [ - "domainName" - ], - "properties": { - "domainName": { - "type": "string", - "description": "Domain name identifier" - }, - "baseUrl": { - "type": "string", - "description": "Base URL of the domain service" - }, - "healthUrl": { - "type": "string", - "description": "Health check URL of the domain service" - }, - "appId": { - "type": "string", - "description": "Application identifier" - } - }, - "additionalProperties": false - } - } -} \ No newline at end of file diff --git a/core/Schemas/discovery/domain-update-schema.json b/core/Schemas/discovery/domain-update-schema.json deleted file mode 100644 index a3fc34e..0000000 --- a/core/Schemas/discovery/domain-update-schema.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "key": "domain-update", - "version": "1.0.0", - "domain": "core", - "flow": "sys-schemas", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "workflow", - "instance", - "lookup", - "registration" - ], - "attributes": { - "type": "workflow", - "schema": { - "$id": "https://schemas.vnext.com/banking/domain-update.json", - "title": "Domain update transition Schema", - "description": "Domain update transition Schema", - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "required": [ - "domainName" - ], - "properties": { - "domainName": { - "type": "string", - "description": "Domain name identifier" - }, - "baseUrl": { - "type": "string", - "description": "Base URL of the domain service" - }, - "healthUrl": { - "type": "string", - "description": "Health check URL of the domain service" - }, - "appId": { - "type": "string", - "description": "Application identifier" - }, - "eTag": { - "type": "string", - "description": "Entity tag for optimistic concurrency control" - } - }, - "additionalProperties": false - } - } -} \ No newline at end of file diff --git a/core/Tasks/account-opening/user-session.json b/core/Tasks/account-opening/user-session.json deleted file mode 100644 index dc900af..0000000 --- a/core/Tasks/account-opening/user-session.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "key": "user-session", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "banking", - "account-creation", - "demand-deposit", - "core-banking", - "account-opening" - ], - "attributes": { - "type": "7", - "config": {} - } - } - \ No newline at end of file diff --git a/core/Tasks/contract/get-contract-documents.json b/core/Tasks/contract/get-contract-documents.json deleted file mode 100644 index 6af2cec..0000000 --- a/core/Tasks/contract/get-contract-documents.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "get-contract-documents", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "contract", - "documents", - "http", - "get-list" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/contract/get-documents", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 30, - "validateSsl": true - } - } -} - diff --git a/core/Tasks/contract/notify-document-approved.json b/core/Tasks/contract/notify-document-approved.json deleted file mode 100644 index 3a945c2..0000000 --- a/core/Tasks/contract/notify-document-approved.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "key": "notify-document-approved", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "contract", - "notification", - "direct-trigger", - "document-approved" - ], - "attributes": { - "type": "12", - "config": { - "domain": "core", - "flow": "contract-approval-workflow", - "transitionName": "document-approved", - "body": {} - } - } -} - diff --git a/core/Tasks/contract/notify-document-ready.json b/core/Tasks/contract/notify-document-ready.json deleted file mode 100644 index 2d66498..0000000 --- a/core/Tasks/contract/notify-document-ready.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "key": "notify-document-ready", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "contract", - "notification", - "direct-trigger", - "document-ready" - ], - "attributes": { - "type": "12", - "config": { - "domain": "core", - "flow": "contract-approval-workflow", - "transitionName": "document-ready", - "body": {} - } - } -} - diff --git a/core/Tasks/contract/render-document.json b/core/Tasks/contract/render-document.json deleted file mode 100644 index 1ca4f4c..0000000 --- a/core/Tasks/contract/render-document.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "render-document", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "contract", - "document", - "render", - "http" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/contract/render-document", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 30, - "validateSsl": true - } - } -} - diff --git a/core/Tasks/contract/start-document-subprocess.json b/core/Tasks/contract/start-document-subprocess.json deleted file mode 100644 index b1de5d3..0000000 --- a/core/Tasks/contract/start-document-subprocess.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "key": "start-document-subprocess", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "contract", - "subprocess", - "start", - "document-process" - ], - "attributes": { - "type": "14", - "config": { - "domain": "core", - "flow": "contract-document-subflow", - "body": {} - } - } -} - diff --git a/core/Tasks/discovery/check-domain-exists.json b/core/Tasks/discovery/check-domain-exists.json deleted file mode 100644 index 3e1d982..0000000 --- a/core/Tasks/discovery/check-domain-exists.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "key": "check-domain-exists", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "workflow", - "instance", - "lookup", - "registration" - ], - "attributes": { - "type": "3", - "config": { - "appId": "{{discoveryAPPId}}", - "methodName": "/api/v1/core/workflows/domain/instances/{domainName}/functions/data", - "httpVerb": "GET" - } - } -} - diff --git a/core/Tasks/discovery/check-health-endpoint.json b/core/Tasks/discovery/check-health-endpoint.json deleted file mode 100644 index b27bfce..0000000 --- a/core/Tasks/discovery/check-health-endpoint.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "key": "check-health-endpoint", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "health-check", - "http", - "monitoring" - ], - "attributes": { - "type": "6", - "config": { - "url": "", - "method": "GET", - "headers": { - "Content-Type": "application/json" - }, - "timeoutSeconds": 5, - "validateSsl": true - } - } -} - diff --git a/core/Tasks/discovery/fetch-domains-list.json b/core/Tasks/discovery/fetch-domains-list.json deleted file mode 100644 index 597b440..0000000 --- a/core/Tasks/discovery/fetch-domains-list.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "key": "fetch-domains-list", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "api", - "http", - "fetch", - "pagination" - ], - "attributes": { - "type": "6", - "config": { - "url": "{{discoveryBaseUrl}}/api/v1/core/workflows/domain/functions/data?Page=1&PageSize=10", - "method": "GET", - "headers": { - "Content-Type": "application/json", - "accept": "*/*" - }, - "timeoutSeconds": 30, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/discovery/get-domain-health-url.json b/core/Tasks/discovery/get-domain-health-url.json deleted file mode 100644 index 99ea987..0000000 --- a/core/Tasks/discovery/get-domain-health-url.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "key": "get-domain-health-url", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "redis", - "health-check", - "lookup" - ], - "attributes": { - "type": "6", - "config": { - "url": "{{discoveryDaprUrl}}/v1.0/state/vnext-execution-state/domain:{domainName}", - "method": "GET", - "headers": { - "Content-Type": "application/json" - }, - "timeoutSeconds": 10, - "validateSsl": true - } - } -} - diff --git a/core/Tasks/discovery/register-domain-lifecycle.json b/core/Tasks/discovery/register-domain-lifecycle.json deleted file mode 100644 index d206823..0000000 --- a/core/Tasks/discovery/register-domain-lifecycle.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "key": "register-domain-lifecycle", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "start", - "lifecycle", - "register" - ], - "attributes": { - "type": "11", - "config": { - "domain": "core", - "flow": "domain" - } - } -} - diff --git a/core/Tasks/discovery/register-domain.json b/core/Tasks/discovery/register-domain.json deleted file mode 100644 index 438cb97..0000000 --- a/core/Tasks/discovery/register-domain.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "register-domain", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "redis", - "create", - "registration" - ], - "attributes": { - "type": "6", - "config": { - "url": "{{discoveryDaprUrl}/v1.0/state/vnext-execution-state", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/discovery/schedule-health-check.json b/core/Tasks/discovery/schedule-health-check.json deleted file mode 100644 index a7213a0..0000000 --- a/core/Tasks/discovery/schedule-health-check.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "key": "schedule-health-check", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "subprocess", - "health-check", - "trigger" - ], - "attributes": { - "type": "14", - "config": { - "domain": "core", - "flow": "domain-health-check", - "version": "1.0.0" - } - } -} - - - diff --git a/core/Tasks/discovery/update-domain-lifecycle.json b/core/Tasks/discovery/update-domain-lifecycle.json deleted file mode 100644 index 1026f52..0000000 --- a/core/Tasks/discovery/update-domain-lifecycle.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "key": "update-domain-lifecycle", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "trigger", - "lifecycle", - "update" - ], - "attributes": { - "type": "12", - "config": { - "domain": "core", - "flow": "domain", - "transitionName": "update" - } - } -} - diff --git a/core/Tasks/discovery/update-domain.json b/core/Tasks/discovery/update-domain.json deleted file mode 100644 index 1f5b4f3..0000000 --- a/core/Tasks/discovery/update-domain.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "update-domain", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "redis", - "update", - "registration" - ], - "attributes": { - "type": "6", - "config": { - "url": "{{discoveryDaprUrl}/v1.0/state/vnext-execution-state", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/discovery/update-health-status.json b/core/Tasks/discovery/update-health-status.json deleted file mode 100644 index 475e0a9..0000000 --- a/core/Tasks/discovery/update-health-status.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "update-health-status", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "domain", - "redis", - "health-check", - "update" - ], - "attributes": { - "type": "6", - "config": { - "url": "{{discoveryDaprUrl}/v1.0/state/vnext-execution-state", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/morph-touch/start-transfer-from-absence-entry.json b/core/Tasks/morph-touch/start-transfer-from-absence-entry.json deleted file mode 100644 index 07327e3..0000000 --- a/core/Tasks/morph-touch/start-transfer-from-absence-entry.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "key": "start-transfer-from-absence-entry", - "flow": "sys-tasks", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "absence-entry", - "transfer", - "start-task" - ], - "attributes": { - "type": "11", - "labels": [ - { - "label": "Start Transfer from Absence Entry", - "language": "en-US" - }, - { - "label": "Yokluk Kaydından Transfer Başlat", - "language": "tr-TR" - } - ], - "description": "StartTask that starts a rezervation-transfer subflow when a personal-leave absence-entry is created.", - "config": { - "domain": "touch", - "flow": "rezervation-transfer" - } - } -} \ No newline at end of file diff --git a/core/Tasks/oauth/check-device-registration.json b/core/Tasks/oauth/check-device-registration.json deleted file mode 100644 index e8b4414..0000000 --- a/core/Tasks/oauth/check-device-registration.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "check-device-registration", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "device-registration", - "mfa", - "user-device", - "security" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/devices/check/", - "method": "GET", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 5, - "validateSsl": true - } - } -} diff --git a/core/Tasks/oauth/check-push-denied-response.json b/core/Tasks/oauth/check-push-denied-response.json deleted file mode 100644 index 50171f9..0000000 --- a/core/Tasks/oauth/check-push-denied-response.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "key": "check-push-denied-response", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "push-notification", - "mfa", - "response-check", - "approval" - ], - "attributes": { - "type": "7", - "config": { - } - } -} diff --git a/core/Tasks/oauth/check-push-response.json b/core/Tasks/oauth/check-push-response.json deleted file mode 100644 index fd90b2e..0000000 --- a/core/Tasks/oauth/check-push-response.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "check-push-response", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "push-notification", - "mfa", - "response-check", - "approval" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/push/status", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 5, - "validateSsl": true - } - } -} diff --git a/core/Tasks/oauth/generate-tokens.json b/core/Tasks/oauth/generate-tokens.json deleted file mode 100644 index 4a7a1c3..0000000 --- a/core/Tasks/oauth/generate-tokens.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "generate-tokens", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "token-generation", - "jwt", - "access-token", - "refresh-token" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/tokens/generate", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 5, - "validateSsl": true - } - } -} diff --git a/core/Tasks/oauth/register-device.json b/core/Tasks/oauth/register-device.json deleted file mode 100644 index 78bf3c4..0000000 --- a/core/Tasks/oauth/register-device.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "register-device", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "device-registration", - "mfa", - "user-device", - "security" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/devices/register", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 5, - "validateSsl": true - } - } -} diff --git a/core/Tasks/oauth/send-otp-notification.json b/core/Tasks/oauth/send-otp-notification.json deleted file mode 100644 index 907e43a..0000000 --- a/core/Tasks/oauth/send-otp-notification.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "key": "send-otp-notification", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "otp", - "notification", - "mfa", - "sms", - "email" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/otp/send", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": true - } - } -} diff --git a/core/Tasks/oauth/send-push-notification.json b/core/Tasks/oauth/send-push-notification.json deleted file mode 100644 index 3cbcd1e..0000000 --- a/core/Tasks/oauth/send-push-notification.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "send-push-notification", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "push-notification", - "mfa", - "mobile", - "approval" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/push/send", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": true - } - } -} diff --git a/core/Tasks/oauth/validate-authorization-code.json b/core/Tasks/oauth/validate-authorization-code.json deleted file mode 100644 index 50eea10..0000000 --- a/core/Tasks/oauth/validate-authorization-code.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "validate-authorization-code", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "authorization-code", - "authentication", - "pkce", - "security" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/user/validate-authorization-code", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": true - } - } -} diff --git a/core/Tasks/oauth/validate-client.json b/core/Tasks/oauth/validate-client.json deleted file mode 100644 index 5b1c580..0000000 --- a/core/Tasks/oauth/validate-client.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "key": "validate-client", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "client-validation", - "authentication", - "security" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/client/validate", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 5, - "validateSsl": true - } - } -} diff --git a/core/Tasks/oauth/validate-user-credentials.json b/core/Tasks/oauth/validate-user-credentials.json deleted file mode 100644 index cc4150a..0000000 --- a/core/Tasks/oauth/validate-user-credentials.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "validate-user-credentials", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "user-validation", - "authentication", - "password", - "credentials" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/user/authenticate", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": true - } - } -} diff --git a/core/Tasks/oauth/verify-otp-code.json b/core/Tasks/oauth/verify-otp-code.json deleted file mode 100644 index a74759a..0000000 --- a/core/Tasks/oauth/verify-otp-code.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "verify-otp-code", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "oauth2", - "otp", - "verification", - "mfa", - "two-factor" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/oauth2/otp/verify", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 5, - "validateSsl": true - } - } -} diff --git a/core/Tasks/subflow-test/trigger-busy-completion-task.json b/core/Tasks/subflow-test/trigger-busy-completion-task.json index f5c8a5d..c30af43 100644 --- a/core/Tasks/subflow-test/trigger-busy-completion-task.json +++ b/core/Tasks/subflow-test/trigger-busy-completion-task.json @@ -14,7 +14,7 @@ "type": "12", "config": { "domain": "core", - "flow": "sys-flows", + "flow": "subflow-view-test-grandchild", "transitionName": "complete-busy-state", "body": {} } diff --git a/core/Tasks/task-test/error-boundary-abort-task.json b/core/Tasks/task-test/error-boundary-abort-task.json deleted file mode 100644 index 2a9bcd4..0000000 --- a/core/Tasks/task-test/error-boundary-abort-task.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "key": "error-boundary-abort-task", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "error-boundary", - "abort", - "http", - "test", - "500" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/error-boundary/simulate-500", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/task-test/error-boundary-ignore-task.json b/core/Tasks/task-test/error-boundary-ignore-task.json deleted file mode 100644 index 208795e..0000000 --- a/core/Tasks/task-test/error-boundary-ignore-task.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "key": "error-boundary-ignore-task", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "error-boundary", - "ignore", - "http", - "test", - "400" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/error-boundary/simulate-400", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/task-test/error-boundary-retry-task.json b/core/Tasks/task-test/error-boundary-retry-task.json deleted file mode 100644 index 773beae..0000000 --- a/core/Tasks/task-test/error-boundary-retry-task.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "key": "error-boundary-retry-task", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "error-boundary", - "retry", - "http", - "test", - "503" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/error-boundary/simulate-503", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/task-test/error-boundary-success-task.json b/core/Tasks/task-test/error-boundary-success-task.json deleted file mode 100644 index 9f4e85a..0000000 --- a/core/Tasks/task-test/error-boundary-success-task.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "error-boundary-success-task", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "error-boundary", - "success", - "http", - "test" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/error-boundary/simulate-success", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 10, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/task-test/error-boundary-timeout-task.json b/core/Tasks/task-test/error-boundary-timeout-task.json deleted file mode 100644 index 7e33120..0000000 --- a/core/Tasks/task-test/error-boundary-timeout-task.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "error-boundary-timeout-task", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "error-boundary", - "timeout", - "http", - "test" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/error-boundary/simulate-timeout", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 5, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/task-test/test-dapr-pubsub.json b/core/Tasks/task-test/test-dapr-pubsub.json deleted file mode 100644 index 5a67392..0000000 --- a/core/Tasks/task-test/test-dapr-pubsub.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "test-dapr-pubsub", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "dapr", - "pubsub", - "messaging", - "event" - ], - "attributes": { - "type": "4", - "config": { - "pubSubName": "vnext-execution-pubsub", - "topic": "vnext.test.events", - "data": {}, - "metadata": { - "priority": "normal", - "source": "task-test-workflow" - } - } - } -} - diff --git a/core/Tasks/task-test/test-dapr-service-task.json b/core/Tasks/task-test/test-dapr-service-task.json deleted file mode 100644 index 1a02f7f..0000000 --- a/core/Tasks/task-test/test-dapr-service-task.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "key": "test-dapr-service-task", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "dapr", - "service-invocation", - "microservice" - ], - "attributes": { - "type": "3", - "config": { - "appId": "mockoon", - "methodName": "/api/api/task-test/dapr-endpoint", - "httpVerb": "POST", - "queryString": "", - "timeoutSeconds": 30 - } - } -} - diff --git a/core/Tasks/task-test/test-direct-transition.json b/core/Tasks/task-test/test-direct-transition.json deleted file mode 100644 index bd44b39..0000000 --- a/core/Tasks/task-test/test-direct-transition.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "key": "test-direct-transition", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "direct-trigger", - "transition", - "workflow-communication" - ], - "attributes": { - "type": "12", - "config": { - "domain": "core", - "flow": "task-test-subflow", - "transitionName": "complete-subflow", - "body": {} - } - } -} - diff --git a/core/Tasks/task-test/test-get-instance-data.json b/core/Tasks/task-test/test-get-instance-data.json deleted file mode 100644 index b9460f6..0000000 --- a/core/Tasks/task-test/test-get-instance-data.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "key": "test-get-instance-data", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "instance-data", - "workflow-communication", - "data-fetch" - ], - "attributes": { - "type": "13", - "config": { - "domain": "onboarding", - "flow": "task-test-subflow", - "extensions": [] - } - } -} - diff --git a/core/Tasks/task-test/test-get-instances.json b/core/Tasks/task-test/test-get-instances.json deleted file mode 100644 index 167d43a..0000000 --- a/core/Tasks/task-test/test-get-instances.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "key": "test-get-instances", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "instances", - "workflow-communication", - "data-fetch", - "filter-test", - "pagination" - ], - "attributes": { - "type": "15", - "config": { - "domain": "core", - "flow": "task-test-subflow", - "page": 1, - "pageSize": 10, - "sort": "-CreatedAt" - } - } -} - diff --git a/core/Tasks/task-test/test-http-items.json b/core/Tasks/task-test/test-http-items.json deleted file mode 100644 index 7cb237d..0000000 --- a/core/Tasks/task-test/test-http-items.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "test-http-items", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "http", - "api", - "external-service" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/task-test/list-items", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 30, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/task-test/test-http-task.json b/core/Tasks/task-test/test-http-task.json deleted file mode 100644 index 2b3977c..0000000 --- a/core/Tasks/task-test/test-http-task.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "key": "test-http-task", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "http", - "api", - "external-service" - ], - "attributes": { - "type": "6", - "config": { - "url": "http://localhost:3001/api/task-test/http-endpoint", - "method": "POST", - "headers": { - "Content-Type": "application/json" - }, - "body": {}, - "timeoutSeconds": 30, - "validateSsl": false - } - } -} - diff --git a/core/Tasks/task-test/test-start-workflow.json b/core/Tasks/task-test/test-start-workflow.json deleted file mode 100644 index b4c6348..0000000 --- a/core/Tasks/task-test/test-start-workflow.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "key": "test-start-workflow", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "start", - "workflow-initiation", - "new-instance" - ], - "attributes": { - "type": "11", - "config": { - "domain": "core", - "flow": "task-test-subflow", - "body": {} - } - } -} - diff --git a/core/Tasks/task-test/test-subprocess.json b/core/Tasks/task-test/test-subprocess.json deleted file mode 100644 index cc93e57..0000000 --- a/core/Tasks/task-test/test-subprocess.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "key": "test-subprocess", - "version": "1.0.0", - "domain": "core", - "flow": "sys-tasks", - "flowVersion": "1.0.0", - "tags": [ - "task-test", - "subprocess", - "fire-and-forget", - "background-task" - ], - "attributes": { - "type": "14", - "config": { - "domain": "contract", - "flow": "task-test-subflow", - "version": "1.0.0", - "body": {}, - "validateSsl": false - } - } -} - diff --git a/core/Workflows/account-opening/.meta/account-opening-workflow.diagram.json b/core/Workflows/account-opening/.meta/account-opening-workflow.diagram.json index 474d930..cd0bdde 100644 --- a/core/Workflows/account-opening/.meta/account-opening-workflow.diagram.json +++ b/core/Workflows/account-opening/.meta/account-opening-workflow.diagram.json @@ -25,8 +25,8 @@ "y": 1400 }, "cancelled": { - "x": 100, - "y": 100 + "x": 160, + "y": -200 }, "__start__": { "x": 840, diff --git a/core/Workflows/account-opening/account-opening-workflow.http b/core/Workflows/account-opening/account-opening-workflow.http deleted file mode 100644 index 88259b4..0000000 --- a/core/Workflows/account-opening/account-opening-workflow.http +++ /dev/null @@ -1,209 +0,0 @@ -############################################################################### -# Account Opening Workflow - HTTP Test File -# -# This file tests the account-opening workflow which handles: -# - Account type selection (demand deposit, time deposit, etc.) -# - Account details input and validation -# - Policy validation -# - Account creation confirmation -# - Bank account creation via external API -# -# Prerequisites: -# 1. vNext Runtime running on localhost:4201 -# 2. Mockoon running on localhost:3001 -############################################################################### - -@baseUrl = http://localhost:4201 -@apiVersion = 1 -@domain = core -@workflow = account-opening -@instanceKey = account-{{$timestamp}} - -############################################################################### -# Step 1: Start Account Opening Workflow -# Initiates the account opening flow with session information -############################################################################### - -### Start Account Opening Instance -# @name startAccountOpening -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start?sync=true -Content-Type: application/json -Accept-Language: tr-TR -X-Request-Id: {{$guid}} -X-Device-Id: {{$guid}} -X-Token-Id: {{$guid}} -X-Device-Info: IOS 16 -X-Forwarded-For: 192.168.2.1 -user_reference: 34987491018 - -{ - "key": "{{instanceKey}}", - "tags": [ - "test", - "banking", - "account-opening" - ], - "attributes": { - "session": "session-{{$timestamp}}" - } -} - -############################################################################### -# Step 2: Get Current State -# Check the current state after workflow start -############################################################################### - -### Get Current State -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -############################################################################### -# Step 3: Get Current View -# Retrieve the UI view definition for current state -############################################################################### - -### Get Current View -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/view -Accept: application/json - -### Get Transition Schema -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/schema?transitionKey=select-demand-deposit -Accept: application/json - -############################################################################### -# Step 4: Select Account Type - Demand Deposit -# User selects the type of account to open -############################################################################### - -### Select Demand Deposit Account -# @name selectDemandDeposit -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/select-demand-deposit?sync=true -Content-Type: application/json - -{ - "key": "{{instanceKey}}", - "tags": [ - "test", - "banking", - "account-opening", - "demand-deposit" - ], - "attributes": { - "accountType": "demand-deposit" - } -} - -############################################################################### -# Step 4.1: Select Account Type - Time Deposit (Alternative) -# User selects time deposit account instead -############################################################################### - -### Select Time Deposit Account (Alternative) -# @name selectTimeDeposit -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/select-time-deposit?sync=true -Content-Type: application/json - -{ - "attributes": { - "accountType": "time-deposit" - } -} - -############################################################################### -# Step 5: Submit Account Details -# User provides detailed account configuration -############################################################################### - -### Submit Account Details -# @name submitAccountDetails -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/submit-account-details?sync=true -Content-Type: application/json - -{ - "attributes": { - "accountName": "My Demand Deposit Account", - "currency": "TRY", - "branchCode": "5436", - "initialDeposit": 100, - "accountPurpose": "personal-banking", - "notifications": { - "smsNotifications": true, - "emailNotifications": true, - "pushNotifications": true - } - } -} - -############################################################################### -# Step 6: Confirm Account Opening -# User confirms all details and accepts terms -############################################################################### - -### Confirm Account Opening -# @name confirmAccountOpening -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/confirm-account-opening?sync=true -Content-Type: application/json - -{ - "attributes": { - "confirmed": true, - "termsAccepted": true, - "privacyPolicyAccepted": true - } -} - -############################################################################### -# Step 7: Get Instance Data with Extensions -# Retrieve all instance data including user session extension data -############################################################################### - -### Get Instance Data with User Session Extension -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data?extensions=extension-user-session -Accept: application/json - -############################################################################### -# Step 8: Get Final Instance Data -# Retrieve all accumulated data including account details -############################################################################### - -### Get Final Instance Data -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -############################################################################### -# Cancel Flow -############################################################################### - -### Cancel Account Opening -# @name cancelAccountOpening -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/cancel?sync=false -Content-Type: application/json - -############################################################################### -# Back Navigation (Go to Previous State) -############################################################################### - -### Go Back from Account Details -# @name goBackFromDetails -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/back-to-type-selection?sync=true -Content-Type: application/json - -############################################################################### -# Account Opening Flow Summary -############################################################################### -# -# | Step | Transition | Description | -# |------|-------------------------|--------------------------------------| -# | 1 | start | Start with session info | -# | 2 | select-demand-deposit | Select demand deposit account type | -# | | select-time-deposit | OR select time deposit account type | -# | 3 | submit-account-details | Provide account configuration | -# | 4 | (auto) | Validate policies | -# | 5 | confirm-account-opening | Confirm and accept terms | -# | 6 | (auto) | Create bank account via API | -# | 7 | (complete) | Workflow completes successfully | -# | | cancel | Cancel at any point | -# | | back-to-type-selection | Go back to type selection | -# -############################################################################### - diff --git a/core/Workflows/account-opening/account-opening-workflow.json b/core/Workflows/account-opening/account-opening-workflow.json index 9b687d7..729722e 100644 --- a/core/Workflows/account-opening/account-opening-workflow.json +++ b/core/Workflows/account-opening/account-opening-workflow.json @@ -13,7 +13,15 @@ ], "attributes": { "type": "F", - "timeout": null, + "timeout": { + "key": "timeout", + "target": "timeouted", + "versionStrategy": "Minor", + "timer": { + "reset": "OnEntry", + "duration": "PT1M" + } + }, "labels": [ { "language": "en-US", @@ -80,7 +88,7 @@ { "order": 1, "task": { - "key": "user-session", + "key": "script-task", "domain": "core", "version": "1.0.0", "flow": "sys-tasks" @@ -535,7 +543,7 @@ }, "mapping": { "location": "./src/CreateBankAccountMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gQ3JlYXRlIEJhbmsgQWNjb3VudCBNYXBwaW5nIC0gQ3JlYXRlcyB0aGUgYWN0dWFsIGJhbmsgYWNjb3VudCBpbiBjb3JlIGJhbmtpbmcgc3lzdGVtCi8vLyBUaGlzIG1hcHBpbmcgY3JlYXRlcyB0aGUgZGVtYW5kIGRlcG9zaXQgYWNjb3VudCBpbiB0aGUgY29yZSBiYW5raW5nIHN5c3RlbS4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIENyZWF0ZUJhbmtBY2NvdW50TWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGFuIEh0dHBUYXNrIGZvciBhY2NvdW50IGNyZWF0aW9uIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEdldCBhbGwgcmVxdWlyZWQgZGF0YSBmcm9tIHdvcmtmbG93IGNvbnRleHQKICAgICAgICAgICAgdmFyIHVzZXJTZXNzaW9uID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udXNlclNlc3Npb247CiAgICAgICAgICAgIHZhciBhY2NvdW50VHlwZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFjY291bnRUeXBlOwogICAgICAgICAgICB2YXIgcG9saWN5VmFsaWRhdGlvbiA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnBvbGljeVZhbGlkYXRpb247CgogICAgICAgICAgICAvLyBQcmVwYXJlIHRoZSByZXF1ZXN0IGJvZHkgZm9yIGFjY291bnQgY3JlYXRpb24KICAgICAgICAgICAgdmFyIHJlcXVlc3RCb2R5ID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEFjY291bnQgaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgIGFjY291bnRUeXBlID0gYWNjb3VudFR5cGU/LmFjY291bnRUeXBlID8/ICJkZW1hbmQtZGVwb3NpdCIsCiAgICAgICAgICAgICAgICBhY2NvdW50TmFtZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFjY291bnROYW1lLAogICAgICAgICAgICAgICAgY3VycmVuY3kgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5jdXJyZW5jeSwKICAgICAgICAgICAgICAgIGJyYW5jaENvZGUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5icmFuY2hDb2RlLAogICAgICAgICAgICAgICAgaW5pdGlhbERlcG9zaXQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5pbml0aWFsRGVwb3NpdCA/PyAwLAogICAgICAgICAgICAgICAgYWNjb3VudFB1cnBvc2UgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5hY2NvdW50UHVycG9zZSwKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gQ3VzdG9tZXIgaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgIGN1c3RvbWVySWQgPSB1c2VyU2Vzc2lvbj8udXNlcklkLAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBBY2NvdW50IGxpbWl0cyBmcm9tIHBvbGljeSB2YWxpZGF0aW9uCiAgICAgICAgICAgICAgICBhY2NvdW50TGltaXRzID0gcG9saWN5VmFsaWRhdGlvbj8uYWNjb3VudExpbWl0cyA/PyBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkYWlseVRyYW5zYWN0aW9uTGltaXQgPSA1MDAwMCwKICAgICAgICAgICAgICAgICAgICBtb250aGx5VHJhbnNhY3Rpb25MaW1pdCA9IDUwMDAwMCwKICAgICAgICAgICAgICAgICAgICBtaW5pbXVtQmFsYW5jZSA9IDAsCiAgICAgICAgICAgICAgICAgICAgbWF4aW11bUJhbGFuY2UgPSAxMDAwMDAwCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBOb3RpZmljYXRpb24gcHJlZmVyZW5jZXMKICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbnMgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5ub3RpZmljYXRpb25zID8/IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNtc05vdGlmaWNhdGlvbnMgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgIGVtYWlsTm90aWZpY2F0aW9ucyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgcHVzaE5vdGlmaWNhdGlvbnMgPSB0cnVlCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBDb21wbGlhbmNlIGFuZCBhdWRpdCBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgY29tcGxpYW5jZUluZm8gPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uSWQgPSBwb2xpY3lWYWxpZGF0aW9uPy52YWxpZGF0aW9uSWQsCiAgICAgICAgICAgICAgICAgICAgcG9saWN5VmVyc2lvbiA9IHBvbGljeVZhbGlkYXRpb24/LnBvbGljeVZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgdGVybXNBY2NlcHRlZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRlcm1zQWNjZXB0ZWQsCiAgICAgICAgICAgICAgICAgICAgcHJpdmFjeVBvbGljeUFjY2VwdGVkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucHJpdmFjeVBvbGljeUFjY2VwdGVkLAogICAgICAgICAgICAgICAgICAgIGlwQWRkcmVzcyA9IHVzZXJTZXNzaW9uPy5pcEFkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgdXNlckFnZW50ID0gdXNlclNlc3Npb24/LnVzZXJBZ2VudAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gUmVxdWVzdCBtZXRhZGF0YQogICAgICAgICAgICAgICAgcmVxdWVzdElkID0gY29udGV4dC5IZWFkZXJzP1sieC1yZXF1ZXN0LWlkIl0gPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIHdvcmtmbG93SW5zdGFuY2VJZCA9IGNvbnRleHQuSW5zdGFuY2U/LklkLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICByZXF1ZXN0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBjb250ZXh0CiAgICAgICAgICAgICAgICBjaGFubmVsID0gImRpZ2l0YWwtYmFua2luZyIsCiAgICAgICAgICAgICAgICBzb3VyY2UgPSAiYWNjb3VudC1vcGVuaW5nLXdvcmtmbG93IgogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaHR0cFRhc2suU2V0Qm9keShyZXF1ZXN0Qm9keSk7CgogICAgICAgICAgICAvLyBTZXQgSGVhZGVycwogICAgICAgICAgICB2YXIgaGVhZGVycyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi9qc29uIiwKICAgICAgICAgICAgICAgIFsidXNlcl9yZWZlcmVuY2UiXSA9IHVzZXJTZXNzaW9uPy51c2VySWQ/LlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIlgtUmVxdWVzdC1JZCJdID0gcmVxdWVzdEJvZHkucmVxdWVzdElkLAogICAgICAgICAgICAgICAgWyJYLUluc3RhbmNlLUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlPy5JZC5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgWyJYLUFjY291bnQtVHlwZSJdID0gYWNjb3VudFR5cGU/LmFjY291bnRUeXBlPy5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgWyJYLUN1cnJlbmN5Il0gPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5jdXJyZW5jeT8uVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIFsiWC1CcmFuY2gtQ29kZSJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uYnJhbmNoQ29kZT8uVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIFsiWC1WYWxpZGF0aW9uLUlkIl0gPSBwb2xpY3lWYWxpZGF0aW9uPy52YWxpZGF0aW9uSWQ/LlRvU3RyaW5nKCkKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGh0dHBUYXNrLlNldEhlYWRlcnMoaGVhZGVycyk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgIH0KCiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gUHJvY2VzcyB0aGUgYWNjb3VudCBjcmVhdGlvbiByZXN1bHQgYW5kIG1lcmdlIGl0IGludG8gdGhlIHdvcmtmbG93IGluc3RhbmNlCiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHN0YXR1c0NvZGUgPSBHZXRTdGF0dXNDb2RlRnJvbVJlc3BvbnNlKGNvbnRleHQpOwogICAgICAgICAgICB2YXIgcmVzcG9uc2VEYXRhID0gR2V0UmVzcG9uc2VEYXRhRnJvbUNvbnRleHQoY29udGV4dCk7CgogICAgICAgICAgICAvLyBTdWNjZXNzZnVsIGFjY291bnQgY3JlYXRpb24KICAgICAgICAgICAgaWYgKHN0YXR1c0NvZGUgPj0gMjAwICYmIHN0YXR1c0NvZGUgPCAzMDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBhY2NvdW50Q3JlYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBjcmVhdGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gQWNjb3VudCBkZXRhaWxzCiAgICAgICAgICAgICAgICAgICAgYWNjb3VudElkID0gcmVzcG9uc2VEYXRhPy5hY2NvdW50SWQgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICBhY2NvdW50TnVtYmVyID0gcmVzcG9uc2VEYXRhPy5hY2NvdW50TnVtYmVyLAogICAgICAgICAgICAgICAgICAgIGliYW4gPSByZXNwb25zZURhdGE/LmliYW4sCiAgICAgICAgICAgICAgICAgICAgYWNjb3VudFR5cGUgPSByZXNwb25zZURhdGE/LmFjY291bnRUeXBlID8/ICJkZW1hbmQtZGVwb3NpdCIsCiAgICAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSByZXNwb25zZURhdGE/LmN1cnJlbmN5LAogICAgICAgICAgICAgICAgICAgIGJyYW5jaENvZGUgPSByZXNwb25zZURhdGE/LmJyYW5jaENvZGUsCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gQWNjb3VudCBzdGF0dXMKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSByZXNwb25zZURhdGE/LnN0YXR1cyA/PyAiYWN0aXZlIiwKICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZSA9IHJlc3BvbnNlRGF0YT8uaXNBY3RpdmUgPz8gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBCYWxhbmNlIGluZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgICAgY3VycmVudEJhbGFuY2UgPSByZXNwb25zZURhdGE/LmN1cnJlbnRCYWxhbmNlID8/IDAsCiAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlQmFsYW5jZSA9IHJlc3BvbnNlRGF0YT8uYXZhaWxhYmxlQmFsYW5jZSA/PyAwLAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIEFjY291bnQgbGltaXRzCiAgICAgICAgICAgICAgICAgICAgbGltaXRzID0gcmVzcG9uc2VEYXRhPy5saW1pdHMgPz8gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBkYWlseVRyYW5zYWN0aW9uTGltaXQgPSA1MDAwMCwKICAgICAgICAgICAgICAgICAgICAgICAgbW9udGhseVRyYW5zYWN0aW9uTGltaXQgPSA1MDAwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgIG1pbmltdW1CYWxhbmNlID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgbWF4aW11bUJhbGFuY2UgPSAxMDAwMDAwCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBDYXJkcyBhbmQgc2VydmljZXMKICAgICAgICAgICAgICAgICAgICBkZWJpdENhcmRSZXF1ZXN0ZWQgPSByZXNwb25zZURhdGE/LmRlYml0Q2FyZFJlcXVlc3RlZCA/PyBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBvbmxpbmVCYW5raW5nRW5hYmxlZCA9IHJlc3BvbnNlRGF0YT8ub25saW5lQmFua2luZ0VuYWJsZWQgPz8gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBtb2JpbGVCYW5raW5nRW5hYmxlZCA9IHJlc3BvbnNlRGF0YT8ubW9iaWxlQmFua2luZ0VuYWJsZWQgPz8gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBNZXRhZGF0YQogICAgICAgICAgICAgICAgICAgIGNyZWF0aW9uUmVmZXJlbmNlID0gcmVzcG9uc2VEYXRhPy5jcmVhdGlvblJlZmVyZW5jZSA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgIGNvcmVCYW5raW5nSWQgPSByZXNwb25zZURhdGE/LmNvcmVCYW5raW5nSWQsCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbCBzZXJ2aWNlcwogICAgICAgICAgICAgICAgICAgIHNlcnZpY2VzID0gcmVzcG9uc2VEYXRhPy5zZXJ2aWNlcyA/PyBuZXdbXQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgIm9ubGluZS1iYW5raW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgIm1vYmlsZS1iYW5raW5nIiwKICAgICAgICAgICAgICAgICAgICAgICAgInNtcy1iYW5raW5nIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJhY2NvdW50LWNyZWF0aW9uLXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFjY291bnRDcmVhdGlvbiA9IGFjY291bnRDcmVhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW5jbHVkZSBzdW1tYXJ5IGZvciBzdWNjZXNzIHZpZXcKICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3VudFN1bW1hcnkgPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3VudE51bWJlciA9IGFjY291bnRDcmVhdGlvbi5hY2NvdW50TnVtYmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWJhbiA9IGFjY291bnRDcmVhdGlvbi5pYmFuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjb3VudFR5cGUgPSBhY2NvdW50Q3JlYXRpb24uYWNjb3VudFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9IGFjY291bnRDcmVhdGlvbi5jdXJyZW5jeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IGFjY291bnRDcmVhdGlvbi5zdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVkQXQgPSBhY2NvdW50Q3JlYXRpb24uY3JlYXRlZEF0CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJiYW5raW5nIiwgImFjY291bnQtY3JlYXRpb24iLCAic3VjY2VzcyIsICJhY2NvdW50LW9wZW5lZCIsICJjb3JlLWJhbmtpbmciIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLy8gRmFpbGVkIGFjY291bnQgY3JlYXRpb24KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgZXJyb3JJbmZvID0gRXh0cmFjdEVycm9ySW5mb3JtYXRpb24oY29udGV4dCwgc3RhdHVzQ29kZSk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBhY2NvdW50Q3JlYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgY3JlYXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIEVycm9yIGRldGFpbHMKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGVycm9ySW5mby5tZXNzYWdlLAogICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9IGVycm9ySW5mby5jb2RlLAogICAgICAgICAgICAgICAgICAgIGVycm9yRGVzY3JpcHRpb24gPSBlcnJvckluZm8uZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gRmFpbHVyZSBhbmFseXNpcwogICAgICAgICAgICAgICAgICAgIGZhaWx1cmVSZWFzb24gPSByZXNwb25zZURhdGE/LmZhaWx1cmVSZWFzb24gPz8gInVua25vd24iLAogICAgICAgICAgICAgICAgICAgIGZhaWx1cmVDYXRlZ29yeSA9IHJlc3BvbnNlRGF0YT8uZmFpbHVyZUNhdGVnb3J5ID8/ICJzeXN0ZW1fZXJyb3IiLAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIFJldHJ5IGluZm9ybWF0aW9uCiAgICAgICAgICAgICAgICAgICAgY2FuUmV0cnkgPSByZXNwb25zZURhdGE/LmNhblJldHJ5ID8/IHRydWUsCiAgICAgICAgICAgICAgICAgICAgcmV0cnlBZnRlciA9IHJlc3BvbnNlRGF0YT8ucmV0cnlBZnRlciA/PyAzMDAsIC8vIDUgbWludXRlcwogICAgICAgICAgICAgICAgICAgIG1heFJldHJpZXMgPSByZXNwb25zZURhdGE/Lm1heFJldHJpZXMgPz8gMywKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBSZWNvbW1lbmRhdGlvbnMKICAgICAgICAgICAgICAgICAgICByZWNvbW1lbmRhdGlvbnMgPSByZXNwb25zZURhdGE/LnJlY29tbWVuZGF0aW9ucyA/PyBuZXdbXQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgIlBsZWFzZSBjaGVjayB5b3VyIGFjY291bnQgaW5mb3JtYXRpb24gYW5kIHRyeSBhZ2FpbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICJJZiB0aGUgcHJvYmxlbSBwZXJzaXN0cywgY29udGFjdCBjdXN0b21lciBzdXBwb3J0IgogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gU3VwcG9ydCBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgIHN1cHBvcnRSZWZlcmVuY2UgPSByZXNwb25zZURhdGE/LnN1cHBvcnRSZWZlcmVuY2UgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBNZXRhZGF0YQogICAgICAgICAgICAgICAgICAgIHJlcXVlc3RJZCA9IGNvbnRleHQuSGVhZGVycz9bIngtcmVxdWVzdC1pZCJdLAogICAgICAgICAgICAgICAgICAgIHdvcmtmbG93SW5zdGFuY2VJZCA9IGNvbnRleHQuSW5zdGFuY2U/LklkLlRvU3RyaW5nKCkKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJhY2NvdW50LWNyZWF0aW9uLWZhaWx1cmUiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGFjY291bnRDcmVhdGlvbiA9IGFjY291bnRDcmVhdGlvbgogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImJhbmtpbmciLCAiYWNjb3VudC1jcmVhdGlvbiIsICJmYWlsdXJlIiwgImVycm9yIiwgImNvcmUtYmFua2luZy1lcnJvciIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiYWNjb3VudC1jcmVhdGlvbi1vdXRwdXQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFjY291bnRDcmVhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJJbnRlcm5hbCBwcm9jZXNzaW5nIGVycm9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gInByb2Nlc3NpbmdfZXJyb3IiLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICBjYW5SZXRyeSA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1cHBvcnRSZWZlcmVuY2UgPSBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJiYW5raW5nIiwgImFjY291bnQtY3JlYXRpb24iLCAiZXJyb3IiLCAiZXhjZXB0aW9uIiwgInByb2Nlc3NpbmctZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9CgogICAgI3JlZ2lvbiBIZWxwZXIgTWV0aG9kcwoKICAgIHByaXZhdGUgc3RhdGljIGludCBHZXRTdGF0dXNDb2RlRnJvbVJlc3BvbnNlKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICBpZiAoY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlICE9IG51bGwpCiAgICAgICAgICAgIHJldHVybiAoaW50KWNvbnRleHQuQm9keS5zdGF0dXNDb2RlOwoKICAgICAgICByZXR1cm4gMjAwOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGR5bmFtaWM/IEdldFJlc3BvbnNlRGF0YUZyb21Db250ZXh0KFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICBpZiAoY29udGV4dC5Cb2R5Py5kYXRhICE9IG51bGwpCiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LkJvZHkuZGF0YTsKCiAgICAgICAgaWYgKGNvbnRleHQuQm9keSAhPSBudWxsICYmIGNvbnRleHQuQm9keS5zdGF0dXNDb2RlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LkJvZHk7CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIChzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGNvZGUsIHN0cmluZyBkZXNjcmlwdGlvbikgRXh0cmFjdEVycm9ySW5mb3JtYXRpb24oU2NyaXB0Q29udGV4dCBjb250ZXh0LCBpbnQgc3RhdHVzQ29kZSkKICAgIHsKICAgICAgICB2YXIgZXJyb3JEYXRhID0gY29udGV4dC5Cb2R5Py5kYXRhPy5lcnJvciA/PyBudWxsOwogICAgICAgIAogICAgICAgIHN0cmluZyBtZXNzYWdlID0gIkFjY291bnQgY3JlYXRpb24gZmFpbGVkIjsKICAgICAgICBzdHJpbmcgY29kZSA9ICJhY2NvdW50X2NyZWF0aW9uX2Vycm9yIjsKICAgICAgICBzdHJpbmcgZGVzY3JpcHRpb24gPSAiVW5hYmxlIHRvIGNyZWF0ZSB0aGUgYmFuayBhY2NvdW50IjsKCiAgICAgICAgaWYgKGVycm9yRGF0YSAhPSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9yRGF0YS5tZXNzYWdlID8/IG1lc3NhZ2U7CiAgICAgICAgICAgIGNvZGUgPSBlcnJvckRhdGEuY29kZSA/PyBjb2RlOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9IGVycm9yRGF0YS5kZXNjcmlwdGlvbiA/PyBkZXNjcmlwdGlvbjsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoc3RhdHVzQ29kZSA9PSA0MDApCiAgICAgICAgewogICAgICAgICAgICBjb2RlID0gImludmFsaWRfYWNjb3VudF9kYXRhIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAiSW52YWxpZCBhY2NvdW50IGNyZWF0aW9uIGRhdGEgcHJvdmlkZWQiOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID09IDQwOSkKICAgICAgICB7CiAgICAgICAgICAgIGNvZGUgPSAiYWNjb3VudF9hbHJlYWR5X2V4aXN0cyI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIkFuIGFjY291bnQgd2l0aCBzaW1pbGFyIGRldGFpbHMgYWxyZWFkeSBleGlzdHMiOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID09IDQyMikKICAgICAgICB7CiAgICAgICAgICAgIGNvZGUgPSAidmFsaWRhdGlvbl9lcnJvciI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIkFjY291bnQgZGF0YSB2YWxpZGF0aW9uIGZhaWxlZCI7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHN0YXR1c0NvZGUgPj0gNTAwKQogICAgICAgIHsKICAgICAgICAgICAgY29kZSA9ICJjb3JlX2JhbmtpbmdfZXJyb3IiOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJDb3JlIGJhbmtpbmcgc3lzdGVtIGVycm9yIGR1cmluZyBhY2NvdW50IGNyZWF0aW9uIjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAobWVzc2FnZSwgY29kZSwgZGVzY3JpcHRpb24pOwogICAgfQoKICAgICNlbmRyZWdpb24KfQo=" + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gQ3JlYXRlIEJhbmsgQWNjb3VudCBNYXBwaW5nIC0gQ3JlYXRlcyB0aGUgYWN0dWFsIGJhbmsgYWNjb3VudCBpbiBjb3JlIGJhbmtpbmcgc3lzdGVtCi8vLyBUaGlzIG1hcHBpbmcgY3JlYXRlcyB0aGUgZGVtYW5kIGRlcG9zaXQgYWNjb3VudCBpbiB0aGUgY29yZSBiYW5raW5nIHN5c3RlbS4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIENyZWF0ZUJhbmtBY2NvdW50TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGFuIEh0dHBUYXNrIGZvciBhY2NvdW50IGNyZWF0aW9uIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEdldCBhbGwgcmVxdWlyZWQgZGF0YSBmcm9tIHdvcmtmbG93IGNvbnRleHQKICAgICAgICAgICAgdmFyIHVzZXJTZXNzaW9uID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udXNlclNlc3Npb247CiAgICAgICAgICAgIHZhciBhY2NvdW50VHlwZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFjY291bnRUeXBlOwogICAgICAgICAgICB2YXIgcG9saWN5VmFsaWRhdGlvbiA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnBvbGljeVZhbGlkYXRpb247CgogICAgICAgICAgICAvLyBQcmVwYXJlIHRoZSByZXF1ZXN0IGJvZHkgZm9yIGFjY291bnQgY3JlYXRpb24KICAgICAgICAgICAgdmFyIHJlcXVlc3RCb2R5ID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEFjY291bnQgaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgIGFjY291bnRUeXBlID0gYWNjb3VudFR5cGUgPz8gImRlbWFuZC1kZXBvc2l0IiwKICAgICAgICAgICAgICAgIGFjY291bnROYW1lID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uYWNjb3VudE5hbWUsCiAgICAgICAgICAgICAgICBjdXJyZW5jeSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmN1cnJlbmN5LAogICAgICAgICAgICAgICAgYnJhbmNoQ29kZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmJyYW5jaENvZGUsCiAgICAgICAgICAgICAgICBpbml0aWFsRGVwb3NpdCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmluaXRpYWxEZXBvc2l0ID8/IDAsCiAgICAgICAgICAgICAgICBhY2NvdW50UHVycG9zZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFjY291bnRQdXJwb3NlLAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBDdXN0b21lciBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgY3VzdG9tZXJJZCA9IHVzZXJTZXNzaW9uPy51c2VySWQsCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vIEFjY291bnQgbGltaXRzIGZyb20gcG9saWN5IHZhbGlkYXRpb24KICAgICAgICAgICAgICAgIGFjY291bnRMaW1pdHMgPSBwb2xpY3lWYWxpZGF0aW9uPy5hY2NvdW50TGltaXRzID8/IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRhaWx5VHJhbnNhY3Rpb25MaW1pdCA9IDUwMDAwLAogICAgICAgICAgICAgICAgICAgIG1vbnRobHlUcmFuc2FjdGlvbkxpbWl0ID0gNTAwMDAwLAogICAgICAgICAgICAgICAgICAgIG1pbmltdW1CYWxhbmNlID0gMCwKICAgICAgICAgICAgICAgICAgICBtYXhpbXVtQmFsYW5jZSA9IDEwMDAwMDAKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vIE5vdGlmaWNhdGlvbiBwcmVmZXJlbmNlcwogICAgICAgICAgICAgICAgbm90aWZpY2F0aW9ucyA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/Lm5vdGlmaWNhdGlvbnMgPz8gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc21zTm90aWZpY2F0aW9ucyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgZW1haWxOb3RpZmljYXRpb25zID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBwdXNoTm90aWZpY2F0aW9ucyA9IHRydWUKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vIENvbXBsaWFuY2UgYW5kIGF1ZGl0IGluZm9ybWF0aW9uCiAgICAgICAgICAgICAgICBjb21wbGlhbmNlSW5mbyA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25JZCA9IHBvbGljeVZhbGlkYXRpb24/LnZhbGlkYXRpb25JZCwKICAgICAgICAgICAgICAgICAgICBwb2xpY3lWZXJzaW9uID0gcG9saWN5VmFsaWRhdGlvbj8ucG9saWN5VmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICB0ZXJtc0FjY2VwdGVkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udGVybXNBY2NlcHRlZCwKICAgICAgICAgICAgICAgICAgICBwcml2YWN5UG9saWN5QWNjZXB0ZWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5wcml2YWN5UG9saWN5QWNjZXB0ZWQsCiAgICAgICAgICAgICAgICAgICAgaXBBZGRyZXNzID0gdXNlclNlc3Npb24/LmlwQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICB1c2VyQWdlbnQgPSB1c2VyU2Vzc2lvbj8udXNlckFnZW50CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBSZXF1ZXN0IG1ldGFkYXRhCiAgICAgICAgICAgICAgICByZXF1ZXN0SWQgPSBjb250ZXh0LkhlYWRlcnM/WyJ4LXJlcXVlc3QtaWQiXSA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgd29ya2Zsb3dJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIHJlcXVlc3RlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIGNvbnRleHQKICAgICAgICAgICAgICAgIGNoYW5uZWwgPSAiZGlnaXRhbC1iYW5raW5nIiwKICAgICAgICAgICAgICAgIHNvdXJjZSA9ICJhY2NvdW50LW9wZW5pbmctd29ya2Zsb3ciCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KTsKCiAgICAgICAgICAgIC8vIFNldCBIZWFkZXJzCiAgICAgICAgICAgIHZhciBoZWFkZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbIkNvbnRlbnQtVHlwZSJdID0gImFwcGxpY2F0aW9uL2pzb24iLAogICAgICAgICAgICAgICAgWyJ1c2VyX3JlZmVyZW5jZSJdID0gdXNlclNlc3Npb24/LnVzZXJJZD8uVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIFsiWC1SZXF1ZXN0LUlkIl0gPSByZXF1ZXN0Qm9keS5yZXF1ZXN0SWQsCiAgICAgICAgICAgICAgICBbIlgtSW5zdGFuY2UtSWQiXSA9IGNvbnRleHQuSW5zdGFuY2U/LklkLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIlgtQWNjb3VudC1UeXBlIl0gPSBhY2NvdW50VHlwZT8uVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIFsiWC1DdXJyZW5jeSJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uY3VycmVuY3k/LlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIlgtQnJhbmNoLUNvZGUiXSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmJyYW5jaENvZGU/LlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIlgtVmFsaWRhdGlvbi1JZCJdID0gcG9saWN5VmFsaWRhdGlvbj8udmFsaWRhdGlvbklkPy5Ub1N0cmluZygpCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKGhlYWRlcnMpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiQ3JlYXRlQmFua0FjY291bnRNYXBwaW5nIC0gRXJyb3I6IHswfSIsIGFyZ3M6IG5ldyBvYmplY3Q/W10geyBleC5NZXNzYWdlIH0pOwogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICB9CgogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIFByb2Nlc3MgdGhlIGFjY291bnQgY3JlYXRpb24gcmVzdWx0IGFuZCBtZXJnZSBpdCBpbnRvIHRoZSB3b3JrZmxvdyBpbnN0YW5jZQogICAgLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gR2V0U3RhdHVzQ29kZUZyb21SZXNwb25zZShjb250ZXh0KTsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9IEdldFJlc3BvbnNlRGF0YUZyb21Db250ZXh0KGNvbnRleHQpOwoKICAgICAgICAgICAgLy8gU3VjY2Vzc2Z1bCBhY2NvdW50IGNyZWF0aW9uCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDwgMzAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgYWNjb3VudENyZWF0aW9uID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgY3JlYXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIEFjY291bnQgZGV0YWlscwogICAgICAgICAgICAgICAgICAgIGFjY291bnRJZCA9IHJlc3BvbnNlRGF0YT8uYWNjb3VudElkID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgYWNjb3VudE51bWJlciA9IHJlc3BvbnNlRGF0YT8uYWNjb3VudE51bWJlciwKICAgICAgICAgICAgICAgICAgICBpYmFuID0gcmVzcG9uc2VEYXRhPy5pYmFuLAogICAgICAgICAgICAgICAgICAgIGFjY291bnRUeXBlID0gcmVzcG9uc2VEYXRhPy5hY2NvdW50VHlwZSA/PyAiZGVtYW5kLWRlcG9zaXQiLAogICAgICAgICAgICAgICAgICAgIGN1cnJlbmN5ID0gcmVzcG9uc2VEYXRhPy5jdXJyZW5jeSwKICAgICAgICAgICAgICAgICAgICBicmFuY2hDb2RlID0gcmVzcG9uc2VEYXRhPy5icmFuY2hDb2RlLAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIEFjY291bnQgc3RhdHVzCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gcmVzcG9uc2VEYXRhPy5zdGF0dXMgPz8gImFjdGl2ZSIsCiAgICAgICAgICAgICAgICAgICAgaXNBY3RpdmUgPSByZXNwb25zZURhdGE/LmlzQWN0aXZlID8/IHRydWUsCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gQmFsYW5jZSBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgIGN1cnJlbnRCYWxhbmNlID0gcmVzcG9uc2VEYXRhPy5jdXJyZW50QmFsYW5jZSA/PyAwLAogICAgICAgICAgICAgICAgICAgIGF2YWlsYWJsZUJhbGFuY2UgPSByZXNwb25zZURhdGE/LmF2YWlsYWJsZUJhbGFuY2UgPz8gMCwKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBBY2NvdW50IGxpbWl0cwogICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9IHJlc3BvbnNlRGF0YT8ubGltaXRzID8/IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGFpbHlUcmFuc2FjdGlvbkxpbWl0ID0gNTAwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgIG1vbnRobHlUcmFuc2FjdGlvbkxpbWl0ID0gNTAwMDAwLAogICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtQmFsYW5jZSA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgIG1heGltdW1CYWxhbmNlID0gMTAwMDAwMAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gQ2FyZHMgYW5kIHNlcnZpY2VzCiAgICAgICAgICAgICAgICAgICAgZGViaXRDYXJkUmVxdWVzdGVkID0gcmVzcG9uc2VEYXRhPy5kZWJpdENhcmRSZXF1ZXN0ZWQgPz8gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgb25saW5lQmFua2luZ0VuYWJsZWQgPSByZXNwb25zZURhdGE/Lm9ubGluZUJhbmtpbmdFbmFibGVkID8/IHRydWUsCiAgICAgICAgICAgICAgICAgICAgbW9iaWxlQmFua2luZ0VuYWJsZWQgPSByZXNwb25zZURhdGE/Lm1vYmlsZUJhbmtpbmdFbmFibGVkID8/IHRydWUsCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gTWV0YWRhdGEKICAgICAgICAgICAgICAgICAgICBjcmVhdGlvblJlZmVyZW5jZSA9IHJlc3BvbnNlRGF0YT8uY3JlYXRpb25SZWZlcmVuY2UgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICBjb3JlQmFua2luZ0lkID0gcmVzcG9uc2VEYXRhPy5jb3JlQmFua2luZ0lkLAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIEFkZGl0aW9uYWwgc2VydmljZXMKICAgICAgICAgICAgICAgICAgICBzZXJ2aWNlcyA9IHJlc3BvbnNlRGF0YT8uc2VydmljZXMgPz8gbmV3W10KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJvbmxpbmUtYmFua2luZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJtb2JpbGUtYmFua2luZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJzbXMtYmFua2luZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAiYWNjb3VudC1jcmVhdGlvbi1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhY2NvdW50Q3JlYXRpb24gPSBhY2NvdW50Q3JlYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEluY2x1ZGUgc3VtbWFyeSBmb3Igc3VjY2VzcyB2aWV3CiAgICAgICAgICAgICAgICAgICAgICAgIGFjY291bnRTdW1tYXJ5ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY291bnROdW1iZXIgPSBhY2NvdW50Q3JlYXRpb24uYWNjb3VudE51bWJlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGliYW4gPSBhY2NvdW50Q3JlYXRpb24uaWJhbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY291bnRUeXBlID0gYWNjb3VudENyZWF0aW9uLmFjY291bnRUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSBhY2NvdW50Q3JlYXRpb24uY3VycmVuY3ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBhY2NvdW50Q3JlYXRpb24uc3RhdHVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlZEF0ID0gYWNjb3VudENyZWF0aW9uLmNyZWF0ZWRBdAogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiYmFua2luZyIsICJhY2NvdW50LWNyZWF0aW9uIiwgInN1Y2Nlc3MiLCAiYWNjb3VudC1vcGVuZWQiLCAiY29yZS1iYW5raW5nIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEZhaWxlZCBhY2NvdW50IGNyZWF0aW9uCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGVycm9ySW5mbyA9IEV4dHJhY3RFcnJvckluZm9ybWF0aW9uKGNvbnRleHQsIHN0YXR1c0NvZGUpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgYWNjb3VudENyZWF0aW9uID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGNyZWF0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBFcnJvciBkZXRhaWxzCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBlcnJvckluZm8ubWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBlcnJvckNvZGUgPSBlcnJvckluZm8uY29kZSwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXJyb3JJbmZvLmRlc2NyaXB0aW9uLAogICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIEZhaWx1cmUgYW5hbHlzaXMKICAgICAgICAgICAgICAgICAgICBmYWlsdXJlUmVhc29uID0gcmVzcG9uc2VEYXRhPy5mYWlsdXJlUmVhc29uID8/ICJ1bmtub3duIiwKICAgICAgICAgICAgICAgICAgICBmYWlsdXJlQ2F0ZWdvcnkgPSByZXNwb25zZURhdGE/LmZhaWx1cmVDYXRlZ29yeSA/PyAic3lzdGVtX2Vycm9yIiwKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvLyBSZXRyeSBpbmZvcm1hdGlvbgogICAgICAgICAgICAgICAgICAgIGNhblJldHJ5ID0gcmVzcG9uc2VEYXRhPy5jYW5SZXRyeSA/PyB0cnVlLAogICAgICAgICAgICAgICAgICAgIHJldHJ5QWZ0ZXIgPSByZXNwb25zZURhdGE/LnJldHJ5QWZ0ZXIgPz8gMzAwLCAvLyA1IG1pbnV0ZXMKICAgICAgICAgICAgICAgICAgICBtYXhSZXRyaWVzID0gcmVzcG9uc2VEYXRhPy5tYXhSZXRyaWVzID8/IDMsCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gUmVjb21tZW5kYXRpb25zCiAgICAgICAgICAgICAgICAgICAgcmVjb21tZW5kYXRpb25zID0gcmVzcG9uc2VEYXRhPy5yZWNvbW1lbmRhdGlvbnMgPz8gbmV3W10KICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICJQbGVhc2UgY2hlY2sgeW91ciBhY2NvdW50IGluZm9ybWF0aW9uIGFuZCB0cnkgYWdhaW4iLAogICAgICAgICAgICAgICAgICAgICAgICAiSWYgdGhlIHByb2JsZW0gcGVyc2lzdHMsIGNvbnRhY3QgY3VzdG9tZXIgc3VwcG9ydCIKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIFN1cHBvcnQgaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UmVmZXJlbmNlID0gcmVzcG9uc2VEYXRhPy5zdXBwb3J0UmVmZXJlbmNlID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gTWV0YWRhdGEKICAgICAgICAgICAgICAgICAgICByZXF1ZXN0SWQgPSBjb250ZXh0LkhlYWRlcnM/WyJ4LXJlcXVlc3QtaWQiXSwKICAgICAgICAgICAgICAgICAgICB3b3JrZmxvd0luc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZC5Ub1N0cmluZygpCiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAiYWNjb3VudC1jcmVhdGlvbi1mYWlsdXJlIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhY2NvdW50Q3JlYXRpb24gPSBhY2NvdW50Q3JlYXRpb24KICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJiYW5raW5nIiwgImFjY291bnQtY3JlYXRpb24iLCAiZmFpbHVyZSIsICJlcnJvciIsICJjb3JlLWJhbmtpbmctZXJyb3IiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImFjY291bnQtY3JlYXRpb24tb3V0cHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBhY2NvdW50Q3JlYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiSW50ZXJuYWwgcHJvY2Vzc2luZyBlcnJvciIsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9ICJwcm9jZXNzaW5nX2Vycm9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JEZXNjcmlwdGlvbiA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgY2FuUmV0cnkgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBzdXBwb3J0UmVmZXJlbmNlID0gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiYmFua2luZyIsICJhY2NvdW50LWNyZWF0aW9uIiwgImVycm9yIiwgImV4Y2VwdGlvbiIsICJwcm9jZXNzaW5nLWVycm9yIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQoKICAgICNyZWdpb24gSGVscGVyIE1ldGhvZHMKCiAgICBwcml2YXRlIHN0YXRpYyBpbnQgR2V0U3RhdHVzQ29kZUZyb21SZXNwb25zZShTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgaWYgKGNvbnRleHQuQm9keT8uc3RhdHVzQ29kZSAhPSBudWxsKQogICAgICAgICAgICByZXR1cm4gKGludCljb250ZXh0LkJvZHkuc3RhdHVzQ29kZTsKCiAgICAgICAgcmV0dXJuIDIwMDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBkeW5hbWljPyBHZXRSZXNwb25zZURhdGFGcm9tQ29udGV4dChTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgaWYgKGNvbnRleHQuQm9keT8uZGF0YSAhPSBudWxsKQogICAgICAgICAgICByZXR1cm4gY29udGV4dC5Cb2R5LmRhdGE7CgogICAgICAgIGlmIChjb250ZXh0LkJvZHkgIT0gbnVsbCAmJiBjb250ZXh0LkJvZHkuc3RhdHVzQ29kZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gY29udGV4dC5Cb2R5OwoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyAoc3RyaW5nIG1lc3NhZ2UsIHN0cmluZyBjb2RlLCBzdHJpbmcgZGVzY3JpcHRpb24pIEV4dHJhY3RFcnJvckluZm9ybWF0aW9uKFNjcmlwdENvbnRleHQgY29udGV4dCwgaW50IHN0YXR1c0NvZGUpCiAgICB7CiAgICAgICAgdmFyIGVycm9yRGF0YSA9IGNvbnRleHQuQm9keT8uZGF0YT8uZXJyb3IgPz8gbnVsbDsKICAgICAgICAKICAgICAgICBzdHJpbmcgbWVzc2FnZSA9ICJBY2NvdW50IGNyZWF0aW9uIGZhaWxlZCI7CiAgICAgICAgc3RyaW5nIGNvZGUgPSAiYWNjb3VudF9jcmVhdGlvbl9lcnJvciI7CiAgICAgICAgc3RyaW5nIGRlc2NyaXB0aW9uID0gIlVuYWJsZSB0byBjcmVhdGUgdGhlIGJhbmsgYWNjb3VudCI7CgogICAgICAgIGlmIChlcnJvckRhdGEgIT0gbnVsbCkKICAgICAgICB7CiAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnJvckRhdGEubWVzc2FnZSA/PyBtZXNzYWdlOwogICAgICAgICAgICBjb2RlID0gZXJyb3JEYXRhLmNvZGUgPz8gY29kZTsKICAgICAgICAgICAgZGVzY3JpcHRpb24gPSBlcnJvckRhdGEuZGVzY3JpcHRpb24gPz8gZGVzY3JpcHRpb247CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHN0YXR1c0NvZGUgPT0gNDAwKQogICAgICAgIHsKICAgICAgICAgICAgY29kZSA9ICJpbnZhbGlkX2FjY291bnRfZGF0YSI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIkludmFsaWQgYWNjb3VudCBjcmVhdGlvbiBkYXRhIHByb3ZpZGVkIjsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoc3RhdHVzQ29kZSA9PSA0MDkpCiAgICAgICAgewogICAgICAgICAgICBjb2RlID0gImFjY291bnRfYWxyZWFkeV9leGlzdHMiOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJBbiBhY2NvdW50IHdpdGggc2ltaWxhciBkZXRhaWxzIGFscmVhZHkgZXhpc3RzIjsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoc3RhdHVzQ29kZSA9PSA0MjIpCiAgICAgICAgewogICAgICAgICAgICBjb2RlID0gInZhbGlkYXRpb25fZXJyb3IiOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJBY2NvdW50IGRhdGEgdmFsaWRhdGlvbiBmYWlsZWQiOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID49IDUwMCkKICAgICAgICB7CiAgICAgICAgICAgIGNvZGUgPSAiY29yZV9iYW5raW5nX2Vycm9yIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAiQ29yZSBiYW5raW5nIHN5c3RlbSBlcnJvciBkdXJpbmcgYWNjb3VudCBjcmVhdGlvbiI7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gKG1lc3NhZ2UsIGNvZGUsIGRlc2NyaXB0aW9uKTsKICAgIH0KCiAgICAjZW5kcmVnaW9uCn0K" } } ], @@ -639,6 +647,26 @@ "subFlow": null, "onEntries": [], "onExits": [] + }, + { + "key": "timeouted", + "stateType": 3, + "subType": 8, + "versionStrategy": "Minor", + "labels": [ + { + "language": "en-US", + "label": "Account Opening Timeout" + }, + { + "language": "tr-TR", + "label": "Hesap Açılışı Zaman Aşımına Uğradı" + } + ], + "view": null, + "subFlow": null, + "onEntries": [], + "onExits": [] } ] } diff --git a/core/Workflows/account-opening/src/CreateBankAccountMapping.csx b/core/Workflows/account-opening/src/CreateBankAccountMapping.csx index d1fc602..ae52467 100644 --- a/core/Workflows/account-opening/src/CreateBankAccountMapping.csx +++ b/core/Workflows/account-opening/src/CreateBankAccountMapping.csx @@ -6,7 +6,7 @@ using BBT.Workflow.Definitions; /// Create Bank Account Mapping - Creates the actual bank account in core banking system /// This mapping creates the demand deposit account in the core banking system. /// -public class CreateBankAccountMapping : IMapping +public class CreateBankAccountMapping : ScriptBase, IMapping { public Task InputHandler(WorkflowTask task, ScriptContext context) { @@ -27,7 +27,7 @@ public class CreateBankAccountMapping : IMapping var requestBody = new { // Account information - accountType = accountType?.accountType ?? "demand-deposit", + accountType = accountType ?? "demand-deposit", accountName = context.Instance?.Data?.accountName, currency = context.Instance?.Data?.currency, branchCode = context.Instance?.Data?.branchCode, @@ -84,7 +84,7 @@ public class CreateBankAccountMapping : IMapping ["user_reference"] = userSession?.userId?.ToString(), ["X-Request-Id"] = requestBody.requestId, ["X-Instance-Id"] = context.Instance?.Id.ToString(), - ["X-Account-Type"] = accountType?.accountType?.ToString(), + ["X-Account-Type"] = accountType?.ToString(), ["X-Currency"] = context.Instance?.Data?.currency?.ToString(), ["X-Branch-Code"] = context.Instance?.Data?.branchCode?.ToString(), ["X-Validation-Id"] = policyValidation?.validationId?.ToString() @@ -96,6 +96,7 @@ public class CreateBankAccountMapping : IMapping } catch (Exception ex) { + LogError("CreateBankAccountMapping - Error: {0}", args: new object?[] { ex.Message }); return Task.FromResult(new ScriptResponse()); } } diff --git a/core/Workflows/account-opening/src/OnEntryGetInstanceDataMapping.csx b/core/Workflows/account-opening/src/OnEntryGetInstanceDataMapping.csx new file mode 100644 index 0000000..d729bd6 --- /dev/null +++ b/core/Workflows/account-opening/src/OnEntryGetInstanceDataMapping.csx @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +public class OnEntryGetInstanceDataMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + var triggerTask = (task as GetInstanceDataTask)!; + + triggerTask.SetInstance(context.Instance.Key); + + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + return Task.FromResult(new ScriptResponse() + { + Data = new + { + instanceSnapshot = context.Body, + fetchedAt = System.DateTime.UtcNow + } + }); + } +} diff --git a/core/Workflows/contract/.meta/contract-approval-workflow.diagram.json b/core/Workflows/contract/.meta/contract-approval-workflow.diagram.json deleted file mode 100644 index 3f26be9..0000000 --- a/core/Workflows/contract/.meta/contract-approval-workflow.diagram.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "nodePos": { - "get-documents": { - "x": 832.2613564163169, - "y": -59.090639542492255 - }, - "process-next-document": { - "x": 785.847542225539, - "y": 187.31525053290247 - }, - "waiting-for-ready": { - "x": 1077.8742868701956, - "y": 419.9565626003958 - }, - "check-all-ready": { - "x": 416, - "y": 418 - }, - "all-ready": { - "x": 333.43882559601354, - "y": 693.4918284667067 - }, - "check-all-approved": { - "x": 1395.5109010718922, - "y": 693.2832210317742 - }, - "contract-completed": { - "x": 1396, - "y": -60 - }, - "contract-rejected": { - "x": 448.62784213385794, - "y": 952.2279820637636 - }, - "__start__": { - "x": 262, - "y": -52 - } - } -} \ No newline at end of file diff --git a/core/Workflows/contract/.meta/contract-document-subflow.diagram.json b/core/Workflows/contract/.meta/contract-document-subflow.diagram.json deleted file mode 100644 index 7f5cc85..0000000 --- a/core/Workflows/contract/.meta/contract-document-subflow.diagram.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "nodePos": { - "render-document": { - "x": 100, - "y": 300 - }, - "notify-parent-ready": { - "x": 531, - "y": 200 - }, - "waiting-for-approval": { - "x": 1097, - "y": 200 - }, - "notify-parent-approved": { - "x": 1573, - "y": 100 - }, - "notify-parent-rejected": { - "x": 1573, - "y": 300 - }, - "document-completed": { - "x": 2085, - "y": 100 - }, - "document-rejected": { - "x": 2085, - "y": 300 - }, - "document-failed": { - "x": 391, - "y": 500 - }, - "__start__": { - "x": -296, - "y": 300 - } - } -} \ No newline at end of file diff --git a/core/Workflows/contract/contract-approval-workflow.http b/core/Workflows/contract/contract-approval-workflow.http deleted file mode 100644 index 4ab3145..0000000 --- a/core/Workflows/contract/contract-approval-workflow.http +++ /dev/null @@ -1,188 +0,0 @@ -############################################################################### -# Contract Approval Workflow - HTTP Test File -# -# This file tests the contract-approval workflow which handles: -# - Contract document fetching -# - Document rendering via subflow -# - Document approval/rejection by user -# - Multi-document processing in a loop -# - Completion notification -# -# Prerequisites: -# 1. vNext Runtime running on localhost:4201 -# 2. Mockoon running on localhost:3001 -############################################################################### - -@baseUrl = http://localhost:4201 -@apiVersion = 1 -@domain = core -@workflow = contract-approval-workflow -@subflow = contract-document-subflow -@instanceKey = contract-{{$timestamp}} - -############################################################################### -# Step 1: Start Contract Approval Workflow -# Initiates the contract approval flow with group code -############################################################################### - -### Start Contract Approval Instance -# @name startContractApproval -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start?sync=false -Content-Type: application/json -Accept-Language: tr-TR -X-Request-Id: {{$guid}} -X-Device-Id: {{$guid}} -X-Token-Id: {{$guid}} -X-Device-Info: IOS 16 -X-Forwarded-For: 192.168.2.1 -user_reference: 34987491018 - -{ - "key": "{{instanceKey}}", - "tags": [ - "contract", - "approval", - "test" - ], - "attributes": { - "groupCode": "KG-2024-001", - "userId": "user-123", - "sessionId": "session-456", - "requestedAt": "{{$isoTimestamp}}" - } -} - -############################################################################### -# Step 2: Get Main Workflow State -# Check the current state of the main approval workflow -############################################################################### - -### Get Main Workflow State -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -############################################################################### -# Step 3: Get Main Workflow Data -# Retrieve data including document list -############################################################################### - -### Get Main Workflow Data -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -############################################################################### -# Document Subflow Operations -# Each document is processed in a separate subflow instance -############################################################################### - -@subflowInstanceKey = document-subflow-instance-id - -### Get Document Subflow State -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{subflow}}/instances/{{subflowInstanceKey}}/functions/state -Accept: application/json - -### Get Document Subflow Data -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{subflow}}/instances/{{subflowInstanceKey}}/functions/data -Accept: application/json - -############################################################################### -# Step 4: Approve Document -# User approves the rendered document -############################################################################### - -### Approve Document -# @name approveDocument -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{subflow}}/instances/{{subflowInstanceKey}}/transitions/approve-document?sync=true -Content-Type: application/json - -{ - "attributes": { - "approvedBy": "user-123", - "approvalNotes": "Document reviewed and approved" - } -} - -############################################################################### -# Step 4.1: Reject Document (Alternative) -# User rejects the document with reason -############################################################################### - -### Reject Document (Alternative) -# @name rejectDocument -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{subflow}}/instances/{{subflowInstanceKey}}/transitions/reject-document?sync=true -Content-Type: application/json - -{ - "attributes": { - "rejectedBy": "user-123", - "reason": "Document content has missing information" - } -} - -############################################################################### -# Step 5: Check Final State -# Verify all documents are processed and workflow is complete -############################################################################### - -### Get Final Main Workflow State -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -### Get Final Main Workflow Data -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -############################################################################### -# Contract Approval Flow Summary -############################################################################### -# -# Main Workflow (contract-approval-workflow): -# | Step | State/Transition | Description | -# |------|-----------------------|---------------------------------------| -# | 1 | start | Start with groupCode for documents | -# | 2 | (auto) | Fetch contract documents | -# | 3 | (auto) | Start document subflow for each doc | -# | 4 | (wait) | Wait for all documents to be approved | -# | 5 | (auto) | Notify completion | -# | 6 | (complete) | All documents approved | -# -# Document Subflow (contract-document-subflow): -# | Step | Transition | Description | -# |------|-----------------------|---------------------------------------| -# | 1 | (start) | Receive document from parent workflow | -# | 2 | (auto) | Render document for display | -# | 3 | approve-document | User approves the document | -# | | reject-document | OR user rejects the document | -# | 4 | (auto) | Notify parent workflow | -# | 5 | (complete) | Subflow completes | -# -############################################################################### - -############################################################################### -# Mockoon Endpoint Tests - Verify Mock Server is Running -############################################################################### - -### Test Get Contract Documents (Mockoon) -GET http://localhost:3001/api/contract/documents?groupCode=KG-2024-001 -Accept: application/json - -### Test Render Document (Mockoon) -POST http://localhost:3001/api/contract/documents/render -Content-Type: application/json - -{ - "documentId": "doc-001", - "templateId": "template-standard", - "userId": "user-123" -} - -### Test Notify Document Approved (Mockoon) -POST http://localhost:3001/api/contract/documents/notify-approved -Content-Type: application/json - -{ - "documentId": "doc-001", - "approvedBy": "user-123", - "approvedAt": "{{$isoTimestamp}}" -} - diff --git a/core/Workflows/contract/contract-approval-workflow.json b/core/Workflows/contract/contract-approval-workflow.json deleted file mode 100644 index 2702ae6..0000000 --- a/core/Workflows/contract/contract-approval-workflow.json +++ /dev/null @@ -1,526 +0,0 @@ -{ - "key": "contract-approval-workflow", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "contract", - "approval", - "workflow", - "document-management", - "sequential-process" - ], - "attributes": { - "type": "F", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Contract Approval Workflow" - }, - { - "language": "tr-TR", - "label": "Kontrat Onay İş Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-contract-approval", - "target": "get-documents", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Contract Approval" - }, - { - "language": "tr-TR", - "label": "Kontrat Onayını Başlat" - } - ], - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/InitContractApprovalMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBJbml0aWFsaXplIENvbnRyYWN0IEFwcHJvdmFsIFdvcmtmbG93IC0gUHJlcGFyZXMgaW5pdGlhbCBkYXRhCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBJbml0Q29udHJhY3RBcHByb3ZhbE1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGlucHV0RGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE7CiAgICAgICAgICAgIHZhciBncm91cENvZGUgPSBpbnB1dERhdGE/Lmdyb3VwQ29kZT8uVG9TdHJpbmcoKSA/PyAiIjsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImluaXQtc3VjY2VzcyIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZ3JvdXBDb2RlID0gZ3JvdXBDb2RlLAogICAgICAgICAgICAgICAgICAgIHdvcmtmbG93U3RhcnRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50cyA9IG5ldyBvYmplY3RbXSB7IH0sCiAgICAgICAgICAgICAgICAgICAgY3VycmVudERvY3VtZW50SW5kZXggPSAwLAogICAgICAgICAgICAgICAgICAgIHJlYWR5Q291bnQgPSAwLAogICAgICAgICAgICAgICAgICAgIGFwcHJvdmVkQ291bnQgPSAwLAogICAgICAgICAgICAgICAgICAgIHJlamVjdGVkQ291bnQgPSAwLAogICAgICAgICAgICAgICAgICAgIHRvdGFsRG9jdW1lbnRzID0gMCwKICAgICAgICAgICAgICAgICAgICBkb2N1bWVudEluc3RhbmNlcyA9IG5ldyBvYmplY3RbXSB7IH0sCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gImluaXRpYWxpemVkIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJjb250cmFjdCIsICJpbml0aWFsaXplZCIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiaW5pdC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - } - ] - }, - "states": [ - { - "key": "get-documents", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Get Document List" - }, - { - "language": "tr-TR", - "label": "Döküman Listesini Al" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "get-contract-documents", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/GetContractDocumentsMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBHZXQgQ29udHJhY3QgRG9jdW1lbnRzIE1hcHBpbmcgLSBSZXRyaWV2ZXMgZG9jdW1lbnQgbGlzdCBmcm9tIEFQSQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgR2V0Q29udHJhY3REb2N1bWVudHNNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGdyb3VwQ29kZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/Lmdyb3VwQ29kZT8uVG9TdHJpbmcoKSA/PyAiIjsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIE1vY2tvb24gQVBJIGV4cGVjdHMgImdyb3VwQ29kZSIgZmllbGQKICAgICAgICAgICAgdmFyIHJlcXVlc3RCb2R5ID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdyb3VwQ29kZSA9IGdyb3VwQ29kZSwKICAgICAgICAgICAgICAgIHJlcXVlc3RJZCA9IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICB0aW1lc3RhbXAgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGh0dHBUYXNrLlNldEJvZHkocmVxdWVzdEJvZHkpOwoKICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIHN0cmluZz8+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgICAgICBbIlgtUmVxdWVzdC1JZCJdID0gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIFsiWC1Db3JyZWxhdGlvbi1JZCJdID0gY29udGV4dC5JbnN0YW5jZS5JZC5Ub1N0cmluZygpCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGh0dHBUYXNrLlNldEhlYWRlcnMoaGVhZGVycyk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJnZXQtZG9jdW1lbnRzLWlucHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwogICAgICAgICAgICB2YXIgc3RhdHVzQ29kZSA9IHJlc3BvbnNlPy5zdGF0dXNDb2RlID8/IDUwMDsKCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDwgMzAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBNb2Nrb29uIEFQSSByZXR1cm5zICJjb250cmFjdHMiIGFycmF5LCBub3QgImRvY3VtZW50cyIKICAgICAgICAgICAgICAgIHZhciBjb250cmFjdHMgPSByZXNwb25zZT8uZGF0YT8uZGF0YT8uY29udHJhY3RzID8/IG5ldyBvYmplY3RbXSB7IH07CiAgICAgICAgICAgICAgICB2YXIgY29udHJhY3RMaXN0ID0gbmV3IExpc3Q8b2JqZWN0PigpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoY29udHJhY3RzICE9IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGNvbnRyYWN0IGluIGNvbnRyYWN0cykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyYWN0TGlzdC5BZGQoY29udHJhY3QpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyB0b3RhbENvbnRyYWN0cyBmcm9tIEFQSSByZXNwb25zZSBvciBjYWxjdWxhdGVkIGZyb20gbGlzdAogICAgICAgICAgICAgICAgdmFyIHRvdGFsQ29udHJhY3RzID0gcmVzcG9uc2U/LmRhdGE/LmRhdGE/LnRvdGFsQ29udHJhY3RzID8/IGNvbnRyYWN0TGlzdC5Db3VudDsKCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImdldC1kb2N1bWVudHMtc3VjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRzID0gY29udHJhY3RMaXN0LlRvQXJyYXkoKSwKICAgICAgICAgICAgICAgICAgICAgICAgdG90YWxEb2N1bWVudHMgPSAoaW50KXRvdGFsQ29udHJhY3RzLAogICAgICAgICAgICAgICAgICAgICAgICBncm91cENvZGUgPSByZXNwb25zZT8uZGF0YT8uZGF0YT8uZ3JvdXBDb2RlLAogICAgICAgICAgICAgICAgICAgICAgICByZXRyaWV2ZWRBdCA9IHJlc3BvbnNlPy5kYXRhPy5kYXRhPy5yZXRyaWV2ZWRBdCwKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudERvY3VtZW50SW5kZXggPSAwLAogICAgICAgICAgICAgICAgICAgICAgICByZWFkeUNvdW50ID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgYXBwcm92ZWRDb3VudCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50SW5zdGFuY2VzID0gbmV3IG9iamVjdFtdIHsgfSwKICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRzTG9hZGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJjb250cmFjdCIsICJkb2N1bWVudHMtbG9hZGVkIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJnZXQtZG9jdW1lbnRzLWZhaWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSByZXNwb25zZT8uZGF0YT8uZXJyb3I/Lm1lc3NhZ2UgPz8gcmVzcG9uc2U/LmVycm9yID8/ICJGYWlsZWQgdG8gZ2V0IGRvY3VtZW50cyIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gcmVzcG9uc2U/LmRhdGE/LmVycm9yPy5jb2RlLAogICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50cyA9IG5ldyBvYmplY3RbXSB7IH0sCiAgICAgICAgICAgICAgICAgICAgdG90YWxEb2N1bWVudHMgPSAwCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJnZXQtZG9jdW1lbnRzLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBleC5NZXNzYWdlLAogICAgICAgICAgICAgICAgICAgIGRvY3VtZW50cyA9IG5ldyBvYmplY3RbXSB7IH0sCiAgICAgICAgICAgICAgICAgICAgdG90YWxEb2N1bWVudHMgPSAwCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "documents-loaded", - "target": "process-next-document", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Documents Loaded" - }, - { - "language": "tr-TR", - "label": "Dökümanlar Yüklendi" - } - ], - "schema": null, - "rule": { - "location": "./src/DocumentsLoadedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIERvY3VtZW50cyBMb2FkZWQgUnVsZSAtIENoZWNrcyBpZiBkb2N1bWVudHMgYXJlIGxvYWRlZCBzdWNjZXNzZnVsbHkKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIERvY3VtZW50c0xvYWRlZFJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciB0b3RhbERvY3VtZW50cyA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRvdGFsRG9jdW1lbnRzID8/IDA7CiAgICAgICAgICAgIHJldHVybiAoaW50KXRvdGFsRG9jdW1lbnRzID4gMDsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "no-documents", - "target": "contract-completed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "No Documents Found" - }, - { - "language": "tr-TR", - "label": "Döküman Bulunamadı" - } - ], - "schema": null, - "rule": { - "location": "./src/NoDocumentsRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIE5vIERvY3VtZW50cyBSdWxlIC0gQ2hlY2tzIGlmIG5vIGRvY3VtZW50cyBmb3VuZAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgTm9Eb2N1bWVudHNSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgdG90YWxEb2N1bWVudHMgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50b3RhbERvY3VtZW50cyA/PyAwOwogICAgICAgICAgICByZXR1cm4gKGludCl0b3RhbERvY3VtZW50cyA9PSAwOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "process-next-document", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Process Next Document" - }, - { - "language": "tr-TR", - "label": "Sonraki Dökümanı İşle" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "start-document-subprocess", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/StartDocumentSubprocessMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTdGFydCBEb2N1bWVudCBTdWJwcm9jZXNzIE1hcHBpbmcgLSBTdGFydHMgc3VicHJvY2VzcyBmb3IgY3VycmVudCBkb2N1bWVudAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgU3RhcnREb2N1bWVudFN1YnByb2Nlc3NNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHN0YXJ0VGFzayA9IHRhc2sgYXMgU3ViUHJvY2Vzc1Rhc2s7CiAgICAgICAgICAgIGlmIChzdGFydFRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIFN0YXJ0VGFzayIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDb25maWd1cmUgdGFyZ2V0IHdvcmtmbG93CiAgICAgICAgICAgIHN0YXJ0VGFzay5TZXREb21haW4oImNvcmUiKTsKICAgICAgICAgICAgc3RhcnRUYXNrLlNldEZsb3coImNvbnRyYWN0LWRvY3VtZW50LXN1YmZsb3ciKTsKICAgICAgICAgICAgc3RhcnRUYXNrLlNldFZlcnNpb24oIjEuMC4wIik7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBHZXQgY3VycmVudCBkb2N1bWVudAogICAgICAgICAgICB2YXIgY3VycmVudEluZGV4ID0gKGludCkoY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uY3VycmVudERvY3VtZW50SW5kZXggPz8gMCk7CiAgICAgICAgICAgIHZhciBkb2N1bWVudHMgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb2N1bWVudHM7CiAgICAgICAgICAgIAogICAgICAgICAgICBvYmplY3QgY3VycmVudERvY3VtZW50ID0gbnVsbDsKICAgICAgICAgICAgaWYgKGRvY3VtZW50cyAhPSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgZG9jTGlzdCA9IG5ldyBMaXN0PG9iamVjdD4oKTsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBkb2MgaW4gZG9jdW1lbnRzKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRvY0xpc3QuQWRkKGRvYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoY3VycmVudEluZGV4IDwgZG9jTGlzdC5Db3VudCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjdXJyZW50RG9jdW1lbnQgPSBkb2NMaXN0W2N1cnJlbnRJbmRleF07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEdlbmVyYXRlIHVuaXF1ZSBrZXkgZm9yIHN1YnByb2Nlc3MKICAgICAgICAgICAgdmFyIHN1YnByb2Nlc3NLZXkgPSAkIntjb250ZXh0Lkluc3RhbmNlPy5LZXl9LWRvYy17Y3VycmVudEluZGV4fSI7CiAgICAgICAgICAgIHN0YXJ0VGFzay5TZXRLZXkoc3VicHJvY2Vzc0tleSk7CiAgICAgICAgICAgIHN0YXJ0VGFzay5TZXRUYWdzKG5ld1tdIHsgImNvbnRyYWN0IiwgImRvY3VtZW50IiwgInN1YnByb2Nlc3MiIH0pOwoKICAgICAgICAgICAgLy8gUHJlcGFyZSBpbml0aWFsaXphdGlvbiBib2R5CiAgICAgICAgICAgIHZhciBpbml0Qm9keSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwYXJlbnRJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICBwYXJlbnRJbnN0YW5jZUtleSA9IGNvbnRleHQuSW5zdGFuY2U/LktleSwKICAgICAgICAgICAgICAgIHBhcmVudFdvcmtmbG93S2V5ID0gY29udGV4dC5Xb3JrZmxvdz8uS2V5LAogICAgICAgICAgICAgICAgZG9jdW1lbnQgPSBjdXJyZW50RG9jdW1lbnQsCiAgICAgICAgICAgICAgICBkb2N1bWVudEluZGV4ID0gY3VycmVudEluZGV4LAogICAgICAgICAgICAgICAgZ3JvdXBDb2RlID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZ3JvdXBDb2RlLAogICAgICAgICAgICAgICAgc3RhcnRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHN0YXJ0VGFzay5TZXRCb2R5KGluaXRCb2R5KTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInN0YXJ0LXN1YnByb2Nlc3MtaW5wdXQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBjb250ZXh0LkJvZHk7CiAgICAgICAgICAgIHZhciBjdXJyZW50SW5kZXggPSAoaW50KShjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5jdXJyZW50RG9jdW1lbnRJbmRleCA/PyAwKTsKCiAgICAgICAgICAgIGlmIChyZXNwb25zZT8uaXNTdWNjZXNzID09IHRydWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFN0b3JlIHN1YnByb2Nlc3MgaW5zdGFuY2UgaW5mbwogICAgICAgICAgICAgICAgdmFyIGV4aXN0aW5nSW5zdGFuY2VzID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9jdW1lbnRJbnN0YW5jZXMgPz8gbmV3IG9iamVjdFtdIHsgfTsKICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZUxpc3QgPSBuZXcgTGlzdDxvYmplY3Q+KCk7CiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIgaW5zdCBpbiBleGlzdGluZ0luc3RhbmNlcykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUxpc3QuQWRkKGluc3QpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBHZXQgY3VycmVudCBkb2N1bWVudCBmb3IgY29udHJhY3RJZCByZWZlcmVuY2UKICAgICAgICAgICAgICAgIHZhciBkb2N1bWVudHMgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb2N1bWVudHM7CiAgICAgICAgICAgICAgICBvYmplY3QgY3VycmVudERvYyA9IG51bGw7CiAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnRzICE9IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdmFyIGRvY0xpc3QgPSBuZXcgTGlzdDxvYmplY3Q+KCk7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGQgaW4gZG9jdW1lbnRzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG9jTGlzdC5BZGQoZCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50SW5kZXggPCBkb2NMaXN0LkNvdW50KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudERvYyA9IGRvY0xpc3RbY3VycmVudEluZGV4XTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaW5zdGFuY2VMaXN0LkFkZChuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkID0gcmVzcG9uc2U/LmRhdGE/LmlkLAogICAgICAgICAgICAgICAgICAgIGNvbnRyYWN0SWQgPSAoKGR5bmFtaWMpY3VycmVudERvYyk/LmNvbnRyYWN0SWQsCiAgICAgICAgICAgICAgICAgICAgY29udHJhY3ROYW1lID0gKChkeW5hbWljKWN1cnJlbnREb2MpPy5jb250cmFjdE5hbWUsCiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRJbmRleCA9IGN1cnJlbnRJbmRleCwKICAgICAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gInN0YXJ0ZWQiCiAgICAgICAgICAgICAgICB9KTsKCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInN1YnByb2Nlc3Mtc3RhcnRlZCIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRJbnN0YW5jZXMgPSBpbnN0YW5jZUxpc3QuVG9BcnJheSgpLAogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50RG9jdW1lbnRJbmRleCA9IGN1cnJlbnRJbmRleCArIDEsCiAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RTdWJwcm9jZXNzSWQgPSByZXNwb25zZT8uZGF0YT8uaWQKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJjb250cmFjdCIsICJzdWJwcm9jZXNzLXN0YXJ0ZWQiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInN1YnByb2Nlc3MtZmFpbGVkIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IHJlc3BvbnNlPy5lcnJvck1lc3NhZ2UgPz8gIkZhaWxlZCB0byBzdGFydCBzdWJwcm9jZXNzIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAic3VicHJvY2Vzcy1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "subprocess-started", - "target": "waiting-for-ready", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Subprocess Started" - }, - { - "language": "tr-TR", - "label": "Alt Süreç Başlatıldı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "waiting-for-ready", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Waiting for Document Ready" - }, - { - "language": "tr-TR", - "label": "Döküman Hazır Bekliyor" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "document-ready", - "target": "check-all-ready", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Document Ready" - }, - { - "language": "tr-TR", - "label": "Döküman Hazır" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/IncrementReadyCountMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBJbmNyZW1lbnQgUmVhZHkgQ291bnQgTWFwcGluZyAtIEluY3JlbWVudHMgdGhlIHJlYWR5IGRvY3VtZW50IGNvdW50ZXIKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEluY3JlbWVudFJlYWR5Q291bnRNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBjdXJyZW50UmVhZHlDb3VudCA9IChpbnQpKGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnJlYWR5Q291bnQgPz8gMCk7CiAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uRGF0YSA9IGNvbnRleHQuQm9keTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFVzaW5nIE1vY2tvb24gY29udHJhY3Qgc3RydWN0dXJlIC0gY29udHJhY3RJZCBpbnN0ZWFkIG9mIGRvY3VtZW50SWQKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAicmVhZHktY291bnQtaW5jcmVtZW50ZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlYWR5Q291bnQgPSBjdXJyZW50UmVhZHlDb3VudCArIDEsCiAgICAgICAgICAgICAgICAgICAgbGFzdFJlYWR5Q29udHJhY3RJZCA9IHRyYW5zaXRpb25EYXRhPy5jb250cmFjdElkLAogICAgICAgICAgICAgICAgICAgIGxhc3RSZWFkeUNvbnRyYWN0TmFtZSA9IHRyYW5zaXRpb25EYXRhPy5jb250cmFjdE5hbWUsCiAgICAgICAgICAgICAgICAgICAgbGFzdFJlYWR5QXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiY29udHJhY3QiLCAiZG9jdW1lbnQtcmVhZHkiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImluY3JlbWVudC1yZWFkeS1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - } - ] - } - ] - }, - { - "key": "check-all-ready", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Check All Documents Ready" - }, - { - "language": "tr-TR", - "label": "Tüm Dökümanlar Hazır mı Kontrol Et" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "has-more-documents", - "target": "process-next-document", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Has More Documents" - }, - { - "language": "tr-TR", - "label": "Daha Fazla Döküman Var" - } - ], - "schema": null, - "rule": { - "location": "./src/HasMoreDocumentsRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEhhcyBNb3JlIERvY3VtZW50cyBSdWxlIC0gQ2hlY2tzIGlmIHRoZXJlIGFyZSBtb3JlIGRvY3VtZW50cyB0byBwcm9jZXNzCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBIYXNNb3JlRG9jdW1lbnRzUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGN1cnJlbnRJbmRleCA9IChpbnQpKGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmN1cnJlbnREb2N1bWVudEluZGV4ID8/IDApOwogICAgICAgICAgICB2YXIgdG90YWxEb2N1bWVudHMgPSAoaW50KShjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50b3RhbERvY3VtZW50cyA/PyAwKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIElmIGN1cnJlbnQgaW5kZXggaXMgbGVzcyB0aGFuIHRvdGFsLCB0aGVyZSBhcmUgbW9yZSBkb2N1bWVudHMKICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRJbmRleCA8IHRvdGFsRG9jdW1lbnRzOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KfQoK" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "all-documents-ready", - "target": "all-ready", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "All Documents Ready" - }, - { - "language": "tr-TR", - "label": "Tüm Dökümanlar Hazır" - } - ], - "schema": null, - "rule": { - "location": "./src/AllDocumentsReadyRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsbCBEb2N1bWVudHMgUmVhZHkgUnVsZSAtIENoZWNrcyBpZiBhbGwgZG9jdW1lbnRzIGFyZSByZWFkeQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgQWxsRG9jdW1lbnRzUmVhZHlSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgY3VycmVudEluZGV4ID0gKGludCkoY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uY3VycmVudERvY3VtZW50SW5kZXggPz8gMCk7CiAgICAgICAgICAgIHZhciB0b3RhbERvY3VtZW50cyA9IChpbnQpKGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRvdGFsRG9jdW1lbnRzID8/IDApOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gQWxsIGRvY3VtZW50cyBhcmUgcHJvY2Vzc2VkIChzdGFydGVkKSB3aGVuIGN1cnJlbnQgaW5kZXggZXF1YWxzIHRvdGFsCiAgICAgICAgICAgIHJldHVybiBjdXJyZW50SW5kZXggPj0gdG90YWxEb2N1bWVudHM7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9Cn0KCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "all-ready", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "All Documents Ready - Waiting for Approvals" - }, - { - "language": "tr-TR", - "label": "Tüm Dökümanlar Hazır - Onay Bekliyor" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "document-approved", - "target": "check-all-approved", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Document Approved" - }, - { - "language": "tr-TR", - "label": "Döküman Onaylandı" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/IncrementApprovedCountMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBJbmNyZW1lbnQgQXBwcm92ZWQgQ291bnQgTWFwcGluZyAtIEluY3JlbWVudHMgdGhlIGFwcHJvdmVkIGRvY3VtZW50IGNvdW50ZXIKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEluY3JlbWVudEFwcHJvdmVkQ291bnRNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBjdXJyZW50QXBwcm92ZWRDb3VudCA9IChpbnQpKGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFwcHJvdmVkQ291bnQgPz8gMCk7CiAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uRGF0YSA9IGNvbnRleHQuQm9keTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFVzaW5nIE1vY2tvb24gY29udHJhY3Qgc3RydWN0dXJlIC0gY29udHJhY3RJZCBpbnN0ZWFkIG9mIGRvY3VtZW50SWQKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiYXBwcm92ZWQtY291bnQtaW5jcmVtZW50ZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGFwcHJvdmVkQ291bnQgPSBjdXJyZW50QXBwcm92ZWRDb3VudCArIDEsCiAgICAgICAgICAgICAgICAgICAgbGFzdEFwcHJvdmVkQ29udHJhY3RJZCA9IHRyYW5zaXRpb25EYXRhPy5jb250cmFjdElkLAogICAgICAgICAgICAgICAgICAgIGxhc3RBcHByb3ZlZENvbnRyYWN0TmFtZSA9IHRyYW5zaXRpb25EYXRhPy5jb250cmFjdE5hbWUsCiAgICAgICAgICAgICAgICAgICAgbGFzdEFwcHJvdmVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiY29udHJhY3QiLCAiZG9jdW1lbnQtYXBwcm92ZWQiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImluY3JlbWVudC1hcHByb3ZlZC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - } - ] - }, - { - "key": "document-rejected", - "target": "contract-rejected", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Document Rejected" - }, - { - "language": "tr-TR", - "label": "Döküman Reddedildi" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "check-all-approved", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Check All Approved" - }, - { - "language": "tr-TR", - "label": "Tüm Onaylar Kontrol Et" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "more-approvals-pending", - "target": "all-ready", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "More Approvals Pending" - }, - { - "language": "tr-TR", - "label": "Daha Fazla Onay Bekliyor" - } - ], - "schema": null, - "rule": { - "location": "./src/MoreApprovalsPendingRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIE1vcmUgQXBwcm92YWxzIFBlbmRpbmcgUnVsZSAtIENoZWNrcyBpZiBtb3JlIGFwcHJvdmFscyBhcmUgcGVuZGluZwovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgTW9yZUFwcHJvdmFsc1BlbmRpbmdSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgYXBwcm92ZWRDb3VudCA9IChpbnQpKGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFwcHJvdmVkQ291bnQgPz8gMCk7CiAgICAgICAgICAgIHZhciB0b3RhbERvY3VtZW50cyA9IChpbnQpKGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRvdGFsRG9jdW1lbnRzID8/IDApOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gTW9yZSBhcHByb3ZhbHMgcGVuZGluZyBpZiBhcHByb3ZlZCBjb3VudCBpcyBsZXNzIHRoYW4gdG90YWwKICAgICAgICAgICAgcmV0dXJuIGFwcHJvdmVkQ291bnQgPCB0b3RhbERvY3VtZW50czsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "all-approved", - "target": "contract-completed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "All Documents Approved" - }, - { - "language": "tr-TR", - "label": "Tüm Dökümanlar Onaylandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AllApprovedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsbCBBcHByb3ZlZCBSdWxlIC0gQ2hlY2tzIGlmIGFsbCBkb2N1bWVudHMgYXJlIGFwcHJvdmVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbGxBcHByb3ZlZFJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBhcHByb3ZlZENvdW50ID0gKGludCkoY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uYXBwcm92ZWRDb3VudCA/PyAwKTsKICAgICAgICAgICAgdmFyIHRvdGFsRG9jdW1lbnRzID0gKGludCkoY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udG90YWxEb2N1bWVudHMgPz8gMCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBBbGwgYXBwcm92ZWQgd2hlbiBhcHByb3ZlZCBjb3VudCBlcXVhbHMgdG90YWwgZG9jdW1lbnRzCiAgICAgICAgICAgIHJldHVybiBhcHByb3ZlZENvdW50ID49IHRvdGFsRG9jdW1lbnRzOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "contract-completed", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Contract Completed" - }, - { - "language": "tr-TR", - "label": "Kontrat Tamamlandı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "contract-rejected", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Contract Rejected" - }, - { - "language": "tr-TR", - "label": "Kontrat Reddedildi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/contract/contract-document-subflow.json b/core/Workflows/contract/contract-document-subflow.json deleted file mode 100644 index 85270b1..0000000 --- a/core/Workflows/contract/contract-document-subflow.json +++ /dev/null @@ -1,456 +0,0 @@ -{ - "key": "contract-document-subflow", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "contract", - "document", - "subflow", - "render", - "approval" - ], - "attributes": { - "type": "S", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Contract Document Subflow" - }, - { - "language": "tr-TR", - "label": "Kontrat Döküman Alt Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-document-process", - "target": "render-document", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Document Process" - }, - { - "language": "tr-TR", - "label": "Döküman İşlemini Başlat" - } - ], - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/InitDocumentMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBJbml0aWFsaXplIERvY3VtZW50IFByb2Nlc3MgTWFwcGluZyAtIFByZXBhcmVzIGRvY3VtZW50IGRhdGEgZm9yIHN1YnByb2Nlc3MKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEluaXREb2N1bWVudE1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGlucHV0RGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJpbml0LWRvY3VtZW50LXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHBhcmVudEluc3RhbmNlSWQgPSBpbnB1dERhdGE/LnBhcmVudEluc3RhbmNlSWQsCiAgICAgICAgICAgICAgICAgICAgcGFyZW50SW5zdGFuY2VLZXkgPSBpbnB1dERhdGE/LnBhcmVudEluc3RhbmNlS2V5LAogICAgICAgICAgICAgICAgICAgIHBhcmVudFdvcmtmbG93S2V5ID0gaW5wdXREYXRhPy5wYXJlbnRXb3JrZmxvd0tleSwKICAgICAgICAgICAgICAgICAgICBkb2N1bWVudCA9IGlucHV0RGF0YT8uZG9jdW1lbnQsCiAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnRJbmRleCA9IGlucHV0RGF0YT8uZG9jdW1lbnRJbmRleCwKICAgICAgICAgICAgICAgICAgICBncm91cENvZGUgPSBpbnB1dERhdGE/Lmdyb3VwQ29kZSwKICAgICAgICAgICAgICAgICAgICBwcm9jZXNzU3RhcnRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIHJlbmRlclN0YXR1cyA9ICJwZW5kaW5nIiwKICAgICAgICAgICAgICAgICAgICBhcHByb3ZhbFN0YXR1cyA9ICJwZW5kaW5nIgogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJjb250cmFjdCIsICJkb2N1bWVudCIsICJpbml0aWFsaXplZCIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiaW5pdC1kb2N1bWVudC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - } - ] - }, - "states": [ - { - "key": "render-document", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Render Document" - }, - { - "language": "tr-TR", - "label": "Dökümanı Hazırla" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "render-document", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/RenderDocumentMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBSZW5kZXIgRG9jdW1lbnQgTWFwcGluZyAtIFJlbmRlcnMgZG9jdW1lbnQgdmlhIEhUVFAgQVBJCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBSZW5kZXJEb2N1bWVudE1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgICAgICBpZiAoaHR0cFRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgZG9jdW1lbnQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb2N1bWVudDsKICAgICAgICAgICAgdmFyIGdyb3VwQ29kZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/Lmdyb3VwQ29kZT8uVG9TdHJpbmcoKSA/PyAiIjsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIE1vY2tvb24gQVBJIGNvbnRyYWN0IHN0cnVjdHVyZTogY29udHJhY3RJZCwgY29udHJhY3RUeXBlLCBjb250cmFjdE5hbWUsIHRlbXBsYXRlSWQsIGNvbnRyYWN0RGF0YQogICAgICAgICAgICB2YXIgcmVxdWVzdEJvZHkgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZ3JvdXBDb2RlID0gZ3JvdXBDb2RlLAogICAgICAgICAgICAgICAgY29udHJhY3RJZCA9IGRvY3VtZW50Py5jb250cmFjdElkLAogICAgICAgICAgICAgICAgY29udHJhY3RUeXBlID0gZG9jdW1lbnQ/LmNvbnRyYWN0VHlwZSwKICAgICAgICAgICAgICAgIGNvbnRyYWN0TmFtZSA9IGRvY3VtZW50Py5jb250cmFjdE5hbWUsCiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUlkID0gZG9jdW1lbnQ/LnRlbXBsYXRlSWQsCiAgICAgICAgICAgICAgICBjb250cmFjdERhdGEgPSBkb2N1bWVudD8uY29udHJhY3REYXRhID8/IG5ldyB7IH0sCiAgICAgICAgICAgICAgICByZXF1ZXN0SWQgPSBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgdGltZXN0YW1wID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgIH07CgogICAgICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KTsKCiAgICAgICAgICAgIHZhciBoZWFkZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbIkNvbnRlbnQtVHlwZSJdID0gImFwcGxpY2F0aW9uL2pzb24iLAogICAgICAgICAgICAgICAgWyJYLVJlcXVlc3QtSWQiXSA9IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIlgtQ29udHJhY3QtSWQiXSA9IGRvY3VtZW50Py5jb250cmFjdElkPy5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgWyJYLUNvcnJlbGF0aW9uLUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlLklkLlRvU3RyaW5nKCkKICAgICAgICAgICAgfTsKICAgICAgICAgICAgaHR0cFRhc2suU2V0SGVhZGVycyhoZWFkZXJzKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInJlbmRlci1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKICAgICAgICAgICAgdmFyIHN0YXR1c0NvZGUgPSByZXNwb25zZT8uc3RhdHVzQ29kZSA/PyA1MDA7CgogICAgICAgICAgICBpZiAoc3RhdHVzQ29kZSA+PSAyMDAgJiYgc3RhdHVzQ29kZSA8IDMwMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gTW9ja29vbiBBUEkgcmV0dXJuczogZG9jdW1lbnRJZCwgZG9jdW1lbnRVcmwsIGRvY3VtZW50U2l6ZSwgcGFnZUNvdW50LCBjaGVja3N1bSwgZXhwaXJlc0F0LCByZW5kZXJlZEF0LCBmb3JtYXQsIHRlbXBsYXRlVmVyc2lvbgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJyZW5kZXItc3VjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyU3RhdHVzID0gInN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudElkID0gcmVzcG9uc2U/LmRhdGE/LmRhdGE/LmRvY3VtZW50SWQsCiAgICAgICAgICAgICAgICAgICAgICAgIGRvY3VtZW50VXJsID0gcmVzcG9uc2U/LmRhdGE/LmRhdGE/LmRvY3VtZW50VXJsLAogICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudFNpemUgPSByZXNwb25zZT8uZGF0YT8uZGF0YT8uZG9jdW1lbnRTaXplLAogICAgICAgICAgICAgICAgICAgICAgICBwYWdlQ291bnQgPSByZXNwb25zZT8uZGF0YT8uZGF0YT8ucGFnZUNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICBjaGVja3N1bSA9IHJlc3BvbnNlPy5kYXRhPy5kYXRhPy5jaGVja3N1bSwKICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJlc0F0ID0gcmVzcG9uc2U/LmRhdGE/LmRhdGE/LmV4cGlyZXNBdCwKICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0ID0gcmVzcG9uc2U/LmRhdGE/LmRhdGE/LmZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVWZXJzaW9uID0gcmVzcG9uc2U/LmRhdGE/LmRhdGE/LnRlbXBsYXRlVmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyZWRBdCA9IHJlc3BvbnNlPy5kYXRhPy5kYXRhPy5yZW5kZXJlZEF0ID8/IERhdGVUaW1lLlV0Y05vdy5Ub1N0cmluZygibyIpCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiY29udHJhY3QiLCAiZG9jdW1lbnQiLCAicmVuZGVyZWQiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInJlbmRlci1mYWlsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHJlbmRlclN0YXR1cyA9ICJmYWlsZWQiLAogICAgICAgICAgICAgICAgICAgIGVycm9yID0gcmVzcG9uc2U/LmRhdGE/LmVycm9yPy5tZXNzYWdlID8/IHJlc3BvbnNlPy5lcnJvciA/PyAiRmFpbGVkIHRvIHJlbmRlciBkb2N1bWVudCIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gcmVzcG9uc2U/LmRhdGE/LmVycm9yPy5jb2RlLAogICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgIGZhaWxlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJyZW5kZXItZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZW5kZXJTdGF0dXMgPSAiZmFpbGVkIiwKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgZmFpbGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "render-success", - "target": "notify-parent-ready", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Render Success" - }, - { - "language": "tr-TR", - "label": "Hazırlama Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/RenderSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFJlbmRlciBTdWNjZXNzIFJ1bGUgLSBDaGVja3MgaWYgZG9jdW1lbnQgcmVuZGVyIHdhcyBzdWNjZXNzZnVsCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBSZW5kZXJTdWNjZXNzUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlbmRlclN0YXR1cyA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnJlbmRlclN0YXR1cz8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgcmV0dXJuIHJlbmRlclN0YXR1cyA9PSAic3VjY2VzcyI7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "render-failed", - "target": "document-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Render Failed" - }, - { - "language": "tr-TR", - "label": "Hazırlama Başarısız" - } - ], - "schema": null, - "rule": { - "location": "./src/RenderFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFJlbmRlciBGYWlsZWQgUnVsZSAtIENoZWNrcyBpZiBkb2N1bWVudCByZW5kZXIgZmFpbGVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBSZW5kZXJGYWlsZWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVuZGVyU3RhdHVzID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucmVuZGVyU3RhdHVzPy5Ub1N0cmluZygpOwogICAgICAgICAgICByZXR1cm4gcmVuZGVyU3RhdHVzID09ICJmYWlsZWQiOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "notify-parent-ready", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Notify Parent - Document Ready" - }, - { - "language": "tr-TR", - "label": "Üst Akışa Bildir - Döküman Hazır" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "notify-document-ready", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/NotifyDocumentReadyMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBOb3RpZnkgRG9jdW1lbnQgUmVhZHkgTWFwcGluZyAtIE5vdGlmaWVzIHBhcmVudCB3b3JrZmxvdyB0aGF0IGRvY3VtZW50IGlzIHJlYWR5Ci8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBOb3RpZnlEb2N1bWVudFJlYWR5TWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBkaXJlY3RUcmlnZ2VyVGFzayA9IHRhc2sgYXMgRGlyZWN0VHJpZ2dlclRhc2s7CiAgICAgICAgICAgIGlmIChkaXJlY3RUcmlnZ2VyVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgRGlyZWN0VHJpZ2dlclRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ29uZmlndXJlIHRhcmdldCB3b3JrZmxvdwogICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXREb21haW4oImNvcmUiKTsKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0RmxvdygiY29udHJhY3QtYXBwcm92YWwtd29ya2Zsb3ciKTsKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0VHJhbnNpdGlvbk5hbWUoImRvY3VtZW50LXJlYWR5Iik7CiAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldFN5bmModHJ1ZSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTZXQgcGFyZW50IGluc3RhbmNlCiAgICAgICAgICAgIHZhciBwYXJlbnRJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50SW5zdGFuY2VJZD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlS2V5ID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50SW5zdGFuY2VLZXk/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KHBhcmVudEluc3RhbmNlSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXRJbnN0YW5jZShwYXJlbnRJbnN0YW5jZUlkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KHBhcmVudEluc3RhbmNlS2V5KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0S2V5KHBhcmVudEluc3RhbmNlS2V5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUHJlcGFyZSB0cmFuc2l0aW9uIGJvZHkgLSB1c2luZyBNb2Nrb29uIGNvbnRyYWN0IHN0cnVjdHVyZSAoY29udHJhY3RJZCwgY29udHJhY3ROYW1lLCBjb250cmFjdFR5cGUpCiAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uQm9keSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb250cmFjdElkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9jdW1lbnQ/LmNvbnRyYWN0SWQsCiAgICAgICAgICAgICAgICBjb250cmFjdE5hbWUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb2N1bWVudD8uY29udHJhY3ROYW1lLAogICAgICAgICAgICAgICAgY29udHJhY3RUeXBlID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9jdW1lbnQ/LmNvbnRyYWN0VHlwZSwKICAgICAgICAgICAgICAgIGRvY3VtZW50SW5kZXggPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb2N1bWVudEluZGV4LAogICAgICAgICAgICAgICAgc3VicHJvY2Vzc0luc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3NJbnN0YW5jZUtleSA9IGNvbnRleHQuSW5zdGFuY2U/LktleSwKICAgICAgICAgICAgICAgIGRvY3VtZW50VXJsID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9jdW1lbnRVcmwsCiAgICAgICAgICAgICAgICBkb2N1bWVudElkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9jdW1lbnRJZCwKICAgICAgICAgICAgICAgIHBhZ2VDb3VudCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnBhZ2VDb3VudCwKICAgICAgICAgICAgICAgIHJlYWR5QXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICBzdGF0dXMgPSAicmVhZHkiCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldEJvZHkodHJhbnNpdGlvbkJvZHkpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAibm90aWZ5LXJlYWR5LWlucHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwoKICAgICAgICAgICAgaWYgKHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPT0gdHJ1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJub3RpZnktcmVhZHktc3VjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm90aWZpZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBub3RpZmllZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiY29udHJhY3QiLCAiZG9jdW1lbnQtcmVhZHkiLCAibm90aWZpZWQiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gIm5vdGlmeS1yZWFkeS1mYWlsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHBhcmVudE5vdGlmaWVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSByZXNwb25zZT8uZXJyb3JNZXNzYWdlID8/ICJGYWlsZWQgdG8gbm90aWZ5IHBhcmVudCIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gIm5vdGlmeS1yZWFkeS1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "notify-ready-completed", - "target": "waiting-for-approval", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Notification Sent" - }, - { - "language": "tr-TR", - "label": "Bildirim Gönderildi" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "waiting-for-approval", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Waiting for Approval" - }, - { - "language": "tr-TR", - "label": "Onay Bekliyor" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "approve-document", - "target": "notify-parent-approved", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Approve Document" - }, - { - "language": "tr-TR", - "label": "Dökümanı Onayla" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "reject-document", - "target": "notify-parent-rejected", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Reject Document" - }, - { - "language": "tr-TR", - "label": "Dökümanı Reddet" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "notify-parent-approved", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Notify Parent - Approved" - }, - { - "language": "tr-TR", - "label": "Üst Akışa Bildir - Onaylandı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "notify-document-approved", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/NotifyDocumentApprovedMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBOb3RpZnkgRG9jdW1lbnQgQXBwcm92ZWQgTWFwcGluZyAtIE5vdGlmaWVzIHBhcmVudCB3b3JrZmxvdyB0aGF0IGRvY3VtZW50IGlzIGFwcHJvdmVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBOb3RpZnlEb2N1bWVudEFwcHJvdmVkTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBkaXJlY3RUcmlnZ2VyVGFzayA9IHRhc2sgYXMgRGlyZWN0VHJpZ2dlclRhc2s7CiAgICAgICAgICAgIGlmIChkaXJlY3RUcmlnZ2VyVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgRGlyZWN0VHJpZ2dlclRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ29uZmlndXJlIHRhcmdldCB3b3JrZmxvdwogICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXREb21haW4oImNvcmUiKTsKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0RmxvdygiY29udHJhY3QtYXBwcm92YWwtd29ya2Zsb3ciKTsKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0VHJhbnNpdGlvbk5hbWUoImRvY3VtZW50LWFwcHJvdmVkIik7CiAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldFN5bmModHJ1ZSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTZXQgcGFyZW50IGluc3RhbmNlCiAgICAgICAgICAgIHZhciBwYXJlbnRJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50SW5zdGFuY2VJZD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlS2V5ID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50SW5zdGFuY2VLZXk/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KHBhcmVudEluc3RhbmNlSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXRJbnN0YW5jZShwYXJlbnRJbnN0YW5jZUlkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KHBhcmVudEluc3RhbmNlS2V5KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0S2V5KHBhcmVudEluc3RhbmNlS2V5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUHJlcGFyZSB0cmFuc2l0aW9uIGJvZHkgLSB1c2luZyBNb2Nrb29uIGNvbnRyYWN0IHN0cnVjdHVyZSAoY29udHJhY3RJZCwgY29udHJhY3ROYW1lLCBjb250cmFjdFR5cGUpCiAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uQm9keSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb250cmFjdElkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9jdW1lbnQ/LmNvbnRyYWN0SWQsCiAgICAgICAgICAgICAgICBjb250cmFjdE5hbWUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb2N1bWVudD8uY29udHJhY3ROYW1lLAogICAgICAgICAgICAgICAgY29udHJhY3RUeXBlID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9jdW1lbnQ/LmNvbnRyYWN0VHlwZSwKICAgICAgICAgICAgICAgIGRvY3VtZW50SW5kZXggPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb2N1bWVudEluZGV4LAogICAgICAgICAgICAgICAgc3VicHJvY2Vzc0luc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3NJbnN0YW5jZUtleSA9IGNvbnRleHQuSW5zdGFuY2U/LktleSwKICAgICAgICAgICAgICAgIGFwcHJvdmVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICBhcHByb3ZlZEJ5ID0gY29udGV4dC5Cb2R5Py5hcHByb3ZlZEJ5ID8/ICJ1c2VyIiwKICAgICAgICAgICAgICAgIHN0YXR1cyA9ICJhcHByb3ZlZCIKICAgICAgICAgICAgfTsKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0Qm9keSh0cmFuc2l0aW9uQm9keSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJub3RpZnktYXBwcm92ZWQtaW5wdXQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgcmVzcG9uc2UgPSBjb250ZXh0LkJvZHk7CgogICAgICAgICAgICBpZiAocmVzcG9uc2U/LmlzU3VjY2VzcyA9PSB0cnVlKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gIm5vdGlmeS1hcHByb3ZlZC1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnROb3RpZmllZCA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGFwcHJvdmFsU3RhdHVzID0gImFwcHJvdmVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgbm90aWZpZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImNvbnRyYWN0IiwgImRvY3VtZW50LWFwcHJvdmVkIiwgIm5vdGlmaWVkIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJub3RpZnktYXBwcm92ZWQtZmFpbGVkIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBwYXJlbnROb3RpZmllZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGVycm9yID0gcmVzcG9uc2U/LmVycm9yTWVzc2FnZSA/PyAiRmFpbGVkIHRvIG5vdGlmeSBwYXJlbnQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJub3RpZnktYXBwcm92ZWQtZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "approval-notified", - "target": "document-completed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Approval Notified" - }, - { - "language": "tr-TR", - "label": "Onay Bildirildi" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "notify-parent-rejected", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Notify Parent - Rejected" - }, - { - "language": "tr-TR", - "label": "Üst Akışa Bildir - Reddedildi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "notify-document-approved", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/NotifyDocumentRejectedMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBOb3RpZnkgRG9jdW1lbnQgUmVqZWN0ZWQgTWFwcGluZyAtIE5vdGlmaWVzIHBhcmVudCB3b3JrZmxvdyB0aGF0IGRvY3VtZW50IGlzIHJlamVjdGVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBOb3RpZnlEb2N1bWVudFJlamVjdGVkTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBkaXJlY3RUcmlnZ2VyVGFzayA9IHRhc2sgYXMgRGlyZWN0VHJpZ2dlclRhc2s7CiAgICAgICAgICAgIGlmIChkaXJlY3RUcmlnZ2VyVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgRGlyZWN0VHJpZ2dlclRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ29uZmlndXJlIHRhcmdldCB3b3JrZmxvdwogICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXREb21haW4oImNvcmUiKTsKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0RmxvdygiY29udHJhY3QtYXBwcm92YWwtd29ya2Zsb3ciKTsKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0VHJhbnNpdGlvbk5hbWUoImRvY3VtZW50LXJlamVjdGVkIik7CiAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldFN5bmModHJ1ZSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTZXQgcGFyZW50IGluc3RhbmNlCiAgICAgICAgICAgIHZhciBwYXJlbnRJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50SW5zdGFuY2VJZD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlS2V5ID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGFyZW50SW5zdGFuY2VLZXk/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KHBhcmVudEluc3RhbmNlSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXRJbnN0YW5jZShwYXJlbnRJbnN0YW5jZUlkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KHBhcmVudEluc3RhbmNlS2V5KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0S2V5KHBhcmVudEluc3RhbmNlS2V5KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUHJlcGFyZSB0cmFuc2l0aW9uIGJvZHkgLSB1c2luZyBNb2Nrb29uIGNvbnRyYWN0IHN0cnVjdHVyZSAoY29udHJhY3RJZCwgY29udHJhY3ROYW1lLCBjb250cmFjdFR5cGUpCiAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uQm9keSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb250cmFjdElkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9jdW1lbnQ/LmNvbnRyYWN0SWQsCiAgICAgICAgICAgICAgICBjb250cmFjdE5hbWUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb2N1bWVudD8uY29udHJhY3ROYW1lLAogICAgICAgICAgICAgICAgY29udHJhY3RUeXBlID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9jdW1lbnQ/LmNvbnRyYWN0VHlwZSwKICAgICAgICAgICAgICAgIGRvY3VtZW50SW5kZXggPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb2N1bWVudEluZGV4LAogICAgICAgICAgICAgICAgc3VicHJvY2Vzc0luc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgIHN1YnByb2Nlc3NJbnN0YW5jZUtleSA9IGNvbnRleHQuSW5zdGFuY2U/LktleSwKICAgICAgICAgICAgICAgIHJlamVjdGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICByZWplY3RlZEJ5ID0gY29udGV4dC5Cb2R5Py5yZWplY3RlZEJ5ID8/ICJ1c2VyIiwKICAgICAgICAgICAgICAgIHJlamVjdGlvblJlYXNvbiA9IGNvbnRleHQuQm9keT8ucmVhc29uID8/ICJObyByZWFzb24gcHJvdmlkZWQiLAogICAgICAgICAgICAgICAgc3RhdHVzID0gInJlamVjdGVkIgogICAgICAgICAgICB9OwogICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXRCb2R5KHRyYW5zaXRpb25Cb2R5KTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gIm5vdGlmeS1yZWplY3RlZC1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgICAgIGlmIChyZXNwb25zZT8uaXNTdWNjZXNzID09IHRydWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAibm90aWZ5LXJlamVjdGVkLXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudE5vdGlmaWVkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgYXBwcm92YWxTdGF0dXMgPSAicmVqZWN0ZWQiLAogICAgICAgICAgICAgICAgICAgICAgICBub3RpZmllZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiY29udHJhY3QiLCAiZG9jdW1lbnQtcmVqZWN0ZWQiLCAibm90aWZpZWQiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gIm5vdGlmeS1yZWplY3RlZC1mYWlsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHBhcmVudE5vdGlmaWVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSByZXNwb25zZT8uZXJyb3JNZXNzYWdlID8/ICJGYWlsZWQgdG8gbm90aWZ5IHBhcmVudCIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gIm5vdGlmeS1yZWplY3RlZC1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "rejection-notified", - "target": "document-rejected", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Rejection Notified" - }, - { - "language": "tr-TR", - "label": "Red Bildirildi" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "document-completed", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Document Approved" - }, - { - "language": "tr-TR", - "label": "Döküman Onaylandı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "document-rejected", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Document Rejected" - }, - { - "language": "tr-TR", - "label": "Döküman Reddedildi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "document-failed", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Document Failed" - }, - { - "language": "tr-TR", - "label": "Döküman Başarısız" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/contract/src/AllApprovedRule.csx b/core/Workflows/contract/src/AllApprovedRule.csx deleted file mode 100644 index d685540..0000000 --- a/core/Workflows/contract/src/AllApprovedRule.csx +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// All Approved Rule - Checks if all documents are approved -/// -public class AllApprovedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - var approvedCount = (int)(context.Instance?.Data?.approvedCount ?? 0); - var totalDocuments = (int)(context.Instance?.Data?.totalDocuments ?? 0); - - // All approved when approved count equals total documents - return approvedCount >= totalDocuments; - } - catch (Exception) - { - return true; - } - } -} - diff --git a/core/Workflows/contract/src/AllDocumentsReadyRule.csx b/core/Workflows/contract/src/AllDocumentsReadyRule.csx deleted file mode 100644 index 9678ce0..0000000 --- a/core/Workflows/contract/src/AllDocumentsReadyRule.csx +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// All Documents Ready Rule - Checks if all documents are ready -/// -public class AllDocumentsReadyRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - var currentIndex = (int)(context.Instance?.Data?.currentDocumentIndex ?? 0); - var totalDocuments = (int)(context.Instance?.Data?.totalDocuments ?? 0); - - // All documents are processed (started) when current index equals total - return currentIndex >= totalDocuments; - } - catch (Exception) - { - return true; - } - } -} - diff --git a/core/Workflows/contract/src/AlwaysTrueRule.csx b/core/Workflows/contract/src/AlwaysTrueRule.csx deleted file mode 100644 index 44e727b..0000000 --- a/core/Workflows/contract/src/AlwaysTrueRule.csx +++ /dev/null @@ -1,14 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Always True Rule - Used for auto transitions that should always proceed -/// -public class AlwaysTrueRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return true; - } -} - diff --git a/core/Workflows/contract/src/DocumentsLoadedRule.csx b/core/Workflows/contract/src/DocumentsLoadedRule.csx deleted file mode 100644 index d9efb05..0000000 --- a/core/Workflows/contract/src/DocumentsLoadedRule.csx +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Documents Loaded Rule - Checks if documents are loaded successfully -/// -public class DocumentsLoadedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - var totalDocuments = context.Instance?.Data?.totalDocuments ?? 0; - return (int)totalDocuments > 0; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/contract/src/GetContractDocumentsMapping.csx b/core/Workflows/contract/src/GetContractDocumentsMapping.csx deleted file mode 100644 index f42b81c..0000000 --- a/core/Workflows/contract/src/GetContractDocumentsMapping.csx +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Get Contract Documents Mapping - Retrieves document list from API -/// -public class GetContractDocumentsMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var groupCode = context.Instance?.Data?.groupCode?.ToString() ?? ""; - - // Mockoon API expects "groupCode" field - var requestBody = new - { - groupCode = groupCode, - requestId = Guid.NewGuid().ToString(), - timestamp = DateTime.UtcNow - }; - - httpTask.SetBody(requestBody); - - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Request-Id"] = Guid.NewGuid().ToString(), - ["X-Correlation-Id"] = context.Instance.Id.ToString() - }; - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "get-documents-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - var statusCode = response?.statusCode ?? 500; - - if (statusCode >= 200 && statusCode < 300) - { - // Mockoon API returns "contracts" array, not "documents" - var contracts = response?.data?.data?.contracts ?? new object[] { }; - var contractList = new List(); - - if (contracts != null) - { - foreach (var contract in contracts) - { - contractList.Add(contract); - } - } - - // totalContracts from API response or calculated from list - var totalContracts = response?.data?.data?.totalContracts ?? contractList.Count; - - return new ScriptResponse - { - Key = "get-documents-success", - Data = new - { - documents = contractList.ToArray(), - totalDocuments = (int)totalContracts, - groupCode = response?.data?.data?.groupCode, - retrievedAt = response?.data?.data?.retrievedAt, - currentDocumentIndex = 0, - readyCount = 0, - approvedCount = 0, - documentInstances = new object[] { }, - documentsLoadedAt = DateTime.UtcNow - }, - Tags = new[] { "contract", "documents-loaded" } - }; - } - - return new ScriptResponse - { - Key = "get-documents-failed", - Data = new - { - error = response?.data?.error?.message ?? response?.error ?? "Failed to get documents", - errorCode = response?.data?.error?.code, - statusCode = statusCode, - documents = new object[] { }, - totalDocuments = 0 - } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "get-documents-exception", - Data = new - { - error = ex.Message, - documents = new object[] { }, - totalDocuments = 0 - } - }; - } - } -} - diff --git a/core/Workflows/contract/src/HasMoreDocumentsRule.csx b/core/Workflows/contract/src/HasMoreDocumentsRule.csx deleted file mode 100644 index f116078..0000000 --- a/core/Workflows/contract/src/HasMoreDocumentsRule.csx +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Has More Documents Rule - Checks if there are more documents to process -/// -public class HasMoreDocumentsRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - var currentIndex = (int)(context.Instance?.Data?.currentDocumentIndex ?? 0); - var totalDocuments = (int)(context.Instance?.Data?.totalDocuments ?? 0); - - // If current index is less than total, there are more documents - return currentIndex < totalDocuments; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/contract/src/IncrementApprovedCountMapping.csx b/core/Workflows/contract/src/IncrementApprovedCountMapping.csx deleted file mode 100644 index b463c9b..0000000 --- a/core/Workflows/contract/src/IncrementApprovedCountMapping.csx +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Increment Approved Count Mapping - Increments the approved document counter -/// -public class IncrementApprovedCountMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var currentApprovedCount = (int)(context.Instance?.Data?.approvedCount ?? 0); - var transitionData = context.Body; - - // Using Mockoon contract structure - contractId instead of documentId - return new ScriptResponse - { - Key = "approved-count-incremented", - Data = new - { - approvedCount = currentApprovedCount + 1, - lastApprovedContractId = transitionData?.contractId, - lastApprovedContractName = transitionData?.contractName, - lastApprovedAt = DateTime.UtcNow - }, - Tags = new[] { "contract", "document-approved" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "increment-approved-error", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/contract/src/IncrementReadyCountMapping.csx b/core/Workflows/contract/src/IncrementReadyCountMapping.csx deleted file mode 100644 index ce5e785..0000000 --- a/core/Workflows/contract/src/IncrementReadyCountMapping.csx +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Increment Ready Count Mapping - Increments the ready document counter -/// -public class IncrementReadyCountMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var currentReadyCount = (int)(context.Instance?.Data?.readyCount ?? 0); - var transitionData = context.Body; - - // Using Mockoon contract structure - contractId instead of documentId - return new ScriptResponse - { - Key = "ready-count-incremented", - Data = new - { - readyCount = currentReadyCount + 1, - lastReadyContractId = transitionData?.contractId, - lastReadyContractName = transitionData?.contractName, - lastReadyAt = DateTime.UtcNow - }, - Tags = new[] { "contract", "document-ready" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "increment-ready-error", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/contract/src/InitContractApprovalMapping.csx b/core/Workflows/contract/src/InitContractApprovalMapping.csx deleted file mode 100644 index d28c07d..0000000 --- a/core/Workflows/contract/src/InitContractApprovalMapping.csx +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Initialize Contract Approval Workflow - Prepares initial data -/// -public class InitContractApprovalMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var inputData = context.Instance?.Data; - var groupCode = inputData?.groupCode?.ToString() ?? ""; - - return new ScriptResponse - { - Key = "init-success", - Data = new - { - groupCode = groupCode, - workflowStartedAt = DateTime.UtcNow, - documents = new object[] { }, - currentDocumentIndex = 0, - readyCount = 0, - approvedCount = 0, - rejectedCount = 0, - totalDocuments = 0, - documentInstances = new object[] { }, - status = "initialized" - }, - Tags = new[] { "contract", "initialized" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "init-error", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/contract/src/InitDocumentMapping.csx b/core/Workflows/contract/src/InitDocumentMapping.csx deleted file mode 100644 index 3d964c1..0000000 --- a/core/Workflows/contract/src/InitDocumentMapping.csx +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Initialize Document Process Mapping - Prepares document data for subprocess -/// -public class InitDocumentMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var inputData = context.Instance?.Data; - - return new ScriptResponse - { - Key = "init-document-success", - Data = new - { - parentInstanceId = inputData?.parentInstanceId, - parentInstanceKey = inputData?.parentInstanceKey, - parentWorkflowKey = inputData?.parentWorkflowKey, - document = inputData?.document, - documentIndex = inputData?.documentIndex, - groupCode = inputData?.groupCode, - processStartedAt = DateTime.UtcNow, - renderStatus = "pending", - approvalStatus = "pending" - }, - Tags = new[] { "contract", "document", "initialized" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "init-document-error", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/contract/src/MoreApprovalsPendingRule.csx b/core/Workflows/contract/src/MoreApprovalsPendingRule.csx deleted file mode 100644 index fa07a11..0000000 --- a/core/Workflows/contract/src/MoreApprovalsPendingRule.csx +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// More Approvals Pending Rule - Checks if more approvals are pending -/// -public class MoreApprovalsPendingRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - var approvedCount = (int)(context.Instance?.Data?.approvedCount ?? 0); - var totalDocuments = (int)(context.Instance?.Data?.totalDocuments ?? 0); - - // More approvals pending if approved count is less than total - return approvedCount < totalDocuments; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/contract/src/NoDocumentsRule.csx b/core/Workflows/contract/src/NoDocumentsRule.csx deleted file mode 100644 index 26082eb..0000000 --- a/core/Workflows/contract/src/NoDocumentsRule.csx +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// No Documents Rule - Checks if no documents found -/// -public class NoDocumentsRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - var totalDocuments = context.Instance?.Data?.totalDocuments ?? 0; - return (int)totalDocuments == 0; - } - catch (Exception) - { - return true; - } - } -} - diff --git a/core/Workflows/contract/src/NotifyDocumentApprovedMapping.csx b/core/Workflows/contract/src/NotifyDocumentApprovedMapping.csx deleted file mode 100644 index de50185..0000000 --- a/core/Workflows/contract/src/NotifyDocumentApprovedMapping.csx +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Notify Document Approved Mapping - Notifies parent workflow that document is approved -/// -public class NotifyDocumentApprovedMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var directTriggerTask = task as DirectTriggerTask; - if (directTriggerTask == null) - { - throw new InvalidOperationException("Task must be a DirectTriggerTask"); - } - - // Configure target workflow - directTriggerTask.SetDomain("core"); - directTriggerTask.SetFlow("contract-approval-workflow"); - directTriggerTask.SetTransitionName("document-approved"); - directTriggerTask.SetSync(true); - - // Set parent instance - var parentInstanceId = context.Instance?.Data?.parentInstanceId?.ToString(); - var parentInstanceKey = context.Instance?.Data?.parentInstanceKey?.ToString(); - - if (!string.IsNullOrEmpty(parentInstanceId)) - { - directTriggerTask.SetInstance(parentInstanceId); - } - if (!string.IsNullOrEmpty(parentInstanceKey)) - { - directTriggerTask.SetKey(parentInstanceKey); - } - - // Prepare transition body - using Mockoon contract structure (contractId, contractName, contractType) - var transitionBody = new - { - contractId = context.Instance?.Data?.document?.contractId, - contractName = context.Instance?.Data?.document?.contractName, - contractType = context.Instance?.Data?.document?.contractType, - documentIndex = context.Instance?.Data?.documentIndex, - subprocessInstanceId = context.Instance?.Id, - subprocessInstanceKey = context.Instance?.Key, - approvedAt = DateTime.UtcNow, - approvedBy = context.Body?.approvedBy ?? "user", - status = "approved" - }; - directTriggerTask.SetBody(transitionBody); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "notify-approved-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - if (response?.isSuccess == true) - { - return new ScriptResponse - { - Key = "notify-approved-success", - Data = new - { - parentNotified = true, - approvalStatus = "approved", - notifiedAt = DateTime.UtcNow - }, - Tags = new[] { "contract", "document-approved", "notified" } - }; - } - - return new ScriptResponse - { - Key = "notify-approved-failed", - Data = new - { - parentNotified = false, - error = response?.errorMessage ?? "Failed to notify parent" - } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "notify-approved-exception", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/contract/src/NotifyDocumentReadyMapping.csx b/core/Workflows/contract/src/NotifyDocumentReadyMapping.csx deleted file mode 100644 index 70dd054..0000000 --- a/core/Workflows/contract/src/NotifyDocumentReadyMapping.csx +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Notify Document Ready Mapping - Notifies parent workflow that document is ready -/// -public class NotifyDocumentReadyMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var directTriggerTask = task as DirectTriggerTask; - if (directTriggerTask == null) - { - throw new InvalidOperationException("Task must be a DirectTriggerTask"); - } - - // Configure target workflow - directTriggerTask.SetDomain("core"); - directTriggerTask.SetFlow("contract-approval-workflow"); - directTriggerTask.SetTransitionName("document-ready"); - directTriggerTask.SetSync(true); - - // Set parent instance - var parentInstanceId = context.Instance?.Data?.parentInstanceId?.ToString(); - var parentInstanceKey = context.Instance?.Data?.parentInstanceKey?.ToString(); - - if (!string.IsNullOrEmpty(parentInstanceId)) - { - directTriggerTask.SetInstance(parentInstanceId); - } - if (!string.IsNullOrEmpty(parentInstanceKey)) - { - directTriggerTask.SetKey(parentInstanceKey); - } - - // Prepare transition body - using Mockoon contract structure (contractId, contractName, contractType) - var transitionBody = new - { - contractId = context.Instance?.Data?.document?.contractId, - contractName = context.Instance?.Data?.document?.contractName, - contractType = context.Instance?.Data?.document?.contractType, - documentIndex = context.Instance?.Data?.documentIndex, - subprocessInstanceId = context.Instance?.Id, - subprocessInstanceKey = context.Instance?.Key, - documentUrl = context.Instance?.Data?.documentUrl, - documentId = context.Instance?.Data?.documentId, - pageCount = context.Instance?.Data?.pageCount, - readyAt = DateTime.UtcNow, - status = "ready" - }; - directTriggerTask.SetBody(transitionBody); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "notify-ready-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - if (response?.isSuccess == true) - { - return new ScriptResponse - { - Key = "notify-ready-success", - Data = new - { - parentNotified = true, - notifiedAt = DateTime.UtcNow - }, - Tags = new[] { "contract", "document-ready", "notified" } - }; - } - - return new ScriptResponse - { - Key = "notify-ready-failed", - Data = new - { - parentNotified = false, - error = response?.errorMessage ?? "Failed to notify parent" - } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "notify-ready-exception", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/contract/src/NotifyDocumentRejectedMapping.csx b/core/Workflows/contract/src/NotifyDocumentRejectedMapping.csx deleted file mode 100644 index 53c0da5..0000000 --- a/core/Workflows/contract/src/NotifyDocumentRejectedMapping.csx +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Notify Document Rejected Mapping - Notifies parent workflow that document is rejected -/// -public class NotifyDocumentRejectedMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var directTriggerTask = task as DirectTriggerTask; - if (directTriggerTask == null) - { - throw new InvalidOperationException("Task must be a DirectTriggerTask"); - } - - // Configure target workflow - directTriggerTask.SetDomain("core"); - directTriggerTask.SetFlow("contract-approval-workflow"); - directTriggerTask.SetTransitionName("document-rejected"); - directTriggerTask.SetSync(true); - - // Set parent instance - var parentInstanceId = context.Instance?.Data?.parentInstanceId?.ToString(); - var parentInstanceKey = context.Instance?.Data?.parentInstanceKey?.ToString(); - - if (!string.IsNullOrEmpty(parentInstanceId)) - { - directTriggerTask.SetInstance(parentInstanceId); - } - if (!string.IsNullOrEmpty(parentInstanceKey)) - { - directTriggerTask.SetKey(parentInstanceKey); - } - - // Prepare transition body - using Mockoon contract structure (contractId, contractName, contractType) - var transitionBody = new - { - contractId = context.Instance?.Data?.document?.contractId, - contractName = context.Instance?.Data?.document?.contractName, - contractType = context.Instance?.Data?.document?.contractType, - documentIndex = context.Instance?.Data?.documentIndex, - subprocessInstanceId = context.Instance?.Id, - subprocessInstanceKey = context.Instance?.Key, - rejectedAt = DateTime.UtcNow, - rejectedBy = context.Body?.rejectedBy ?? "user", - rejectionReason = context.Body?.reason ?? "No reason provided", - status = "rejected" - }; - directTriggerTask.SetBody(transitionBody); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "notify-rejected-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - if (response?.isSuccess == true) - { - return new ScriptResponse - { - Key = "notify-rejected-success", - Data = new - { - parentNotified = true, - approvalStatus = "rejected", - notifiedAt = DateTime.UtcNow - }, - Tags = new[] { "contract", "document-rejected", "notified" } - }; - } - - return new ScriptResponse - { - Key = "notify-rejected-failed", - Data = new - { - parentNotified = false, - error = response?.errorMessage ?? "Failed to notify parent" - } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "notify-rejected-exception", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/contract/src/RenderDocumentMapping.csx b/core/Workflows/contract/src/RenderDocumentMapping.csx deleted file mode 100644 index b1cf707..0000000 --- a/core/Workflows/contract/src/RenderDocumentMapping.csx +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Render Document Mapping - Renders document via HTTP API -/// -public class RenderDocumentMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var document = context.Instance?.Data?.document; - var groupCode = context.Instance?.Data?.groupCode?.ToString() ?? ""; - - // Mockoon API contract structure: contractId, contractType, contractName, templateId, contractData - var requestBody = new - { - groupCode = groupCode, - contractId = document?.contractId, - contractType = document?.contractType, - contractName = document?.contractName, - templateId = document?.templateId, - contractData = document?.contractData ?? new { }, - requestId = Guid.NewGuid().ToString(), - timestamp = DateTime.UtcNow - }; - - httpTask.SetBody(requestBody); - - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Request-Id"] = Guid.NewGuid().ToString(), - ["X-Contract-Id"] = document?.contractId?.ToString(), - ["X-Correlation-Id"] = context.Instance.Id.ToString() - }; - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "render-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - var statusCode = response?.statusCode ?? 500; - - if (statusCode >= 200 && statusCode < 300) - { - // Mockoon API returns: documentId, documentUrl, documentSize, pageCount, checksum, expiresAt, renderedAt, format, templateVersion - return new ScriptResponse - { - Key = "render-success", - Data = new - { - renderStatus = "success", - documentId = response?.data?.data?.documentId, - documentUrl = response?.data?.data?.documentUrl, - documentSize = response?.data?.data?.documentSize, - pageCount = response?.data?.data?.pageCount, - checksum = response?.data?.data?.checksum, - expiresAt = response?.data?.data?.expiresAt, - format = response?.data?.data?.format, - templateVersion = response?.data?.data?.templateVersion, - renderedAt = response?.data?.data?.renderedAt ?? DateTime.UtcNow.ToString("o") - }, - Tags = new[] { "contract", "document", "rendered" } - }; - } - - return new ScriptResponse - { - Key = "render-failed", - Data = new - { - renderStatus = "failed", - error = response?.data?.error?.message ?? response?.error ?? "Failed to render document", - errorCode = response?.data?.error?.code, - statusCode = statusCode, - failedAt = DateTime.UtcNow - } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "render-exception", - Data = new - { - renderStatus = "failed", - error = ex.Message, - failedAt = DateTime.UtcNow - } - }; - } - } -} - diff --git a/core/Workflows/contract/src/RenderFailedRule.csx b/core/Workflows/contract/src/RenderFailedRule.csx deleted file mode 100644 index ea9dabb..0000000 --- a/core/Workflows/contract/src/RenderFailedRule.csx +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Render Failed Rule - Checks if document render failed -/// -public class RenderFailedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - var renderStatus = context.Instance?.Data?.renderStatus?.ToString(); - return renderStatus == "failed"; - } - catch (Exception) - { - return true; - } - } -} - diff --git a/core/Workflows/contract/src/RenderSuccessRule.csx b/core/Workflows/contract/src/RenderSuccessRule.csx deleted file mode 100644 index 37ff4ac..0000000 --- a/core/Workflows/contract/src/RenderSuccessRule.csx +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Render Success Rule - Checks if document render was successful -/// -public class RenderSuccessRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - var renderStatus = context.Instance?.Data?.renderStatus?.ToString(); - return renderStatus == "success"; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/contract/src/StartDocumentSubprocessMapping.csx b/core/Workflows/contract/src/StartDocumentSubprocessMapping.csx deleted file mode 100644 index bf2359d..0000000 --- a/core/Workflows/contract/src/StartDocumentSubprocessMapping.csx +++ /dev/null @@ -1,149 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Start Document Subprocess Mapping - Starts subprocess for current document -/// -public class StartDocumentSubprocessMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var startTask = task as SubProcessTask; - if (startTask == null) - { - throw new InvalidOperationException("Task must be a StartTask"); - } - - // Configure target workflow - startTask.SetDomain("core"); - startTask.SetFlow("contract-document-subflow"); - startTask.SetVersion("1.0.0"); - - // Get current document - var currentIndex = (int)(context.Instance?.Data?.currentDocumentIndex ?? 0); - var documents = context.Instance?.Data?.documents; - - object currentDocument = null; - if (documents != null) - { - var docList = new List(); - foreach (var doc in documents) - { - docList.Add(doc); - } - if (currentIndex < docList.Count) - { - currentDocument = docList[currentIndex]; - } - } - - // Generate unique key for subprocess - var subprocessKey = $"{context.Instance?.Key}-doc-{currentIndex}"; - startTask.SetKey(subprocessKey); - startTask.SetTags(new[] { "contract", "document", "subprocess" }); - - // Prepare initialization body - var initBody = new - { - parentInstanceId = context.Instance?.Id, - parentInstanceKey = context.Instance?.Key, - parentWorkflowKey = context.Workflow?.Key, - document = currentDocument, - documentIndex = currentIndex, - groupCode = context.Instance?.Data?.groupCode, - startedAt = DateTime.UtcNow - }; - startTask.SetBody(initBody); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "start-subprocess-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - var currentIndex = (int)(context.Instance?.Data?.currentDocumentIndex ?? 0); - - if (response?.isSuccess == true) - { - // Store subprocess instance info - var existingInstances = context.Instance?.Data?.documentInstances ?? new object[] { }; - var instanceList = new List(); - foreach (var inst in existingInstances) - { - instanceList.Add(inst); - } - - // Get current document for contractId reference - var documents = context.Instance?.Data?.documents; - object currentDoc = null; - if (documents != null) - { - var docList = new List(); - foreach (var d in documents) - { - docList.Add(d); - } - if (currentIndex < docList.Count) - { - currentDoc = docList[currentIndex]; - } - } - - instanceList.Add(new - { - instanceId = response?.data?.id, - contractId = ((dynamic)currentDoc)?.contractId, - contractName = ((dynamic)currentDoc)?.contractName, - documentIndex = currentIndex, - startedAt = DateTime.UtcNow, - status = "started" - }); - - return new ScriptResponse - { - Key = "subprocess-started", - Data = new - { - documentInstances = instanceList.ToArray(), - currentDocumentIndex = currentIndex + 1, - lastSubprocessId = response?.data?.id - }, - Tags = new[] { "contract", "subprocess-started" } - }; - } - - return new ScriptResponse - { - Key = "subprocess-failed", - Data = new - { - error = response?.errorMessage ?? "Failed to start subprocess" - } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "subprocess-exception", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/discovery/domain-health-check-workflow.json b/core/Workflows/discovery/domain-health-check-workflow.json deleted file mode 100644 index 11db359..0000000 --- a/core/Workflows/discovery/domain-health-check-workflow.json +++ /dev/null @@ -1,569 +0,0 @@ -{ - "key": "domain-health-check", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "domain", - "health-check", - "api", - "monitoring", - "scheduled", - "pagination" - ], - "attributes": { - "type": "F", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Domain Health Check Workflow" - }, - { - "language": "tr-TR", - "label": "Domain Sağlık Kontrolü İş Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-health-check", - "target": "initial", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Health Check" - }, - { - "language": "tr-TR", - "label": "Sağlık Kontrolünü Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "initial", - "stateType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Initial" - }, - { - "language": "tr-TR", - "label": "Başlangıç" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "to-fetch-domains", - "target": "fetch-domains", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Fetch Domains" - }, - { - "language": "tr-TR", - "label": "Otomatik - Domainleri Getir" - } - ], - "schema": null, - "rule": { - "location": "./src/InitialTransitionRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEluaXRpYWwgVHJhbnNpdGlvbiBSdWxlIC0gQWx3YXlzIGFsbG93cyB0cmFuc2l0aW9uIGZyb20gaW5pdGlhbCBzdGF0ZQovLy8gVGhpcyBydWxlIGFsd2F5cyByZXR1cm5zIHRydWUgdG8gYWxsb3cgYXV0b21hdGljIHRyYW5zaXRpb24gZnJvbSBpbml0aWFsIHN0YXRlCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBJbml0aWFsVHJhbnNpdGlvblJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIEFsd2F5cyBhbGxvdyB0cmFuc2l0aW9uIGZyb20gaW5pdGlhbCBzdGF0ZQogICAgICAgICAgICAvLyBJbml0aWFsIHN0YXRlIGlzIHRoZSBlbnRyeSBwb2ludCwgc28gdHJhbnNpdGlvbiBzaG91bGQgYWx3YXlzIHByb2NlZWQKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICAvLyBPbiBlcnJvciwgc3RpbGwgYWxsb3cgdHJhbnNpdGlvbiB0byBwcmV2ZW50IHdvcmtmbG93IGZyb20gZ2V0dGluZyBzdHVjawogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9Cn0KCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "fetch-domains", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Fetch Domains" - }, - { - "language": "tr-TR", - "label": "Domainleri Getir" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "domains-fetched", - "target": "process-page", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Domains Fetched" - }, - { - "language": "tr-TR", - "label": "Otomatik - Domainler Getirildi" - } - ], - "schema": null, - "rule": { - "location": "./src/DomainsFetchedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIERvbWFpbnMgRmV0Y2hlZCBSdWxlIC0gQ2hlY2tzIGlmIGRvbWFpbnMgd2VyZSBzdWNjZXNzZnVsbHkgZmV0Y2hlZAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRG9tYWluc0ZldGNoZWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICAvLyBBbHdheXMgcmV0dXJuIHRydWUgLSBtYXBwaW5nIGhhbmRsZXMgdGhlIGxvZ2ljIHZpYSBLZXkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "fetch-failed", - "target": "schedule-next-run", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Fetch Failed" - }, - { - "language": "tr-TR", - "label": "Otomatik - Getirme Başarısız" - } - ], - "schema": null, - "rule": { - "location": "./src/FetchFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEZldGNoIEZhaWxlZCBSdWxlIC0gQ2hlY2tzIGlmIGZldGNoIGZhaWxlZAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRmV0Y2hGYWlsZWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICAvLyBBbHdheXMgcmV0dXJuIHRydWUgLSBtYXBwaW5nIGhhbmRsZXMgdGhlIGxvZ2ljIHZpYSBLZXkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "process-page", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Process Page" - }, - { - "language": "tr-TR", - "label": "Sayfayı İşle" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "to-check-health", - "target": "check-domain-health", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - To Check Health" - }, - { - "language": "tr-TR", - "label": "Otomatik - Sağlık Kontrolüne" - } - ], - "schema": null, - "rule": { - "location": "./src/ToCheckHealthRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUbyBDaGVjayBIZWFsdGggUnVsZSAtIENoZWNrcyBpZiBzaG91bGQgcHJvY2VlZCB0byBoZWFsdGggY2hlY2sKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFRvQ2hlY2tIZWFsdGhSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBwZW5kaW5nRG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5wZW5kaW5nRG9tYWlucyBhcyBMaXN0PG9iamVjdD47CiAgICAgICAgICAgIHJldHVybiBwZW5kaW5nRG9tYWlucyAhPSBudWxsICYmIHBlbmRpbmdEb21haW5zLkNvdW50ID4gMDsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "no-domains", - "target": "check-pagination", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - No Domains" - }, - { - "language": "tr-TR", - "label": "Otomatik - Domain Yok" - } - ], - "schema": null, - "rule": { - "location": "./src/NoDomainsRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBObyBEb21haW5zIFJ1bGUgLSBDaGVja3MgaWYgbm8gZG9tYWlucyB0byBwcm9jZXNzCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBOb0RvbWFpbnNSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgdmFyIHBlbmRpbmdEb21haW5zID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLnBlbmRpbmdEb21haW5zIGFzIExpc3Q8b2JqZWN0PjsKICAgICAgICAgICAgcmV0dXJuIHBlbmRpbmdEb21haW5zID09IG51bGwgfHwgcGVuZGluZ0RvbWFpbnMuQ291bnQgPT0gMDsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0KfQoK" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "check-domain-health", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Check Domain Health" - }, - { - "language": "tr-TR", - "label": "Domain Sağlığını Kontrol Et" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "check-health-endpoint", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/CheckDomainHealthMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIFN5c3RlbS5MaW5xOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CgovLy8gPHN1bW1hcnk+Ci8vLyBDaGVjayBEb21haW4gSGVhbHRoIE1hcHBpbmcgLSBDaGVja3MgaGVhbHRoIGZvciBvbmUgZG9tYWluIGF0IGEgdGltZSAoc2VxdWVudGlhbCBwcm9jZXNzaW5nKQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgQ2hlY2tEb21haW5IZWFsdGhNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gR2V0IGN1cnJlbnQgZG9tYWluIGZyb20gcGVuZGluZ0RvbWFpbnMgYXJyYXkgdXNpbmcgY3VycmVudERvbWFpbkluZGV4CiAgICAgICAgICAgIHZhciBwZW5kaW5nRG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnBlbmRpbmdEb21haW5zIGFzIExpc3Q8b2JqZWN0PjsKICAgICAgICAgICAgdmFyIGN1cnJlbnREb21haW5JbmRleCA9IENvbnZlcnQuVG9JbnQzMihjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5jdXJyZW50RG9tYWluSW5kZXggPz8gMCk7CgogICAgICAgICAgICBpZiAocGVuZGluZ0RvbWFpbnMgPT0gbnVsbCB8fCBjdXJyZW50RG9tYWluSW5kZXggPj0gcGVuZGluZ0RvbWFpbnMuQ291bnQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInBhZ2UtY29tcGxldGUiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9ICJObyBtb3JlIGRvbWFpbnMgdG8gcHJvY2VzcyIgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEdldCBjdXJyZW50IGRvbWFpbgogICAgICAgICAgICB2YXIgY3VycmVudERvbWFpbiA9IHBlbmRpbmdEb21haW5zW2N1cnJlbnREb21haW5JbmRleF0gYXMgRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD47CiAgICAgICAgICAgIGlmIChjdXJyZW50RG9tYWluID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInBhZ2UtY29tcGxldGUiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9ICJJbnZhbGlkIGRvbWFpbiBkYXRhIiB9CiAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGhlYWx0aFVybCA9IGN1cnJlbnREb21haW4uQ29udGFpbnNLZXkoImhlYWx0aFVybCIpID8gY3VycmVudERvbWFpblsiaGVhbHRoVXJsIl0/LlRvU3RyaW5nKCkgOiBudWxsOwoKICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGhlYWx0aFVybCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImhlYWx0aC1jaGVjay1lcnJvciIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gIkhlYWx0aCBVUkwgaXMgbWlzc2luZyIgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFNldCB0aGUgaGVhbHRoIFVSTCBmb3IgdGhlIEhUVFAgcmVxdWVzdAogICAgICAgICAgICBodHRwVGFzay5TZXRVcmwoaGVhbHRoVXJsKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImhlYWx0aC1jaGVjay1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMDsKICAgICAgICAgICAgdmFyIHBlbmRpbmdEb21haW5zID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucGVuZGluZ0RvbWFpbnMgYXMgTGlzdDxvYmplY3Q+ID8/IG5ldyBMaXN0PG9iamVjdD4oKTsKICAgICAgICAgICAgdmFyIGN1cnJlbnREb21haW5JbmRleCA9IENvbnZlcnQuVG9JbnQzMihjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5jdXJyZW50RG9tYWluSW5kZXggPz8gMCk7CiAgICAgICAgICAgIHZhciBoZWFsdGh5RG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LkhlYWx0aHlEb21haW5zIGFzIExpc3Q8b2JqZWN0PiA/PyBuZXcgTGlzdDxvYmplY3Q+KCk7CiAgICAgICAgICAgIHZhciBub3RIZWFsdGh5RG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/Lk5vdEhlYWx0aHlEb21haW5zIGFzIExpc3Q8b2JqZWN0PiA/PyBuZXcgTGlzdDxvYmplY3Q+KCk7CgogICAgICAgICAgICAvLyBHZXQgY3VycmVudCBkb21haW4KICAgICAgICAgICAgaWYgKGN1cnJlbnREb21haW5JbmRleCA+PSBwZW5kaW5nRG9tYWlucy5Db3VudCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJwYWdlLWNvbXBsZXRlIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBIZWFsdGh5RG9tYWlucyA9IGhlYWx0aHlEb21haW5zLAogICAgICAgICAgICAgICAgICAgICAgICBOb3RIZWFsdGh5RG9tYWlucyA9IG5vdEhlYWx0aHlEb21haW5zLAogICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImRvbWFpbiIsICJoZWFsdGgtY2hlY2siLCAiY29tcGxldGUiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBjdXJyZW50RG9tYWluID0gcGVuZGluZ0RvbWFpbnNbY3VycmVudERvbWFpbkluZGV4XSBhcyBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0PjsKICAgICAgICAgICAgdmFyIGRvbWFpbk5hbWUgPSBjdXJyZW50RG9tYWluPy5Db250YWluc0tleSgiZG9tYWluTmFtZSIpID09IHRydWUgPyBjdXJyZW50RG9tYWluWyJkb21haW5OYW1lIl0/LlRvU3RyaW5nKCkgOiBudWxsOwoKICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIGhlYWx0aCBzdGF0dXMgYmFzZWQgb24gSFRUUCBzdGF0dXMgY29kZQogICAgICAgICAgICAvLyAyMDAgPSBoZWFsdGh5LCBvdGhlcndpc2UgdW5oZWFsdGh5CiAgICAgICAgICAgIGJvb2wgaXNIZWFsdGh5ID0gc3RhdHVzQ29kZSA9PSAyMDA7CgogICAgICAgICAgICAvLyBBZGQgdG8gYXBwcm9wcmlhdGUgbGlzdAogICAgICAgICAgICBpZiAoaXNIZWFsdGh5KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoIWhlYWx0aHlEb21haW5zLkNvbnRhaW5zKGRvbWFpbk5hbWUpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGhlYWx0aHlEb21haW5zLkFkZChkb21haW5OYW1lKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghbm90SGVhbHRoeURvbWFpbnMuQ29udGFpbnMoZG9tYWluTmFtZSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbm90SGVhbHRoeURvbWFpbnMuQWRkKGRvbWFpbk5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBJbmNyZW1lbnQgaW5kZXggZm9yIG5leHQgZG9tYWluCiAgICAgICAgICAgIHZhciBuZXh0SW5kZXggPSBjdXJyZW50RG9tYWluSW5kZXggKyAxOwogICAgICAgICAgICB2YXIgaGFzTW9yZURvbWFpbnMgPSBuZXh0SW5kZXggPCBwZW5kaW5nRG9tYWlucy5Db3VudDsKCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gaGFzTW9yZURvbWFpbnMgPyAiaGFzLW1vcmUtZG9tYWlucyIgOiAicGFnZS1jb21wbGV0ZSIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY3VycmVudERvbWFpbkluZGV4ID0gbmV4dEluZGV4LAogICAgICAgICAgICAgICAgICAgIEhlYWx0aHlEb21haW5zID0gaGVhbHRoeURvbWFpbnMsCiAgICAgICAgICAgICAgICAgICAgTm90SGVhbHRoeURvbWFpbnMgPSBub3RIZWFsdGh5RG9tYWlucywKICAgICAgICAgICAgICAgICAgICBpc0hlYWx0aHkgPSBpc0hlYWx0aHksCiAgICAgICAgICAgICAgICAgICAgZG9tYWluTmFtZSA9IGRvbWFpbk5hbWUsCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImRvbWFpbiIsICJoZWFsdGgtY2hlY2siLCBpc0hlYWx0aHkgPyAiaGVhbHRoeSIgOiAidW5oZWFsdGh5IiwgaGFzTW9yZURvbWFpbnMgPyAiY29udGludWUiIDogImNvbXBsZXRlIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJoZWFsdGgtY2hlY2stZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkV4Y2VwdGlvbiBkdXJpbmcgaGVhbHRoIGNoZWNrIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBjaGVja2VkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImhlYWx0aC1jaGVjayIsICJleGNlcHRpb24iLCAiZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "has-more-domains", - "target": "check-domain-health", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Has More Domains (Loop)" - }, - { - "language": "tr-TR", - "label": "Otomatik - Daha Fazla Domain Var (Döngü)" - } - ], - "schema": null, - "rule": { - "location": "./src/HasMoreDomainsRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBIYXMgTW9yZSBEb21haW5zIFJ1bGUgLSBDaGVja3MgaWYgdGhlcmUgYXJlIG1vcmUgZG9tYWlucyB0byBwcm9jZXNzIGluIGN1cnJlbnQgcGFnZQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgSGFzTW9yZURvbWFpbnNSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBwZW5kaW5nRG9tYWlucyA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5wZW5kaW5nRG9tYWlucyBhcyBMaXN0PG9iamVjdD47CiAgICAgICAgICAgIHZhciBjdXJyZW50RG9tYWluSW5kZXggPSBDb252ZXJ0LlRvSW50MzIoY29udGV4dC5JbnN0YW5jZS5EYXRhLmN1cnJlbnREb21haW5JbmRleCA/PyAwKTsKCiAgICAgICAgICAgIGlmIChwZW5kaW5nRG9tYWlucyA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUgYXJlIG1vcmUgZG9tYWlucyB0byBwcm9jZXNzCiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RG9tYWluSW5kZXggPCBwZW5kaW5nRG9tYWlucy5Db3VudDsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "page-complete", - "target": "aggregate-results", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Page Complete" - }, - { - "language": "tr-TR", - "label": "Otomatik - Sayfa Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/PageCompleteRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBQYWdlIENvbXBsZXRlIFJ1bGUgLSBDaGVja3MgaWYgY3VycmVudCBwYWdlIHByb2Nlc3NpbmcgaXMgY29tcGxldGUKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFBhZ2VDb21wbGV0ZVJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb250ZXh0Py5JbnN0YW5jZT8uRGF0YSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgdmFyIHBlbmRpbmdEb21haW5zID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLnBlbmRpbmdEb21haW5zIGFzIExpc3Q8b2JqZWN0PjsKICAgICAgICAgICAgdmFyIGN1cnJlbnREb21haW5JbmRleCA9IENvbnZlcnQuVG9JbnQzMihjb250ZXh0Lkluc3RhbmNlLkRhdGEuY3VycmVudERvbWFpbkluZGV4ID8/IDApOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKHBlbmRpbmdEb21haW5zID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RG9tYWluSW5kZXggPj0gcGVuZGluZ0RvbWFpbnMuQ291bnQ7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "aggregate-results", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Aggregate Results" - }, - { - "language": "tr-TR", - "label": "Sonuçları Topla" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "to-check-pagination", - "target": "check-pagination", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - To Check Pagination" - }, - { - "language": "tr-TR", - "label": "Otomatik - Sayfalama Kontrolüne" - } - ], - "schema": null, - "rule": { - "location": "./src/ToCheckPaginationRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFRvIENoZWNrIFBhZ2luYXRpb24gUnVsZSAtIEFsd2F5cyBhbGxvd3MgdHJhbnNpdGlvbiB0byBwYWdpbmF0aW9uIGNoZWNrCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBUb0NoZWNrUGFnaW5hdGlvblJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KfQoK" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "check-pagination", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Check Pagination" - }, - { - "language": "tr-TR", - "label": "Sayfalamayı Kontrol Et" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "has-next", - "target": "fetch-next-page", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Has Next Page" - }, - { - "language": "tr-TR", - "label": "Otomatik - Sonraki Sayfa Var" - } - ], - "schema": null, - "rule": { - "location": "./src/CheckPaginationRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIENoZWNrIFBhZ2luYXRpb24gUnVsZSAtIENoZWNrcyBpZiBuZXh0IGxpbmsgZXhpc3RzIGluIHJlc3BvbnNlCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBDaGVja1BhZ2luYXRpb25SdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBuZXh0UGFnZVVybCA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5uZXh0UGFnZVVybD8uVG9TdHJpbmcoKTsKCiAgICAgICAgICAgIC8vIFJldHVybiB0cnVlIGlmIG5leHQgbGluayBpcyBub3QgbnVsbC9lbXB0eQogICAgICAgICAgICByZXR1cm4gIXN0cmluZy5Jc051bGxPckVtcHR5KG5leHRQYWdlVXJsKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "no-next", - "target": "schedule-next-run", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - No Next Page" - }, - { - "language": "tr-TR", - "label": "Otomatik - Sonraki Sayfa Yok" - } - ], - "schema": null, - "rule": { - "location": "./src/NoNextRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIE5vIE5leHQgUnVsZSAtIENoZWNrcyBpZiB0aGVyZSBpcyBubyBuZXh0IHBhZ2UgKG9wcG9zaXRlIG9mIENoZWNrUGFnaW5hdGlvblJ1bGUpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBOb05leHRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgdmFyIG5leHRQYWdlVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLm5leHRQYWdlVXJsPy5Ub1N0cmluZygpOwogICAgICAgICAgICByZXR1cm4gc3RyaW5nLklzTnVsbE9yRW1wdHkobmV4dFBhZ2VVcmwpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "fetch-next-page", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Fetch Next Page" - }, - { - "language": "tr-TR", - "label": "Sonraki Sayfayı Getir" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "fetch-domains-list", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/FetchNextPageMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gRmV0Y2ggTmV4dCBQYWdlIE1hcHBpbmcgLSBGZXRjaGVzIG5leHQgcGFnZSB1c2luZyBuZXh0IFVSTCBmcm9tIHJlc3BvbnNlCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBGZXRjaE5leHRQYWdlTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGFuIEh0dHBUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEdldCBuZXh0IHBhZ2UgVVJMIGZyb20gY29udGV4dAogICAgICAgICAgICB2YXIgbmV4dFBhZ2VVcmwgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5uZXh0UGFnZVVybD8uVG9TdHJpbmcoKTsKCiAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShuZXh0UGFnZVVybCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gIm5vLW5leHQtcGFnZSIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gIk5leHQgcGFnZSBVUkwgaXMgbWlzc2luZyIgfQogICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFNldCB0aGUgbmV4dCBwYWdlIFVSTCBmb3IgdGhlIEhUVFAgcmVxdWVzdAogICAgICAgICAgICBodHRwVGFzay5TZXRVcmwobmV4dFBhZ2VVcmwpOwoKICAgICAgICAgICAgLy8gVXBkYXRlIGN1cnJlbnRQYWdlVXJsCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImZldGNoLW5leHQtcGFnZS1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMDsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgICAgIC8vIFN1Y2Nlc3NmdWwgcmVzcG9uc2UgKDIwMCBPSykKICAgICAgICAgICAgaWYgKHN0YXR1c0NvZGUgPj0gMjAwICYmIHN0YXR1c0NvZGUgPCAzMDAgJiYgcmVzcG9uc2VEYXRhICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgaXRlbXMgYW5kIGxpbmtzIGZyb20gcmVzcG9uc2UKICAgICAgICAgICAgICAgIHZhciBpdGVtcyA9IHJlc3BvbnNlRGF0YS5pdGVtczsKICAgICAgICAgICAgICAgIHZhciBsaW5rcyA9IHJlc3BvbnNlRGF0YS5saW5rczsKICAgICAgICAgICAgICAgIHZhciBuZXh0VXJsID0gbGlua3M/Lm5leHQ/LlRvU3RyaW5nKCk7CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJuZXh0LXBhZ2UtZmV0Y2hlZCIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMgPSBpdGVtcywKICAgICAgICAgICAgICAgICAgICAgICAgbGlua3MgPSBsaW5rcywKICAgICAgICAgICAgICAgICAgICAgICAgbmV4dFBhZ2VVcmwgPSBuZXh0VXJsLAogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50UGFnZVVybCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/Lm5leHRQYWdlVXJsLAogICAgICAgICAgICAgICAgICAgICAgICBmZXRjaGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJkb21haW4iLCAiZmV0Y2giLCAicGFnaW5hdGlvbiIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIEVycm9yIHJlc3BvbnNlCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJmZXRjaC1uZXh0LXBhZ2UtZmFpbGVkIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJGYWlsZWQgdG8gZmV0Y2ggbmV4dCBwYWdlIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlRGF0YSA9IHJlc3BvbnNlRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgZmV0Y2hlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImZldGNoIiwgInBhZ2luYXRpb24iLCAiZXJyb3IiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImZldGNoLW5leHQtcGFnZS1mYWlsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkV4Y2VwdGlvbiBkdXJpbmcgbmV4dCBwYWdlIGZldGNoIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBmZXRjaGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImZldGNoIiwgInBhZ2luYXRpb24iLCAiZXhjZXB0aW9uIiwgImVycm9yIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "next-page-fetched", - "target": "process-page", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Next Page Fetched" - }, - { - "language": "tr-TR", - "label": "Otomatik - Sonraki Sayfa Getirildi" - } - ], - "schema": null, - "rule": { - "location": "./src/NextPageFetchedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIE5leHQgUGFnZSBGZXRjaGVkIFJ1bGUgLSBDaGVja3MgaWYgbmV4dCBwYWdlIHdhcyBzdWNjZXNzZnVsbHkgZmV0Y2hlZAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgTmV4dFBhZ2VGZXRjaGVkUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gQWx3YXlzIHJldHVybiB0cnVlIC0gbWFwcGluZyBoYW5kbGVzIHRoZSBsb2dpYyB2aWEgS2V5CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KfQoK" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "schedule-next-run", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Schedule Next Run" - }, - { - "language": "tr-TR", - "label": "Sonraki Çalıştırmayı Planla" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "schedule-health-check", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ScheduleNextRunMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gU2NoZWR1bGUgTmV4dCBSdW4gTWFwcGluZyAtIFRyaWdnZXJzIGRvbWFpbi1oZWFsdGgtY2hlY2sgd29ya2Zsb3cgYXMgc3VicHJvY2VzcyBmb3IgbmV4dCBleGVjdXRpb24KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFNjaGVkdWxlTmV4dFJ1bk1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgc3ViUHJvY2Vzc1Rhc2sgPSB0YXNrIGFzIFN1YlByb2Nlc3NUYXNrOwogICAgICAgICAgICBpZiAoc3ViUHJvY2Vzc1Rhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIFN1YlByb2Nlc3NUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBzdWJwcm9jZXNzIHRvIHRyaWdnZXIgdGhlIHNhbWUgd29ya2Zsb3cKICAgICAgICAgICAgc3ViUHJvY2Vzc1Rhc2suU2V0S2V5KCJkb21haW4taGVhbHRoLWNoZWNrIik7CiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldFZlcnNpb24oIjEuMC4wIik7CgogICAgICAgICAgICAvLyBQcmVwYXJlIHN1YnByb2Nlc3MgaW5pdGlhbGl6YXRpb24gZGF0YSAoZW1wdHkgZm9yIHNjaGVkdWxlZCBydW4pCiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldEJvZHkobmV3IHsgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzY2hlZHVsZS1uZXh0LXJ1bi1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFN1YlByb2Nlc3MgaXMgZmlyZS1hbmQtZm9yZ2V0LCBzbyB3ZSBqdXN0IHJldHVybiBzdWNjZXNzCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInNjaGVkdWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgbmV4dFJ1bkluID0gIjEgaG91ciIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgInNjaGVkdWxlIiwgImhlYWx0aC1jaGVjayIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzY2hlZHVsZS1uZXh0LXJ1bi1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRXhjZXB0aW9uIGR1cmluZyBzY2hlZHVsaW5nIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBzY2hlZHVsZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJkb21haW4iLCAic2NoZWR1bGUiLCAiZXhjZXB0aW9uIiwgImVycm9yIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "scheduled", - "target": "completed", - "triggerType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Scheduled - Next Run" - }, - { - "language": "tr-TR", - "label": "Planlandı - Sonraki Çalıştırma" - } - ], - "schema": null, - "timer": { - "location": "./src/ScheduleNextRunTimerMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zLlRpbWVyOwoKLy8vIDxzdW1tYXJ5PgovLy8gU2NoZWR1bGUgTmV4dCBSdW4gVGltZXIgTWFwcGluZyAtIFJldHVybnMgdGltZXIgc2NoZWR1bGUgZm9yIDEgaG91ciBkZWxheQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgU2NoZWR1bGVOZXh0UnVuVGltZXJNYXBwaW5nIDogSVRpbWVyTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxUaW1lclNjaGVkdWxlPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFJldHVybiB0aW1lciBzY2hlZHVsZSBmb3IgMSBob3VyIGZyb20gbm93CiAgICAgICAgICAgIHJldHVybiBUaW1lclNjaGVkdWxlLkZyb21EYXRlVGltZShEYXRlVGltZS5VdGNOb3cuQWRkTWludXRlcygzKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICAvLyBGYWxsYmFjayB0byAxIGhvdXIgb24gZXJyb3IKICAgICAgICAgICAgcmV0dXJuIFRpbWVyU2NoZWR1bGUuRnJvbURhdGVUaW1lKERhdGVUaW1lLlV0Y05vdy5BZGRNaW51dGVzKDMpKTsKICAgICAgICB9CiAgICB9Cn0KCg==" - }, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "completed", - "stateType": 3, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Completed" - }, - { - "language": "tr-TR", - "label": "Tamamlandı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/discovery/domain-registration-workflow.json b/core/Workflows/discovery/domain-registration-workflow.json deleted file mode 100644 index be7b35c..0000000 --- a/core/Workflows/discovery/domain-registration-workflow.json +++ /dev/null @@ -1,557 +0,0 @@ -{ - "key": "domain-registration", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "domain", - "registration", - "redis", - "health-check", - "dapr" - ], - "attributes": { - "type": "F", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Domain Registration Workflow" - }, - { - "language": "tr-TR", - "label": "Domain Kayıt İş Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-domain-registration", - "target": "initial", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Domain Registration" - }, - { - "language": "tr-TR", - "label": "Domain Kaydını Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "initial", - "stateType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Initial - Check Domain Exists" - }, - { - "language": "tr-TR", - "label": "Başlangıç - Domain Kontrolü" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "check-domain-exists", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/CheckDomainExistsMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nLkZ1bmN0aW9uczsKLy8vIDxzdW1tYXJ5PgovLy8gQ2hlY2sgRG9tYWluIEV4aXN0cyBNYXBwaW5nIC0gUXVlcmllcyBkb21haW4gd29ya2Zsb3cgaW5zdGFuY2UgZm9yIGV4aXN0ZW5jZSB1c2luZyBEYXByU2VydmljZVRhc2sKLy8vIEVuZHBvaW50OiAvYXBpL3YxL2Rpc2NvdmVyeS93b3JrZmxvd3MvZG9tYWluL2luc3RhbmNlcy97ZG9tYWluTmFtZX0vZnVuY3Rpb25zL2RhdGEKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIENoZWNrRG9tYWluRXhpc3RzTWFwcGluZyA6U2NyaXB0QmFzZSwgSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgc3RyaW5nPyBhcHBJZCA9IEdldENvbmZpZ1ZhbHVlKCJPcmNoZXN0cmF0aW9uQXBpOkFwcElkIik7CiAgICAgICAgICAgIHN0cmluZz8gZGFwckFwcElkID0gR2V0Q29uZmlnVmFsdWUoIkRBUFJfQVBQX0lEIik7CiAgICAgICAgICAgCiAgICAgICAgICAgIHZhciAgZGFwclNlcnZpY2VUYXNrPSB0YXNrIGFzIERhcHJTZXJ2aWNlVGFzazsKICAgICAgICAgICAgaWYgKGRhcHJTZXJ2aWNlVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgRGFwclNlcnZpY2VUYXNrIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkFwcElkIGFyaXlvcnVtIGRhcHI6IitkYXByQXBwSWQpOwogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiQXBwSWQgYXJpeW9ydW0gZXhlYyBzZXQ6IithcHBJZCk7CiAgICAgICAgICAgIGRhcHJTZXJ2aWNlVGFzay5TZXRBcHBJZChkYXByQXBwSWQpOwogICAgICAgICAgICB2YXIgZG9tYWluTmFtZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmRvbWFpbk5hbWU7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBSZXBsYWNlIHtkb21haW5OYW1lfSBwbGFjZWhvbGRlciBpbiBtZXRob2ROYW1lCiAgICAgICAgICAgIC8vIE1ldGhvZE5hbWUgZm9ybWF0OiAvYXBpL3YxL2Rpc2NvdmVyeS93b3JrZmxvd3MvZG9tYWluL2luc3RhbmNlcy97ZG9tYWluTmFtZX0vZnVuY3Rpb25zL2RhdGEKICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShkb21haW5OYW1lPy5Ub1N0cmluZygpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIG1ldGhvZE5hbWUgPSBkYXByU2VydmljZVRhc2suTWV0aG9kTmFtZT8uUmVwbGFjZSgie2RvbWFpbk5hbWV9IiwgZG9tYWluTmFtZS5Ub1N0cmluZygpKSA/PyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkIi9hcGkvdjEvZGlzY292ZXJ5L3dvcmtmbG93cy9kb21haW4vaW5zdGFuY2VzL3tkb21haW5OYW1lfS9mdW5jdGlvbnMvZGF0YSI7CiAgICAgICAgICAgICAgICBkYXByU2VydmljZVRhc2suU2V0TWV0aG9kTmFtZShtZXRob2ROYW1lKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiY2hlY2stZG9tYWluLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gV29ya2Zsb3cgSW5zdGFuY2UgRGF0YSBBUEkgcmV0dXJuczoKICAgICAgICAgICAgLy8gLSAyMDAgT0sgd2l0aCBkYXRhIChpbmNsdWRpbmcgZXRhZykgaWYgaW5zdGFuY2UgZXhpc3RzCiAgICAgICAgICAgIC8vIC0gNDA0IE5vdCBGb3VuZCBpZiBpbnN0YW5jZSBkb2Vzbid0IGV4aXN0CiAgICAgICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMDsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9IGNvbnRleHQuQm9keTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIERvbWFpbiB3b3JrZmxvdyBpbnN0YW5jZSBleGlzdHMgKDIwMCBPSyB3aXRoIGRhdGEpCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID09IDIwMCAmJiByZXNwb25zZURhdGEgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBldGFnIGZyb20gcmVzcG9uc2UgYm9keSAocm9vdCBsZXZlbCwgbG93ZXJjYXNlKQogICAgICAgICAgICAgICAgLy8gUmVzcG9uc2UgZm9ybWF0OiB7ICJkYXRhIjogeyAiYXBwSWQiOiAiLi4uIiwgImhlYWx0aFVybCI6ICIuLi4iLCAiZG9tYWluTmFtZSI6ICIuLi4iLCAiYmFzZVVybCI6ICIuLi4iIH0sICJldGFnIjogIi4uLiIsICJleHRlbnNpb25zIjoge30gfQogICAgICAgICAgICAgICAgdmFyIGVUYWcgPSByZXNwb25zZURhdGEuZGF0YT8uZXRhZz8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gRXh0cmFjdCBoZWFsdGhVcmwgYW5kIGFwcElkIGZyb20gZXhpc3RpbmcgZG9tYWluIGRhdGEKICAgICAgICAgICAgICAgIC8vIERvbWFpbiBkYXRhIHN0cnVjdHVyZTogZGlyZWN0IHByb3BlcnRpZXMgaW4gZGF0YSBvYmplY3QgKG5vIHVuZGVyc2NvcmUgcHJlZml4KQogICAgICAgICAgICAgICAgdmFyIGV4aXN0aW5nSGVhbHRoVXJsID0gcmVzcG9uc2VEYXRhLmRhdGE/LmRhdGE/LmhlYWx0aFVybD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIHZhciBleGlzdGluZ0Jhc2VVcmwgPSByZXNwb25zZURhdGEuZGF0YT8uZGF0YT8uYmFzZVVybD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgICAgIHZhciBleGlzdGluZ0FwcElkID0gcmVzcG9uc2VEYXRhLmRhdGE/LmRhdGE/LmFwcElkPy5Ub1N0cmluZygpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1leGlzdHMiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbkV4aXN0cyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nRG9tYWluID0gcmVzcG9uc2VEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUVUYWcgPSBlVGFnLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0hlYWx0aFVybCA9IGV4aXN0aW5nSGVhbHRoVXJsLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0Jhc2VVcmw9ZXhpc3RpbmdCYXNlVXJsLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0FwcElkID0gZXhpc3RpbmdBcHBJZCwKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImV4aXN0cyIsICJ3b3JrZmxvdyIsICJpbnN0YW5jZSIsICJmb3VuZCIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBEb21haW4gd29ya2Zsb3cgaW5zdGFuY2Ugbm90IGZvdW5kICg0MDQgTm90IEZvdW5kKQogICAgICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID09IDQwNCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJkb21haW4tbm90LWV4aXN0cyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluRXhpc3RzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nRG9tYWluID0gKG9iamVjdD8pbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VFVGFnID0gKHN0cmluZz8pbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdIZWFsdGhVcmwgPSAoc3RyaW5nPyludWxsLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0FwcElkID0gKHN0cmluZz8pbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgIm5vdC1leGlzdHMiLCAid29ya2Zsb3ciLCAiaW5zdGFuY2UiLCAibm90LWZvdW5kIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgc3RhdHVzIGNvZGUKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1jaGVjay1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbkV4aXN0cyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZ0RvbWFpbiA9IChvYmplY3Q/KW51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlRVRhZyA9IChzdHJpbmc/KW51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nSGVhbHRoVXJsID0gKHN0cmluZz8pbnVsbCwKICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdBcHBJZCA9IChzdHJpbmc/KW51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gIlVuZXhwZWN0ZWQgc3RhdHVzIGNvZGUgZHVyaW5nIGRvbWFpbiBpbnN0YW5jZSBjaGVjayIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgICAgICBjaGVjaz1yZXNwb25zZURhdGEuZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImV4Y2VwdGlvbiIsICJlcnJvciIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZG9tYWluLWNoZWNrLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZG9tYWluRXhpc3RzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdEb21haW4gPSAob2JqZWN0PyludWxsLAogICAgICAgICAgICAgICAgICAgIGluc3RhbmNlRVRhZyA9IChzdHJpbmc/KW51bGwsCiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmdIZWFsdGhVcmwgPSAoc3RyaW5nPyludWxsLAogICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nQXBwSWQgPSAoc3RyaW5nPyludWxsLAogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkV4Y2VwdGlvbiBkdXJpbmcgZG9tYWluIGluc3RhbmNlIGNoZWNrIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBjaGVja2VkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImV4Y2VwdGlvbiIsICJlcnJvciIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "domain-exists", - "target": "check-domain-need-update", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Domain Exists" - }, - { - "language": "tr-TR", - "label": "Otomatik - Domain Mevcut" - } - ], - "schema": null, - "rule": { - "location": "./src/DomainExistsRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIERvbWFpbiBFeGlzdHMgUnVsZSAtIENoZWNrcyBpZiBkb21haW4gYWxyZWFkeSBleGlzdHMgaW4gd29ya2Zsb3cgaW5zdGFuY2UKLy8vIEFsc28gY2hlY2tzIEVUYWcgdG8gZGV0ZXJtaW5lIGlmIHVwZGF0ZSBpcyBuZWVkZWQKLy8vIFJldHVybnMgZmFsc2UgKHNraXAgdXBkYXRlKSBpZiBFVGFncyBtYXRjaCwgdHJ1ZSAocHJvY2VlZCB0byB1cGRhdGUpIGlmIEVUYWdzIGRpZmZlcgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRG9tYWluRXhpc3RzUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewoKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb250ZXh0Py5JbnN0YW5jZT8uRGF0YSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAgLy8gSWYgbm8gZGF0YSwgYXNzdW1lIGRvbWFpbiBkb2Vzbid0IGV4aXN0CgogICAgICAgICAgICB2YXIgZG9tYWluRXhpc3RzID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmRvbWFpbkV4aXN0czsKCiAgICAgICAgICAgIGlmIChkb21haW5FeGlzdHMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgIC8vIElmIG5vIGNoZWNrIHJlc3VsdCwgYXNzdW1lIGRvbWFpbiBkb2Vzbid0IGV4aXN0CgogICAgICAgICAgICByZXR1cm4gZG9tYWluRXhpc3RzID09IHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7ICAvLyBPbiBlcnJvciwgYXNzdW1lIGRvbWFpbiBkb2Vzbid0IGV4aXN0CiAgICAgICAgfQogICAgICAgIC8vICAgICB0cnkKICAgICAgICAvLyAgICAgewogICAgICAgIC8vICAgICAgICAgaWYgKGNvbnRleHQ/Lkluc3RhbmNlPy5EYXRhID09IG51bGwpCiAgICAgICAgLy8gICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAvLyAgICAgICAgIHZhciBkb21haW5FeGlzdHMgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZG9tYWluRXhpc3RzOwoKICAgICAgICAvLyAgICAgICAgIGlmIChkb21haW5FeGlzdHMgPT0gbnVsbCB8fCBkb21haW5FeGlzdHMgIT0gdHJ1ZSkKICAgICAgICAvLyAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgIC8vICAgICAgICAgLy8gR2V0IEVUYWcgdmFsdWVzCiAgICAgICAgLy8gICAgICAgICAvLyBpbnN0YW5jZUVUYWc6IGZyb20gR2V0SW5zdGFuY2VEYXRhVGFzayByZXNwb25zZSAoY3VycmVudCBpbnN0YW5jZSBFVGFnKQogICAgICAgIC8vICAgICAgICAgLy8gZVRhZzogZnJvbSB0cmFuc2l0aW9uIGNhbGwgKHNlbnQgRVRhZykKICAgICAgICAvLyAgICAgICAgIHZhciBpbnN0YW5jZUVUYWcgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuaW5zdGFuY2VFVGFnPy5Ub1N0cmluZygpOwogICAgICAgIC8vICAgICAgICAgdmFyIHNlbnRFVGFnID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmVUYWc/LlRvU3RyaW5nKCk7CgogICAgICAgIC8vICAgICAgICAgLy8gSWYgbm8gRVRhZ3MgcHJvdmlkZWQsIHByb2NlZWQgdG8gdXBkYXRlIChjb25zZXJ2YXRpdmUgYXBwcm9hY2gpCiAgICAgICAgLy8gICAgICAgICBpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkoaW5zdGFuY2VFVGFnKSB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShzZW50RVRhZykpCiAgICAgICAgLy8gICAgICAgICAgICAgcmV0dXJuIHRydWU7CgogICAgICAgIC8vICAgICAgICAgLy8gSWYgRVRhZ3MgbWF0Y2gsIHNraXAgdXBkYXRlIChyZXR1cm4gZmFsc2UgLSBkb24ndCBnbyB0byB1cGRhdGUgc3RhdGUpCiAgICAgICAgLy8gICAgICAgICBpZiAoaW5zdGFuY2VFVGFnID09IHNlbnRFVGFnKQogICAgICAgIC8vICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgLy8gICAgICAgICAvLyBJZiBFVGFncyBkaWZmZXIsIHByb2NlZWQgdG8gdXBkYXRlIChyZXR1cm4gdHJ1ZSAtIGdvIHRvIHVwZGF0ZSBzdGF0ZSkKICAgICAgICAvLyAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIC8vICAgICB9CiAgICAgICAgLy8gICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgLy8gICAgIHsKICAgICAgICAvLyAgICAgICAgIC8vIE9uIGVycm9yLCBwcm9jZWVkIHRvIHVwZGF0ZSAoY29uc2VydmF0aXZlIGFwcHJvYWNoKQogICAgICAgIC8vICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgLy8gICAgIH0KICAgIH0KfQoKCgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "domain-not-exists", - "target": "register", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Domain Not Exists" - }, - { - "language": "tr-TR", - "label": "Otomatik - Domain Mevcut Değil" - } - ], - "schema": null, - "rule": { - "location": "./src/DomainNotExistsRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIERvbWFpbiBOb3QgRXhpc3RzIFJ1bGUgLSBDaGVja3MgaWYgZG9tYWluIGRvZXMgbm90IGV4aXN0IGluIHdvcmtmbG93IGluc3RhbmNlCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBEb21haW5Ob3RFeGlzdHNSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAgLy8gSWYgbm8gZGF0YSwgYXNzdW1lIGRvbWFpbiBkb2Vzbid0IGV4aXN0CgogICAgICAgICAgICB2YXIgZG9tYWluRXhpc3RzID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmRvbWFpbkV4aXN0czsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChkb21haW5FeGlzdHMgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAgLy8gSWYgbm8gY2hlY2sgcmVzdWx0LCBhc3N1bWUgZG9tYWluIGRvZXNuJ3QgZXhpc3QKCiAgICAgICAgICAgIHJldHVybiBkb21haW5FeGlzdHMgPT0gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIE9uIGVycm9yLCBhc3N1bWUgZG9tYWluIGRvZXNuJ3QgZXhpc3QKICAgICAgICB9CiAgICB9Cn0KCgoK" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "register", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Register Domain" - }, - { - "language": "tr-TR", - "label": "Domain Kaydet" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "register-domain-lifecycle", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/RegisterDomainLifecycleMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gUmVnaXN0ZXIgRG9tYWluIExpZmVjeWNsZSBNYXBwaW5nIC0gU3RhcnRzIGRvbWFpbiB3b3JrZmxvdyBpbnN0YW5jZSB3aXRoIGRvbWFpbiBuYW1lIGFzIGtleSB1c2luZyBTdGFydFRhc2sKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFJlZ2lzdGVyRG9tYWluTGlmZWN5Y2xlTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBzdGFydFRhc2sgPSB0YXNrIGFzIFN0YXJ0VGFzazsKICAgICAgICAgICAgaWYgKHN0YXJ0VGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgU3RhcnRUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHZhciBkb21haW5OYW1lID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9tYWluTmFtZTsKICAgICAgICAgICAgdmFyIGJhc2VVcmwgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5iYXNlVXJsOwogICAgICAgICAgICB2YXIgaGVhbHRoVXJsID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uaGVhbHRoVXJsOwogICAgICAgICAgICB2YXIgYXBwSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5hcHBJZDsKCiAgICAgICAgICAgIC8vIFNldCBpbnN0YW5jZSBrZXkgdG8gZG9tYWluTmFtZQogICAgICAgICAgICAvLyBUaGlzIGVuc3VyZXMgZWFjaCBkb21haW4gaGFzIGl0cyBvd24gd29ya2Zsb3cgaW5zdGFuY2UKICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShkb21haW5OYW1lPy5Ub1N0cmluZygpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc3RhcnRUYXNrLlNldEtleShkb21haW5OYW1lLlRvU3RyaW5nKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBQcmVwYXJlIGluaXRpYWxpemF0aW9uIGRhdGEKICAgICAgICAgICAgLy8gUGFzcyBkb21haW4gaW5mb3JtYXRpb24gdG8gZG9tYWluIHdvcmtmbG93IChzY2hlbWEgY29tcGxpYW50KQogICAgICAgICAgICBzdGFydFRhc2suU2V0Qm9keShuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZG9tYWluTmFtZSA9IGRvbWFpbk5hbWUsCiAgICAgICAgICAgICAgICBiYXNlVXJsID0gYmFzZVVybCwKICAgICAgICAgICAgICAgIGhlYWx0aFVybCA9IGhlYWx0aFVybCwKICAgICAgICAgICAgICAgIGFwcElkID0gYXBwSWQKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJyZWdpc3Rlci1kb21haW4tbGlmZWN5Y2xlLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gU3RhcnRUYXNrIHJldHVybnMgaW5zdGFuY2VJZCBvbiBzdWNjZXNzCiAgICAgICAgICAgIGlmIChjb250ZXh0LkJvZHk/LmlzU3VjY2VzcyA9PSB0cnVlKQogICAgICAgICAgICB7CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJkb21haW4tbGlmZWN5Y2xlLXN0YXJ0ZWQiLAogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5SZWdpc3RyYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gPSAicmVnaXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgIGRvbWFpbkxpZmVjeWNsZVN0YXJ0ZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9ICJET01BSU5fTElGRUNZQ0xFX1dPUktGTE9XX1NUQVJURUQiCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImxpZmVjeWNsZSIsICJzdGFydGVkIiwgInN0YXJ0IiwgInN1Y2Nlc3MiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1saWZlY3ljbGUtc3RhcnQtZmFpbGVkIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5SZWdpc3RyYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uID0gInJlZ2lzdGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkZhaWxlZCB0byByZWdpc3RlciBkb21haW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IGNvbnRleHQuQm9keT8uc3RhdHVzQ29kZSA/PyA1MDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpc3RlcmVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluTGlmZWN5Y2xlU3RhcnRlZCA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGNvbnRleHQuQm9keT8uZXJyb3JNZXNzYWdlID8/ICJGYWlsZWQgdG8gc3RhcnQgZG9tYWluIGxpZmVjeWNsZSB3b3JrZmxvdyIsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImRvbWFpbiIsICJsaWZlY3ljbGUiLCAic3RhcnQiLCAiZXJyb3IiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1saWZlY3ljbGUtc3RhcnQtZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkb21haW5MaWZlY3ljbGVTdGFydGVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRXhjZXB0aW9uIGR1cmluZyBkb21haW4gbGlmZWN5Y2xlIHN0YXJ0IiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgIGRvbWFpblJlZ2lzdHJhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gPSAicmVnaXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJFeGNlcHRpb24gZHVyaW5nIGRvbWFpbiByZWdpc3RyYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJkb21haW4iLCAibGlmZWN5Y2xlIiwgImV4Y2VwdGlvbiIsICJlcnJvciIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "register-success", - "target": "upsert-redis", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Registration Success" - }, - { - "language": "tr-TR", - "label": "Otomatik - Kayıt Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/RegisterSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFJlZ2lzdGVyIFN1Y2Nlc3MgUnVsZSAtIENoZWNrcyBpZiBkb21haW4gcmVnaXN0cmF0aW9uIHdhcyBzdWNjZXNzZnVsCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBSZWdpc3RlclN1Y2Nlc3NSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBkb21haW5SZWdpc3RyYXRpb24gPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZG9tYWluUmVnaXN0cmF0aW9uOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGRvbWFpblJlZ2lzdHJhdGlvbiA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgcmVnaXN0cmF0aW9uIHdhcyBzdWNjZXNzZnVsIGFuZCBvcGVyYXRpb24gaXMgInJlZ2lzdGVyIgogICAgICAgICAgICByZXR1cm4gZG9tYWluUmVnaXN0cmF0aW9uLnN1Y2Nlc3MgPT0gdHJ1ZSAmJiAKICAgICAgICAgICAgICAgICAgIGRvbWFpblJlZ2lzdHJhdGlvbi5vcGVyYXRpb24/LlRvU3RyaW5nKCkgPT0gInJlZ2lzdGVyIjsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0KCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "update", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Update Domain" - }, - { - "language": "tr-TR", - "label": "Domain Güncelle" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "update-domain-lifecycle", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/UpdateDomainLifecycleMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVXBkYXRlIERvbWFpbiBMaWZlY3ljbGUgTWFwcGluZyAtIFRyaWdnZXJzIHVwZGF0ZSB0cmFuc2l0aW9uIGluIGV4aXN0aW5nIGRvbWFpbiB3b3JrZmxvdyBpbnN0YW5jZSB1c2luZyBEaXJlY3RUcmlnZ2VyVGFzawovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgVXBkYXRlRG9tYWluTGlmZWN5Y2xlTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBkaXJlY3RUcmlnZ2VyVGFzayA9IHRhc2sgYXMgRGlyZWN0VHJpZ2dlclRhc2s7CiAgICAgICAgICAgIGlmIChkaXJlY3RUcmlnZ2VyVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgRGlyZWN0VHJpZ2dlclRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdmFyIGRvbWFpbk5hbWUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kb21haW5OYW1lOwogICAgICAgICAgICB2YXIgYmFzZVVybCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmJhc2VVcmw7CiAgICAgICAgICAgIHZhciBoZWFsdGhVcmwgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5oZWFsdGhVcmw7CiAgICAgICAgICAgIHZhciBhcHBJZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmFwcElkOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gR2V0IEVUYWcgZnJvbSBpbnN0YW5jZSBkYXRhIChmcm9tIGNoZWNrLWRvbWFpbi1leGlzdHMgcmVzcG9uc2UpCiAgICAgICAgICAgIHZhciBlVGFnID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uaW5zdGFuY2VFVGFnPy5Ub1N0cmluZygpID8/IAogICAgICAgICAgICAgICAgICAgICAgY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZVRhZz8uVG9TdHJpbmcoKTsKCiAgICAgICAgICAgIC8vIFNldCBpbnN0YW5jZSBrZXkgdG8gZG9tYWluTmFtZQogICAgICAgICAgICAvLyBUaGlzIHdpbGwgZmluZCB0aGUgZXhpc3RpbmcgZG9tYWluIHdvcmtmbG93IGluc3RhbmNlCiAgICAgICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkoZG9tYWluTmFtZT8uVG9TdHJpbmcoKSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldEtleShkb21haW5OYW1lLlRvU3RyaW5nKCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBTZXQgdHJhbnNpdGlvbiBuYW1lIChhbHJlYWR5IGluIGNvbmZpZywgYnV0IGNhbiBiZSBzZXQgZXhwbGljaXRseSkKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0VHJhbnNpdGlvbk5hbWUoInVwZGF0ZSIpOwoKICAgICAgICAgICAgLy8gUHJlcGFyZSB1cGRhdGUgZGF0YQogICAgICAgICAgICAvLyBQYXNzIHVwZGF0ZWQgZG9tYWluIGluZm9ybWF0aW9uIHRvIGRvbWFpbiB3b3JrZmxvdyAoc2NoZW1hIGNvbXBsaWFudCkKICAgICAgICAgICAgLy8gSW5jbHVkZSBFVGFnIGZvciBvcHRpbWlzdGljIGNvbmN1cnJlbmN5IGNvbnRyb2wKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0Qm9keShuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZG9tYWluTmFtZSA9IGRvbWFpbk5hbWUsCiAgICAgICAgICAgICAgICBiYXNlVXJsID0gYmFzZVVybCwKICAgICAgICAgICAgICAgIGhlYWx0aFVybCA9IGhlYWx0aFVybCwKICAgICAgICAgICAgICAgIGFwcElkID0gYXBwSWQKICAgICAgICAgICAgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJ1cGRhdGUtZG9tYWluLWxpZmVjeWNsZS1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIERpcmVjdFRyaWdnZXJUYXNrIHJldHVybnMgc3VjY2VzcyBzdGF0dXMKICAgICAgICAgICAgaWYgKGNvbnRleHQuQm9keT8uaXNTdWNjZXNzID09IHRydWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAiZG9tYWluLWxpZmVjeWNsZS11cGRhdGUtdHJpZ2dlcmVkIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBkb21haW5MaWZlY3ljbGVVcGRhdGVUcmlnZ2VyZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gIkRPTUFJTl9MSUZFQ1lDTEVfVVBEQVRFX1RSSUdHRVJFRCIsCiAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5SZWdpc3RyYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcGVyYXRpb24gPSAidXBkYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImxpZmVjeWNsZSIsICJ1cGRhdGUiLCAidHJpZ2dlcmVkIiwgImRpcmVjdC10cmlnZ2VyIiwgInN1Y2Nlc3MiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1saWZlY3ljbGUtdXBkYXRlLWZhaWxlZCIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZG9tYWluTGlmZWN5Y2xlVXBkYXRlVHJpZ2dlcmVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gY29udGV4dC5Cb2R5Py5lcnJvck1lc3NhZ2UgPz8gIkZhaWxlZCB0byB0cmlnZ2VyIGRvbWFpbiBsaWZlY3ljbGUgdXBkYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcmVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5SZWdpc3RyYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb3BlcmF0aW9uID0gInVwZGF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJGYWlsZWQgdG8gdXBkYXRlIGNhY2hlIGRvbWFpbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlID8/IDUwMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImxpZmVjeWNsZSIsICJ1cGRhdGUiLCAiZGlyZWN0LXRyaWdnZXIiLCAiZXJyb3IiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRvbWFpbi1saWZlY3ljbGUtdXBkYXRlLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZG9tYWluTGlmZWN5Y2xlVXBkYXRlVHJpZ2dlcmVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRXhjZXB0aW9uIGR1cmluZyBkb21haW4gbGlmZWN5Y2xlIHVwZGF0ZSB0cmlnZ2VyIiwKICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgZG9tYWluUmVnaXN0cmF0aW9uID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbiA9ICJ1cGRhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJFeGNlcHRpb24gZHVyaW5nIGRvbWFpbiB1cGRhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvckRlc2NyaXB0aW9uID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJkb21haW4iLCAibGlmZWN5Y2xlIiwgInVwZGF0ZSIsICJleGNlcHRpb24iLCAiZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "update-success", - "target": "upsert-redis", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Update Success" - }, - { - "language": "tr-TR", - "label": "Otomatik - Güncelleme Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/UpdateSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFVwZGF0ZSBTdWNjZXNzIFJ1bGUgLSBDaGVja3MgaWYgZG9tYWluIHVwZGF0ZSB3YXMgc3VjY2Vzc2Z1bAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgVXBkYXRlU3VjY2Vzc1J1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChjb250ZXh0Py5JbnN0YW5jZT8uRGF0YSA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgdmFyIGRvbWFpblJlZ2lzdHJhdGlvbiA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5kb21haW5SZWdpc3RyYXRpb247CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoZG9tYWluUmVnaXN0cmF0aW9uID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgICAgICAvLyBDaGVjayBpZiB1cGRhdGUgd2FzIHN1Y2Nlc3NmdWwgYW5kIG9wZXJhdGlvbiBpcyAidXBkYXRlIgogICAgICAgICAgICByZXR1cm4gZG9tYWluUmVnaXN0cmF0aW9uLnN1Y2Nlc3MgPT0gdHJ1ZSAmJiAKICAgICAgICAgICAgICAgICAgIGRvbWFpblJlZ2lzdHJhdGlvbi5vcGVyYXRpb24/LlRvU3RyaW5nKCkgPT0gInVwZGF0ZSI7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "check-domain-need-update", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Update Domain" - }, - { - "language": "tr-TR", - "label": "Domain Güncelle" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "domain-need-update", - "target": "update", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Domain Not Match Send To Update" - }, - { - "language": "tr-TR", - "label": "Otomatik - Domain Eşleşmedi Update e Gönder" - } - ], - "schema": null, - "rule": { - "location": "./src/CheckDomainDontMatchRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBDaGVja0RvbWFpbkRvbnRNYXRjaFJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIEdldCBpbmNvbWluZyB2YWx1ZXMgZnJvbSByZXF1ZXN0CiAgICAgICAgICAgIHZhciBpbmNvbWluZ0hlYWx0aFVybCA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5oZWFsdGhVcmw/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBpbmNvbWluZ0FwcElkID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmFwcElkPy5Ub1N0cmluZygpOwogICAgICAgICAgICB2YXIgaW5jb21pbmdCYXNlVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmJhc2VVcmw/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIC8vIEdldCBleGlzdGluZyB2YWx1ZXMgZnJvbSBkb21haW4gY2hlY2sgcmVzcG9uc2UKICAgICAgICAgICAgdmFyIGV4aXN0aW5nSGVhbHRoVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmV4aXN0aW5nSGVhbHRoVXJsPy5Ub1N0cmluZygpOwogICAgICAgICAgICB2YXIgZXhpc3RpbmdBcHBJZCA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5leGlzdGluZ0FwcElkPy5Ub1N0cmluZygpOwogICAgICAgICAgICB2YXIgZXhpc3RpbmdCYXNlVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmV4aXN0aW5nQmFzZVVybD8uVG9TdHJpbmcoKTsKCiAgICAgICAgICAgIC8vIElmIGVpdGhlciBpbmNvbWluZyB2YWx1ZSBpcyBtaXNzaW5nL251bGwsIHByb2NlZWQgdG8gdXBkYXRlCiAgICAgICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShpbmNvbWluZ0hlYWx0aFVybCkgfHwgc3RyaW5nLklzTnVsbE9yRW1wdHkoaW5jb21pbmdBcHBJZCkKICAgICAgICAgICAgfHwgc3RyaW5nLklzTnVsbE9yRW1wdHkoaW5jb21pbmdCYXNlVXJsKSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwoKICAgICAgICAgICAgLy8gSWYgZWl0aGVyIGV4aXN0aW5nIHZhbHVlIGlzIG1pc3NpbmcvbnVsbCwgcHJvY2VlZCB0byB1cGRhdGUKICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGV4aXN0aW5nSGVhbHRoVXJsKSB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShleGlzdGluZ0FwcElkKQogICAgICAgICAgICB8fHN0cmluZy5Jc051bGxPckVtcHR5KGV4aXN0aW5nQmFzZVVybCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICAgICAgICAgIC8vIElmIGVpdGhlciB2YWx1ZSBkaWZmZXJzLCBwcm9jZWVkIHRvIHVwZGF0ZQogICAgICAgICAgICBpZiAoaW5jb21pbmdIZWFsdGhVcmwuRXF1YWxzKGV4aXN0aW5nSGVhbHRoVXJsLCBTdHJpbmdDb21wYXJpc29uLk9yZGluYWxJZ25vcmVDYXNlKSAmJgogICAgICAgICAgICAgICAgaW5jb21pbmdBcHBJZC5FcXVhbHMoZXhpc3RpbmdBcHBJZCwgU3RyaW5nQ29tcGFyaXNvbi5PcmRpbmFsSWdub3JlQ2FzZSkmJgogICAgICAgICAgICAgICAgaW5jb21pbmdCYXNlVXJsLkVxdWFscyhleGlzdGluZ0Jhc2VVcmwsIFN0cmluZ0NvbXBhcmlzb24uT3JkaW5hbElnbm9yZUNhc2UpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBHbyB0byBjb21wbGV0ZWQKCiAgICAgICAgICAgIC8vIEdvIHRvIHVwZGF0ZQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsgLy8gR28gdG8gdXBkYXRlIHN0YXRlCiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIE9uIGVycm9yLCBwcm9jZWVkIHRvIHVwZGF0ZSAoY29uc2VydmF0aXZlIGFwcHJvYWNoKQogICAgICAgIH0KICAgIH0KfQoKCgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "domain-dont-need-update", - "target": "completed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Domain Match Send To Completed" - }, - { - "language": "tr-TR", - "label": "Otomatik - Domain Eşleşti Flowu Bitir" - } - ], - "schema": null, - "rule": { - "location": "./src/CheckDomainMatchRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBDaGVja0RvbWFpbk1hdGNoUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gR2V0IGluY29taW5nIHZhbHVlcyBmcm9tIHJlcXVlc3QKICAgICAgICAgICAgdmFyIGluY29taW5nSGVhbHRoVXJsID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmhlYWx0aFVybD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgdmFyIGluY29taW5nQXBwSWQgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuYXBwSWQ/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBpbmNvbWluZ0Jhc2VVcmwgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuYmFzZVVybD8uVG9TdHJpbmcoKTsKICAgICAgICAgICAgLy8gR2V0IGV4aXN0aW5nIHZhbHVlcyBmcm9tIGRvbWFpbiBjaGVjayByZXNwb25zZQogICAgICAgICAgICB2YXIgZXhpc3RpbmdIZWFsdGhVcmwgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZXhpc3RpbmdIZWFsdGhVcmw/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBleGlzdGluZ0FwcElkID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmV4aXN0aW5nQXBwSWQ/LlRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciBleGlzdGluZ0Jhc2VVcmwgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZXhpc3RpbmdCYXNlVXJsPy5Ub1N0cmluZygpOwoKICAgICAgICAgICAgLy8gSWYgZWl0aGVyIGluY29taW5nIHZhbHVlIGlzIG1pc3NpbmcvbnVsbCwgZG9uJ3Qgc2tpcCB0byBjb21wbGV0ZWQKICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGluY29taW5nSGVhbHRoVXJsKSB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShpbmNvbWluZ0FwcElkKQogICAgICAgICAgICB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShpbmNvbWluZ0Jhc2VVcmwpKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgLy8gSWYgZWl0aGVyIGV4aXN0aW5nIHZhbHVlIGlzIG1pc3NpbmcvbnVsbCwgZG9uJ3Qgc2tpcCB0byBjb21wbGV0ZWQKICAgICAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGV4aXN0aW5nSGVhbHRoVXJsKSB8fCBzdHJpbmcuSXNOdWxsT3JFbXB0eShleGlzdGluZ0FwcElkKQogICAgICAgICAgICB8fHN0cmluZy5Jc051bGxPckVtcHR5KGV4aXN0aW5nQmFzZVVybCkpCiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICAgICAgICAvLyBJZiBib3RoIHZhbHVlcyBtYXRjaCwgc2tpcCB0byBjb21wbGV0ZWQKICAgICAgICAgICAgaWYgKGluY29taW5nSGVhbHRoVXJsLkVxdWFscyhleGlzdGluZ0hlYWx0aFVybCwgU3RyaW5nQ29tcGFyaXNvbi5PcmRpbmFsSWdub3JlQ2FzZSkgJiYKICAgICAgICAgICAgICAgIGluY29taW5nQXBwSWQuRXF1YWxzKGV4aXN0aW5nQXBwSWQsIFN0cmluZ0NvbXBhcmlzb24uT3JkaW5hbElnbm9yZUNhc2UpJiYKICAgICAgICAgICAgICAgIGluY29taW5nQmFzZVVybC5FcXVhbHMoZXhpc3RpbmdCYXNlVXJsLCBTdHJpbmdDb21wYXJpc29uLk9yZGluYWxJZ25vcmVDYXNlKSkKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBHbyB0byBjb21wbGV0ZWQKCiAgICAgICAgICAgIC8vIFZhbHVlcyBkb24ndCBtYXRjaCwgZ28gdG8gdXBkYXRlCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBmYWxzZTsgIC8vIE9uIGVycm9yLCBkb24ndCBza2lwIHRvIGNvbXBsZXRlZAogICAgICAgIH0KICAgIH0KfQoKCgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "upsert-redis", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Upsert Redis" - }, - { - "language": "tr-TR", - "label": "Redis'e Kaydet" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "upsert-success", - "target": "check-health-url", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Redis Success" - }, - { - "language": "tr-TR", - "label": "Otomatik - Redis Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/UpsertSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFVwc2VydCBTdWNjZXNzIFJ1bGUgLSBDaGVja3MgaWYgZG9tYWluIHJlZ2lzdHJhdGlvbi91cGRhdGUgd2FzIHN1Y2Nlc3NmdWwKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFVwc2VydFN1Y2Nlc3NSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgICAgICAgIHZhciBkb21haW5SZWdpc3RyYXRpb24gPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZG9tYWluUmVnaXN0cmF0aW9uOwogICAgICAgICAgICAKICAgICAgICAgICAgaWYgKGRvbWFpblJlZ2lzdHJhdGlvbiA9PSBudWxsKQogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgICAgICAgICAgcmV0dXJuIGRvbWFpblJlZ2lzdHJhdGlvbi5zdWNjZXNzID09IHRydWU7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9CgoKCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "upsert-failure", - "target": "error", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Redis Failure" - }, - { - "language": "tr-TR", - "label": "Otomatik - Redis Hatası" - } - ], - "schema": null, - "rule": { - "location": "./src/UpsertFailureRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFVwc2VydCBGYWlsdXJlIFJ1bGUgLSBDaGVja3MgaWYgZG9tYWluIHJlZ2lzdHJhdGlvbi91cGRhdGUgZmFpbGVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBVcHNlcnRGYWlsdXJlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGNvbnRleHQ/Lkluc3RhbmNlPy5EYXRhID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIElmIG5vIGRhdGEsIGNvbnNpZGVyIGl0IGEgZmFpbHVyZQoKICAgICAgICAgICAgdmFyIGRvbWFpblJlZ2lzdHJhdGlvbiA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YS5kb21haW5SZWdpc3RyYXRpb247CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoZG9tYWluUmVnaXN0cmF0aW9uID09IG51bGwpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsgIC8vIElmIG5vIHJlZ2lzdHJhdGlvbiByZXN1bHQsIGNvbnNpZGVyIGl0IGEgZmFpbHVyZQoKICAgICAgICAgICAgcmV0dXJuIGRvbWFpblJlZ2lzdHJhdGlvbi5zdWNjZXNzID09IGZhbHNlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7ICAvLyBPbiBlcnJvciwgY29uc2lkZXIgaXQgYSBmYWlsdXJlCiAgICAgICAgfQogICAgfQp9CgoKCg==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "check-health-url", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Check Health URL" - }, - { - "language": "tr-TR", - "label": "Sağlık URL'sini Kontrol Et" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "trigger-health-check", - "target": "schedule-health-check", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Trigger Health Check" - }, - { - "language": "tr-TR", - "label": "Otomatik - Sağlık Kontrolünü Tetikle" - } - ], - "schema": null, - "rule": { - "location": "./src/ShouldTriggerHealthCheckRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFNob3VsZCBUcmlnZ2VyIEhlYWx0aCBDaGVjayBSdWxlIC0gQ2hlY2tzIGlmIGhlYWx0aCBjaGVjayB3b3JrZmxvdyBzaG91bGQgYmUgdHJpZ2dlcmVkCi8vLyBSZXR1cm5zIHRydWUgaWYgaGVhbHRoVXJsIGV4aXN0cyBBTkQgKG5ldyBkb21haW4gT1IgaGVhbHRoVXJsIGNoYW5nZWQpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBTaG91bGRUcmlnZ2VySGVhbHRoQ2hlY2tSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24pCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "skip-health-check", - "target": "completed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Skip Health Check" - }, - { - "language": "tr-TR", - "label": "Otomatik - Sağlık Kontrolünü Atla" - } - ], - "schema": null, - "rule": { - "location": "./src/SkipHealthCheckRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFNraXAgSGVhbHRoIENoZWNrIFJ1bGUgLSBDaGVja3MgaWYgaGVhbHRoIGNoZWNrIHNob3VsZCBiZSBza2lwcGVkCi8vLyBSZXR1cm5zIHRydWUgaWYgaGVhbHRoVXJsIGlzIG1pc3NpbmcgT1IgKGV4aXN0aW5nIGRvbWFpbiBBTkQgaGVhbHRoVXJsIGRpZG4ndCBjaGFuZ2UpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBTa2lwSGVhbHRoQ2hlY2tSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7ICAvLyBPbiBlcnJvciwgc2tpcAogICAgICAgIH0KICAgIH0KfQoK" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "schedule-health-check", - "stateType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Schedule Health Check" - }, - { - "language": "tr-TR", - "label": "Sağlık Kontrolü Planla" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "health-check-triggered", - "target": "completed", - "triggerType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Health Check Triggered" - }, - { - "language": "tr-TR", - "label": "Otomatik - Sağlık Kontrolü Tetiklendi" - } - ], - "schema": null, - "timer": { - "location": "./src/ScheduleHealthCheckTimerMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zLlRpbWVyOwoKLy8vIDxzdW1tYXJ5PgovLy8gU2NoZWR1bGUgSGVhbHRoIENoZWNrIFRpbWVyIE1hcHBpbmcgLSBSZXR1cm5zIHRpbWVyIHNjaGVkdWxlIGZvciAzMCBzZWNvbmRzIGRlbGF5Ci8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBTY2hlZHVsZUhlYWx0aENoZWNrVGltZXJNYXBwaW5nIDogSVRpbWVyTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxUaW1lclNjaGVkdWxlPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFJldHVybiB0aW1lciBzY2hlZHVsZSBmb3IgMzAgc2Vjb25kcyBmcm9tIG5vdwogICAgICAgICAgICByZXR1cm4gVGltZXJTY2hlZHVsZS5Gcm9tRGF0ZVRpbWUoRGF0ZVRpbWUuVXRjTm93LkFkZFNlY29uZHMoMzApKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbikKICAgICAgICB7CiAgICAgICAgICAgIC8vIEZhbGxiYWNrIHRvIDMwIHNlY29uZHMgb24gZXJyb3IKICAgICAgICAgICAgcmV0dXJuIFRpbWVyU2NoZWR1bGUuRnJvbURhdGVUaW1lKERhdGVUaW1lLlV0Y05vdy5BZGRTZWNvbmRzKDMwKSk7CiAgICAgICAgfQogICAgfQp9Cgo=" - }, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "schedule-health-check", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ScheduleHealthCheckMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gU2NoZWR1bGUgSGVhbHRoIENoZWNrIE1hcHBpbmcgLSBUcmlnZ2VycyBkb21haW4taGVhbHRoLWNoZWNrIHdvcmtmbG93IGFzIHN1YnByb2Nlc3MKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFNjaGVkdWxlSGVhbHRoQ2hlY2tNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHN1YlByb2Nlc3NUYXNrID0gdGFzayBhcyBTdWJQcm9jZXNzVGFzazsKICAgICAgICAgICAgaWYgKHN1YlByb2Nlc3NUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYSBTdWJQcm9jZXNzVGFzayIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgZG9tYWluTmFtZSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmRvbWFpbk5hbWU7CiAgICAgICAgICAgIHZhciBkb21haW5EYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZG9tYWluRGF0YTsKICAgICAgICAgICAgdmFyIGhlYWx0aFVybCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmhlYWx0aFVybDsKCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBzdWJwcm9jZXNzCiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldEtleSgiZG9tYWluLWhlYWx0aC1jaGVjayIpOwogICAgICAgICAgICBzdWJQcm9jZXNzVGFzay5TZXRWZXJzaW9uKCIxLjAuMCIpOwoKICAgICAgICAgICAgLy8gUHJlcGFyZSBzdWJwcm9jZXNzIGluaXRpYWxpemF0aW9uIGRhdGEKICAgICAgICAgICAgLy8gUGFzcyBkb21haW4gaW5mb3JtYXRpb24gdG8gaGVhbHRoIGNoZWNrIHdvcmtmbG93CiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldEJvZHkobmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRvbWFpbk5hbWUgPSBkb21haW5OYW1lLAogICAgICAgICAgICAgICAgaGVhbHRoVXJsID0gaGVhbHRoVXJsID8/IGRvbWFpbkRhdGE/LmhlYWx0aFVybCwKICAgICAgICAgICAgICAgIGRvbWFpbkRhdGEgPSBkb21haW5EYXRhCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAic2NoZWR1bGUtaGVhbHRoLWNoZWNrLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gU3ViUHJvY2VzcyBpcyBmaXJlLWFuZC1mb3JnZXQKICAgICAgICAgICAgLy8gSnVzdCB0cmFjayB0aGF0IGl0IHdhcyBpbml0aWF0ZWQKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiaGVhbHRoLWNoZWNrLXRyaWdnZXJlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaGVhbHRoQ2hlY2tUcmlnZ2VyZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgIHRyaWdnZXJlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9ICJIRUFMVEhfQ0hFQ0tfU1VCUFJPQ0VTU19MQVVOQ0hFRCIKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImhlYWx0aC1jaGVjayIsICJ0cmlnZ2VyZWQiLCAic3VicHJvY2VzcyIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJoZWFsdGgtY2hlY2stdHJpZ2dlci1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGhlYWx0aENoZWNrVHJpZ2dlcmVkID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiRXhjZXB0aW9uIGR1cmluZyBoZWFsdGggY2hlY2sgdHJpZ2dlciIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JEZXNjcmlwdGlvbiA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcmVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZG9tYWluIiwgImhlYWx0aC1jaGVjayIsICJleGNlcHRpb24iLCAiZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0K" - } - } - ] - } - ] - }, - { - "key": "completed", - "stateType": 3, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Completed" - }, - { - "language": "tr-TR", - "label": "Tamamlandı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "error", - "stateType": 3, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Error" - }, - { - "language": "tr-TR", - "label": "Hata" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/discovery/domain-workflow.json b/core/Workflows/discovery/domain-workflow.json deleted file mode 100644 index 0d5e926..0000000 --- a/core/Workflows/discovery/domain-workflow.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "key": "domain", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "domain", - "lifecycle", - "registration" - ], - "attributes": { - "type": "F", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Domain Lifecycle Workflow" - }, - { - "language": "tr-TR", - "label": "Domain Yaşam Döngüsü İş Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-domain", - "target": "domain-registered", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Domain" - }, - { - "language": "tr-TR", - "label": "Domain'i Başlat" - } - ], - "schema": { - "key": "domain-update", - "version": "1.0.0", - "domain": "core", - "flow": "sys-schemas" - }, - "onExecutionTasks": [] - }, - "states": [ - { - "key": "domain-registered", - "stateType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Domain Registered" - }, - { - "language": "tr-TR", - "label": "Domain Kayıtlı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "update", - "target": "domain-registered", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto - Update" - }, - { - "language": "tr-TR", - "label": "Otomatik - Güncelle" - } - ], - "schema": { - "key": "domain-update", - "version": "1.0.0", - "domain": "core", - "flow": "sys-schemas" - }, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/discovery/src/AggregateResultsMapping.csx b/core/Workflows/discovery/src/AggregateResultsMapping.csx deleted file mode 100644 index a42c086..0000000 --- a/core/Workflows/discovery/src/AggregateResultsMapping.csx +++ /dev/null @@ -1,55 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using BBT.Workflow.Scripting; - -/// -/// Aggregate Results Mapping - Combines results from current page -/// -public class AggregateResultsMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - // No input handling needed - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // Get results from context - var healthyDomains = context.Instance?.Data?.HealthyDomains as List ?? new List(); - var notHealthyDomains = context.Instance?.Data?.NotHealthyDomains as List ?? new List(); - - // Aggregate results (already combined in CheckDomainHealthMapping) - return new ScriptResponse - { - Key = "to-check-pagination", - Data = new - { - HealthyDomains = healthyDomains, - NotHealthyDomains = notHealthyDomains, - totalHealthy = healthyDomains.Count, - totalNotHealthy = notHealthyDomains.Count, - aggregatedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "aggregate", "results", "success" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "aggregate-error", - Data = new - { - error = "Exception during result aggregation", - errorDescription = ex.Message, - aggregatedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "aggregate", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/CheckDomainDontMatchRule.csx b/core/Workflows/discovery/src/CheckDomainDontMatchRule.csx deleted file mode 100644 index 8141937..0000000 --- a/core/Workflows/discovery/src/CheckDomainDontMatchRule.csx +++ /dev/null @@ -1,46 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class CheckDomainDontMatchRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - // Get incoming values from request - var incomingHealthUrl = context.Instance.Data.healthUrl?.ToString(); - var incomingAppId = context.Instance.Data.appId?.ToString(); - var incomingBaseUrl = context.Instance.Data.baseUrl?.ToString(); - // Get existing values from domain check response - var existingHealthUrl = context.Instance.Data.existingHealthUrl?.ToString(); - var existingAppId = context.Instance.Data.existingAppId?.ToString(); - var existingBaseUrl = context.Instance.Data.existingBaseUrl?.ToString(); - - // If either incoming value is missing/null, proceed to update - if (string.IsNullOrEmpty(incomingHealthUrl) || string.IsNullOrEmpty(incomingAppId) - || string.IsNullOrEmpty(incomingBaseUrl)) - return true; - - // If either existing value is missing/null, proceed to update - if (string.IsNullOrEmpty(existingHealthUrl) || string.IsNullOrEmpty(existingAppId) - ||string.IsNullOrEmpty(existingBaseUrl)) - return true; - - // If either value differs, proceed to update - if (incomingHealthUrl.Equals(existingHealthUrl, StringComparison.OrdinalIgnoreCase) && - incomingAppId.Equals(existingAppId, StringComparison.OrdinalIgnoreCase)&& - incomingBaseUrl.Equals(existingBaseUrl, StringComparison.OrdinalIgnoreCase)) - return false; // Go to completed - - // Go to update - return true; // Go to update state - } - catch (Exception) - { - return true; // On error, proceed to update (conservative approach) - } - } -} - - - diff --git a/core/Workflows/discovery/src/CheckDomainExistsMapping.csx b/core/Workflows/discovery/src/CheckDomainExistsMapping.csx deleted file mode 100644 index 9440e9b..0000000 --- a/core/Workflows/discovery/src/CheckDomainExistsMapping.csx +++ /dev/null @@ -1,149 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting.Functions; -/// -/// Check Domain Exists Mapping - Queries domain workflow instance for existence using DaprServiceTask -/// Endpoint: /api/v1/discovery/workflows/domain/instances/{domainName}/functions/data -/// -public class CheckDomainExistsMapping :ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - string? appId = GetConfigValue("OrchestrationApi:AppId"); - string? daprAppId = GetConfigValue("DAPR_APP_ID"); - - var daprServiceTask= task as DaprServiceTask; - if (daprServiceTask == null) - { - throw new InvalidOperationException("Task must be a DaprServiceTask"); - } - LogInformation("AppId ariyorum dapr:"+daprAppId); - LogInformation("AppId ariyorum exec set:"+appId); - daprServiceTask.SetAppId(daprAppId); - var domainName = context.Instance?.Data?.domainName; - - // Replace {domainName} placeholder in methodName - // MethodName format: /api/v1/discovery/workflows/domain/instances/{domainName}/functions/data - if (!string.IsNullOrEmpty(domainName?.ToString())) - { - var methodName = daprServiceTask.MethodName?.Replace("{domainName}", domainName.ToString()) ?? - $"/api/v1/discovery/workflows/domain/instances/{domainName}/functions/data"; - daprServiceTask.SetMethodName(methodName); - } - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "check-domain-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // Workflow Instance Data API returns: - // - 200 OK with data (including etag) if instance exists - // - 404 Not Found if instance doesn't exist - var statusCode = context.Body?.statusCode ?? 500; - var responseData = context.Body; - - // Domain workflow instance exists (200 OK with data) - if (statusCode == 200 && responseData != null) - { - // Extract etag from response body (root level, lowercase) - // Response format: { "data": { "appId": "...", "healthUrl": "...", "domainName": "...", "baseUrl": "..." }, "etag": "...", "extensions": {} } - var eTag = responseData.data?.etag?.ToString(); - - // Extract healthUrl and appId from existing domain data - // Domain data structure: direct properties in data object (no underscore prefix) - var existingHealthUrl = responseData.data?.data?.healthUrl?.ToString(); - var existingBaseUrl = responseData.data?.data?.baseUrl?.ToString(); - var existingAppId = responseData.data?.data?.appId?.ToString(); - - return new ScriptResponse - { - Key = "domain-exists", - Data = new - { - domainExists = true, - existingDomain = responseData, - instanceETag = eTag, - existingHealthUrl = existingHealthUrl, - existingBaseUrl=existingBaseUrl, - existingAppId = existingAppId, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "exists", "workflow", "instance", "found" } - }; - } - // Domain workflow instance not found (404 Not Found) - else if (statusCode == 404) - { - return new ScriptResponse - { - Key = "domain-not-exists", - Data = new - { - domainExists = false, - existingDomain = (object?)null, - instanceETag = (string?)null, - existingHealthUrl = (string?)null, - existingAppId = (string?)null, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "not-exists", "workflow", "instance", "not-found" } - }; - } - // Unexpected status code - else - { - return new ScriptResponse - { - Key = "domain-check-exception", - Data = new - { - domainExists = false, - existingDomain = (object?)null, - instanceETag = (string?)null, - existingHealthUrl = (string?)null, - existingAppId = (string?)null, - error = "Unexpected status code during domain instance check", - statusCode = statusCode, - check=responseData.data, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "exception", "error" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "domain-check-exception", - Data = new - { - domainExists = false, - existingDomain = (object?)null, - instanceETag = (string?)null, - existingHealthUrl = (string?)null, - existingAppId = (string?)null, - error = "Exception during domain instance check", - errorDescription = ex.Message, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/CheckDomainHealthMapping.csx b/core/Workflows/discovery/src/CheckDomainHealthMapping.csx deleted file mode 100644 index 1f5529b..0000000 --- a/core/Workflows/discovery/src/CheckDomainHealthMapping.csx +++ /dev/null @@ -1,157 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using System.Linq; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Check Domain Health Mapping - Checks health for one domain at a time (sequential processing) -/// -public class CheckDomainHealthMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - // Get current domain from pendingDomains array using currentDomainIndex - var pendingDomains = context.Instance?.Data?.pendingDomains as List; - var currentDomainIndex = Convert.ToInt32(context.Instance?.Data?.currentDomainIndex ?? 0); - - if (pendingDomains == null || currentDomainIndex >= pendingDomains.Count) - { - return Task.FromResult(new ScriptResponse - { - Key = "page-complete", - Data = new { error = "No more domains to process" } - }); - } - - // Get current domain - var currentDomain = pendingDomains[currentDomainIndex] as Dictionary; - if (currentDomain == null) - { - return Task.FromResult(new ScriptResponse - { - Key = "page-complete", - Data = new { error = "Invalid domain data" } - }); - } - - var healthUrl = currentDomain.ContainsKey("healthUrl") ? currentDomain["healthUrl"]?.ToString() : null; - - if (string.IsNullOrEmpty(healthUrl)) - { - return Task.FromResult(new ScriptResponse - { - Key = "health-check-error", - Data = new { error = "Health URL is missing" } - }); - } - - // Set the health URL for the HTTP request - httpTask.SetUrl(healthUrl); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "health-check-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var statusCode = context.Body?.statusCode ?? 500; - var pendingDomains = context.Instance?.Data?.pendingDomains as List ?? new List(); - var currentDomainIndex = Convert.ToInt32(context.Instance?.Data?.currentDomainIndex ?? 0); - var healthyDomains = context.Instance?.Data?.HealthyDomains as List ?? new List(); - var notHealthyDomains = context.Instance?.Data?.NotHealthyDomains as List ?? new List(); - - // Get current domain - if (currentDomainIndex >= pendingDomains.Count) - { - return new ScriptResponse - { - Key = "page-complete", - Data = new - { - HealthyDomains = healthyDomains, - NotHealthyDomains = notHealthyDomains, - processedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", "complete" } - }; - } - - var currentDomain = pendingDomains[currentDomainIndex] as Dictionary; - var domainName = currentDomain?.ContainsKey("domainName") == true ? currentDomain["domainName"]?.ToString() : null; - - // Determine health status based on HTTP status code - // 200 = healthy, otherwise unhealthy - bool isHealthy = statusCode == 200; - - // Add to appropriate list - if (isHealthy) - { - if (!healthyDomains.Contains(domainName)) - { - healthyDomains.Add(domainName); - } - } - else - { - if (!notHealthyDomains.Contains(domainName)) - { - notHealthyDomains.Add(domainName); - } - } - - // Increment index for next domain - var nextIndex = currentDomainIndex + 1; - var hasMoreDomains = nextIndex < pendingDomains.Count; - - return new ScriptResponse - { - Key = hasMoreDomains ? "has-more-domains" : "page-complete", - Data = new - { - currentDomainIndex = nextIndex, - HealthyDomains = healthyDomains, - NotHealthyDomains = notHealthyDomains, - isHealthy = isHealthy, - domainName = domainName, - statusCode = statusCode, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", isHealthy ? "healthy" : "unhealthy", hasMoreDomains ? "continue" : "complete" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "health-check-error", - Data = new - { - error = "Exception during health check", - errorDescription = ex.Message, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/CheckDomainMatchRule.csx b/core/Workflows/discovery/src/CheckDomainMatchRule.csx deleted file mode 100644 index 4a4699d..0000000 --- a/core/Workflows/discovery/src/CheckDomainMatchRule.csx +++ /dev/null @@ -1,46 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class CheckDomainMatchRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - // Get incoming values from request - var incomingHealthUrl = context.Instance.Data.healthUrl?.ToString(); - var incomingAppId = context.Instance.Data.appId?.ToString(); - var incomingBaseUrl = context.Instance.Data.baseUrl?.ToString(); - // Get existing values from domain check response - var existingHealthUrl = context.Instance.Data.existingHealthUrl?.ToString(); - var existingAppId = context.Instance.Data.existingAppId?.ToString(); - var existingBaseUrl = context.Instance.Data.existingBaseUrl?.ToString(); - - // If either incoming value is missing/null, don't skip to completed - if (string.IsNullOrEmpty(incomingHealthUrl) || string.IsNullOrEmpty(incomingAppId) - || string.IsNullOrEmpty(incomingBaseUrl)) - return false; - - // If either existing value is missing/null, don't skip to completed - if (string.IsNullOrEmpty(existingHealthUrl) || string.IsNullOrEmpty(existingAppId) - ||string.IsNullOrEmpty(existingBaseUrl)) - return false; - - // If both values match, skip to completed - if (incomingHealthUrl.Equals(existingHealthUrl, StringComparison.OrdinalIgnoreCase) && - incomingAppId.Equals(existingAppId, StringComparison.OrdinalIgnoreCase)&& - incomingBaseUrl.Equals(existingBaseUrl, StringComparison.OrdinalIgnoreCase)) - return true; // Go to completed - - // Values don't match, go to update - return false; - } - catch (Exception) - { - return false; // On error, don't skip to completed - } - } -} - - - diff --git a/core/Workflows/discovery/src/CheckHealthEndpointMapping.csx b/core/Workflows/discovery/src/CheckHealthEndpointMapping.csx deleted file mode 100644 index 1005a2f..0000000 --- a/core/Workflows/discovery/src/CheckHealthEndpointMapping.csx +++ /dev/null @@ -1,151 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Check Health Endpoint Mapping - Performs HTTP GET to health endpoint and determines health status -/// -public class CheckHealthEndpointMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var fullHealthUrl = context.Instance?.Data?.fullHealthUrl; - - if (string.IsNullOrEmpty(fullHealthUrl)) - { - return Task.FromResult(new ScriptResponse - { - Key = "health-check-error", - Data = new { error = "Health URL is missing" } - }); - } - - // Set the health URL for the HTTP request - httpTask.SetUrl(fullHealthUrl); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "health-check-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var statusCode = context.Body?.statusCode ?? 500; - var responseData = context.Body; - - // Determine health status based on HTTP status code - // 200-299: Healthy - // 300-399: Degraded (redirects, etc.) - // 400-599: Unhealthy - // Timeout or connection error: Unhealthy - - string healthStatus = null; - bool isHealthy = false; - bool checkPassed = false; - - if (statusCode >= 200 && statusCode < 300) - { - healthStatus = "Healthy"; - isHealthy = true; - checkPassed = true; - } - else if (statusCode >= 300 && statusCode < 400) - { - healthStatus = "Degraded"; - isHealthy = false; - checkPassed = false; - } - else if (statusCode >= 400) - { - healthStatus = "Unhealthy"; - isHealthy = false; - checkPassed = false; - } - else - { - // Timeout or connection error - healthStatus = "Unhealthy"; - isHealthy = false; - checkPassed = false; - } - - if (checkPassed) - { - return new ScriptResponse - { - Key = "health-check-passed", - Data = new - { - healthCheck = new - { - status = healthStatus, - isHealthy = isHealthy, - statusCode = statusCode, - responseData = responseData, - checkedAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "health-check", "passed", "healthy", "success" } - }; - } - else - { - return new ScriptResponse - { - Key = "health-check-failed", - Data = new - { - healthCheck = new - { - status = healthStatus, - isHealthy = isHealthy, - statusCode = statusCode, - error = $"Health check failed with status code {statusCode}", - responseData = responseData, - checkedAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "health-check", "failed", "unhealthy", "error" } - }; - } - } - catch (Exception ex) - { - // Timeout or connection error - return new ScriptResponse - { - Key = "health-check-failed", - Data = new - { - healthCheck = new - { - status = "Unhealthy", - isHealthy = false, - error = "Exception during health check", - errorDescription = ex.Message, - checkedAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "health-check", "failed", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/CheckPaginationRule.csx b/core/Workflows/discovery/src/CheckPaginationRule.csx deleted file mode 100644 index 2732645..0000000 --- a/core/Workflows/discovery/src/CheckPaginationRule.csx +++ /dev/null @@ -1,27 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Check Pagination Rule - Checks if next link exists in response -/// -public class CheckPaginationRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var nextPageUrl = context.Instance.Data.nextPageUrl?.ToString(); - - // Return true if next link is not null/empty - return !string.IsNullOrEmpty(nextPageUrl); - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/DomainExistsRule.csx b/core/Workflows/discovery/src/DomainExistsRule.csx deleted file mode 100644 index 31a0e39..0000000 --- a/core/Workflows/discovery/src/DomainExistsRule.csx +++ /dev/null @@ -1,66 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Domain Exists Rule - Checks if domain already exists in workflow instance -/// Also checks ETag to determine if update is needed -/// Returns false (skip update) if ETags match, true (proceed to update) if ETags differ -/// -public class DomainExistsRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - - try - { - if (context?.Instance?.Data == null) - return false; // If no data, assume domain doesn't exist - - var domainExists = context.Instance.Data.domainExists; - - if (domainExists == null) - return false; // If no check result, assume domain doesn't exist - - return domainExists == true; - } - catch (Exception) - { - return false; // On error, assume domain doesn't exist - } - // try - // { - // if (context?.Instance?.Data == null) - // return false; - - // var domainExists = context.Instance.Data.domainExists; - - // if (domainExists == null || domainExists != true) - // return false; - - // // Get ETag values - // // instanceETag: from GetInstanceDataTask response (current instance ETag) - // // eTag: from transition call (sent ETag) - // var instanceETag = context.Instance.Data.instanceETag?.ToString(); - // var sentETag = context.Instance.Data.eTag?.ToString(); - - // // If no ETags provided, proceed to update (conservative approach) - // if (string.IsNullOrEmpty(instanceETag) || string.IsNullOrEmpty(sentETag)) - // return true; - - // // If ETags match, skip update (return false - don't go to update state) - // if (instanceETag == sentETag) - // return false; - - // // If ETags differ, proceed to update (return true - go to update state) - // return true; - // } - // catch (Exception) - // { - // // On error, proceed to update (conservative approach) - // return true; - // } - } -} - - - diff --git a/core/Workflows/discovery/src/DomainNotExistsRule.csx b/core/Workflows/discovery/src/DomainNotExistsRule.csx deleted file mode 100644 index 8fa5274..0000000 --- a/core/Workflows/discovery/src/DomainNotExistsRule.csx +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Domain Not Exists Rule - Checks if domain does not exist in workflow instance -/// -public class DomainNotExistsRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return true; // If no data, assume domain doesn't exist - - var domainExists = context.Instance.Data.domainExists; - - if (domainExists == null) - return true; // If no check result, assume domain doesn't exist - - return domainExists == false; - } - catch (Exception) - { - return true; // On error, assume domain doesn't exist - } - } -} - - - diff --git a/core/Workflows/discovery/src/DomainsFetchedRule.csx b/core/Workflows/discovery/src/DomainsFetchedRule.csx deleted file mode 100644 index 9fd5472..0000000 --- a/core/Workflows/discovery/src/DomainsFetchedRule.csx +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Domains Fetched Rule - Checks if domains were successfully fetched -/// -public class DomainsFetchedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - // Always return true - mapping handles the logic via Key - return true; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/FetchDomainsListMapping.csx b/core/Workflows/discovery/src/FetchDomainsListMapping.csx deleted file mode 100644 index 37bd7ce..0000000 --- a/core/Workflows/discovery/src/FetchDomainsListMapping.csx +++ /dev/null @@ -1,103 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting.Functions; -/// -/// Fetch Domains List Mapping - Fetches domain list from API endpoint -/// -public class FetchDomainsListMapping :ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var appId = GetConfigValue("OrchestrationApi:AppId"); - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - // Get URL from context (could be initial URL or next page URL) - var url = context.Instance?.Data?.currentPageUrl?.ToString() ?? - context.Instance?.Data?.nextPageUrl?.ToString() ?? - "{{discoveryBaseUrl}}/api/v1/discovery/workflows/domain/functions/data?Page=1&PageSize=10"; - - // Set the URL for the HTTP request - httpTask.SetUrl(url); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "fetch-domains-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var statusCode = context.Body?.statusCode ?? 500; - var responseData = context.Body; - - // Successful response (200 OK) - if (statusCode >= 200 && statusCode < 300 && responseData != null) - { - // Extract items and links from response - var items = responseData.items; - var links = responseData.links; - var nextUrl = links?.next?.ToString(); - - return new ScriptResponse - { - Key = "domains-fetched", - Data = new - { - items = items, - links = links, - nextPageUrl = nextUrl, - currentPageUrl = context.Instance?.Data?.currentPageUrl, - fetchedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "fetch", "success", "api" } - }; - } - // Error response - else - { - return new ScriptResponse - { - Key = "fetch-failed", - Data = new - { - error = "Failed to fetch domains list", - statusCode = statusCode, - responseData = responseData, - fetchedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "fetch", "error", "failed" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "fetch-failed", - Data = new - { - error = "Exception during domain list fetch", - errorDescription = ex.Message, - fetchedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "fetch", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/FetchFailedRule.csx b/core/Workflows/discovery/src/FetchFailedRule.csx deleted file mode 100644 index a3a2f5a..0000000 --- a/core/Workflows/discovery/src/FetchFailedRule.csx +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Fetch Failed Rule - Checks if fetch failed -/// -public class FetchFailedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - // Always return true - mapping handles the logic via Key - return true; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/FetchNextPageMapping.csx b/core/Workflows/discovery/src/FetchNextPageMapping.csx deleted file mode 100644 index d212d91..0000000 --- a/core/Workflows/discovery/src/FetchNextPageMapping.csx +++ /dev/null @@ -1,110 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Fetch Next Page Mapping - Fetches next page using next URL from response -/// -public class FetchNextPageMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - // Get next page URL from context - var nextPageUrl = context.Instance?.Data?.nextPageUrl?.ToString(); - - if (string.IsNullOrEmpty(nextPageUrl)) - { - return Task.FromResult(new ScriptResponse - { - Key = "no-next-page", - Data = new { error = "Next page URL is missing" } - }); - } - - // Set the next page URL for the HTTP request - httpTask.SetUrl(nextPageUrl); - - // Update currentPageUrl - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "fetch-next-page-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var statusCode = context.Body?.statusCode ?? 500; - var responseData = context.Body; - - // Successful response (200 OK) - if (statusCode >= 200 && statusCode < 300 && responseData != null) - { - // Extract items and links from response - var items = responseData.items; - var links = responseData.links; - var nextUrl = links?.next?.ToString(); - - return new ScriptResponse - { - Key = "next-page-fetched", - Data = new - { - items = items, - links = links, - nextPageUrl = nextUrl, - currentPageUrl = context.Instance?.Data?.nextPageUrl, - fetchedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "fetch", "pagination", "success" } - }; - } - // Error response - else - { - return new ScriptResponse - { - Key = "fetch-next-page-failed", - Data = new - { - error = "Failed to fetch next page", - statusCode = statusCode, - responseData = responseData, - fetchedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "fetch", "pagination", "error" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "fetch-next-page-failed", - Data = new - { - error = "Exception during next page fetch", - errorDescription = ex.Message, - fetchedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "fetch", "pagination", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/GetDomainHealthUrlMapping.csx b/core/Workflows/discovery/src/GetDomainHealthUrlMapping.csx deleted file mode 100644 index a17174f..0000000 --- a/core/Workflows/discovery/src/GetDomainHealthUrlMapping.csx +++ /dev/null @@ -1,174 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting.Functions; -/// -/// Get Domain Health URL Mapping - Queries Redis for domain and extracts health URL -/// -public class GetDomainHealthUrlMapping :ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - //DAPR_HTTP_PORT - var daprHttpPort = GetConfigValue("DAPR_HTTP_PORT"); - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var domainName = context.Instance?.Data?.domainName; - var daprStateStore = GetConfigValue("DAPR_STATE_STORE_NAME"); - string url="http://localhost:"+daprHttpPort+"/v1.0/state/"+daprStateStore+"/domain:"+domainName; - httpTask.SetUrl(url); - // // Replace {domainName} placeholder in URL - // if (httpTask.Url != null) - // { - // httpTask.SetUrl(httpTask.Url.Replace("{domainName}", domainName?.ToString() ?? "")); - // } - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "get-health-url-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // Dapr State Store API returns: - // - 200 OK with value if key exists - // - 204 No Content if key doesn't exist - // - 404 Not Found if key doesn't exist (alternative) - var statusCode = context.Body?.statusCode ?? 500; - var responseData = context.Body; - - // Domain exists (200 OK with data) - if (statusCode == 200 && responseData != null) - { - var baseUrl = responseData.baseUrl; - var healthUrl = responseData.healthUrl; - - // Construct full health URL - string fullHealthUrl = null; - if (!string.IsNullOrEmpty(healthUrl)) - { - // If healthUrl is absolute, use it directly - if (healthUrl.StartsWith("http://") || healthUrl.StartsWith("https://")) - { - fullHealthUrl = healthUrl; - } - // If healthUrl is relative, combine with baseUrl - else if (!string.IsNullOrEmpty(baseUrl)) - { - var baseUrlTrimmed = baseUrl.TrimEnd('/'); - var healthUrlTrimmed = healthUrl.TrimStart('/'); - fullHealthUrl = $"{baseUrlTrimmed}/{healthUrlTrimmed}"; - } - else - { - // Health URL provided but no base URL - return new ScriptResponse - { - Key = "health-url-missing", - Data = new - { - healthUrlRetrieved = false, - error = "Health URL found but base URL is missing", - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", "url-missing", "error" } - }; - } - } - else - { - // Health URL not found in domain data - return new ScriptResponse - { - Key = "health-url-missing", - Data = new - { - healthUrlRetrieved = false, - error = "Health URL not found in domain data", - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", "url-missing", "error" } - }; - } - - return new ScriptResponse - { - Key = "health-url-retrieved", - Data = new - { - healthUrlRetrieved = true, - fullHealthUrl = fullHealthUrl, - baseUrl = baseUrl, - healthUrl = healthUrl, - domainData = responseData, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", "url-retrieved", "success" } - }; - } - // Domain not found (204 No Content or 404 Not Found) - else if (statusCode == 204 || statusCode == 404) - { - return new ScriptResponse - { - Key = "health-url-missing", - Data = new - { - healthUrlRetrieved = false, - error = "Domain not found in Redis", - statusCode = statusCode, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", "url-missing", "not-found" } - }; - } - // Unexpected status code - else - { - return new ScriptResponse - { - Key = "health-url-error", - Data = new - { - healthUrlRetrieved = false, - error = "Unexpected status code during domain lookup", - statusCode = statusCode, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", "error", "exception" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "health-url-exception", - Data = new - { - healthUrlRetrieved = false, - error = "Exception during health URL retrieval", - errorDescription = ex.Message, - checkedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/HasMoreDomainsRule.csx b/core/Workflows/discovery/src/HasMoreDomainsRule.csx deleted file mode 100644 index 057dca0..0000000 --- a/core/Workflows/discovery/src/HasMoreDomainsRule.csx +++ /dev/null @@ -1,32 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using BBT.Workflow.Scripting; - -/// -/// Has More Domains Rule - Checks if there are more domains to process in current page -/// -public class HasMoreDomainsRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var pendingDomains = context.Instance.Data.pendingDomains as List; - var currentDomainIndex = Convert.ToInt32(context.Instance.Data.currentDomainIndex ?? 0); - - if (pendingDomains == null) - return false; - - // Check if there are more domains to process - return currentDomainIndex < pendingDomains.Count; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/HealthCheckFailedRule.csx b/core/Workflows/discovery/src/HealthCheckFailedRule.csx deleted file mode 100644 index c78effb..0000000 --- a/core/Workflows/discovery/src/HealthCheckFailedRule.csx +++ /dev/null @@ -1,33 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Health Check Failed Rule - Checks if health check failed -/// -public class HealthCheckFailedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return true; // If no data, consider it failed - - var healthCheck = context.Instance.Data.healthCheck; - - if (healthCheck == null) - return true; // If no health check result, consider it failed - - var isHealthy = healthCheck.isHealthy; - if (isHealthy == null) - return true; // If health status unknown, consider it failed - - return isHealthy == false; - } - catch (Exception) - { - return true; // On error, consider it failed - } - } -} - diff --git a/core/Workflows/discovery/src/HealthCheckPassedRule.csx b/core/Workflows/discovery/src/HealthCheckPassedRule.csx deleted file mode 100644 index 05e895d..0000000 --- a/core/Workflows/discovery/src/HealthCheckPassedRule.csx +++ /dev/null @@ -1,33 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Health Check Passed Rule - Checks if health check passed -/// -public class HealthCheckPassedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var healthCheck = context.Instance.Data.healthCheck; - - if (healthCheck == null) - return false; - - var isHealthy = healthCheck.isHealthy; - if (isHealthy == null) - return false; - - return isHealthy == true; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/HealthCheckScheduledRule.csx b/core/Workflows/discovery/src/HealthCheckScheduledRule.csx deleted file mode 100644 index 0911ec8..0000000 --- a/core/Workflows/discovery/src/HealthCheckScheduledRule.csx +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Health Check Scheduled Rule - Checks if health check was successfully scheduled -/// -public class HealthCheckScheduledRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var healthCheckSchedule = context.Instance.Data.healthCheckSchedule; - - if (healthCheckSchedule == null) - return false; - - return healthCheckSchedule.success == true && healthCheckSchedule.scheduled == true; - } - catch (Exception) - { - return false; - } - } -} - - - diff --git a/core/Workflows/discovery/src/HealthCheckTriggeredRule.csx b/core/Workflows/discovery/src/HealthCheckTriggeredRule.csx deleted file mode 100644 index 3959a06..0000000 --- a/core/Workflows/discovery/src/HealthCheckTriggeredRule.csx +++ /dev/null @@ -1,26 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Health Check Triggered Rule - Checks if health check workflow was successfully triggered -/// Returns true if healthCheckTriggered == true -/// -public class HealthCheckTriggeredRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var healthCheckTriggered = context.Instance.Data.healthCheckTriggered; - return healthCheckTriggered == true; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/HealthStatusUpdateSuccessRule.csx b/core/Workflows/discovery/src/HealthStatusUpdateSuccessRule.csx deleted file mode 100644 index 19fbe18..0000000 --- a/core/Workflows/discovery/src/HealthStatusUpdateSuccessRule.csx +++ /dev/null @@ -1,30 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Health Status Update Success Rule - Checks if health status update was successful -/// -public class HealthStatusUpdateSuccessRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var healthStatusUpdate = context.Instance.Data.healthStatusUpdate; - - if (healthStatusUpdate == null) - return false; - - // Check if update was successful - return healthStatusUpdate.success == true; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/HealthUrlMissingRule.csx b/core/Workflows/discovery/src/HealthUrlMissingRule.csx deleted file mode 100644 index 65af4cb..0000000 --- a/core/Workflows/discovery/src/HealthUrlMissingRule.csx +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Health URL Missing Rule - Checks if health URL retrieval failed -/// -public class HealthUrlMissingRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return true; // If no data, consider it missing - - var healthUrlRetrieved = context.Instance.Data.healthUrlRetrieved; - - if (healthUrlRetrieved == null) - return true; // If no retrieval result, consider it missing - - return healthUrlRetrieved == false; - } - catch (Exception) - { - return true; // On error, consider it missing - } - } -} - diff --git a/core/Workflows/discovery/src/HealthUrlRetrievedRule.csx b/core/Workflows/discovery/src/HealthUrlRetrievedRule.csx deleted file mode 100644 index c7bdc31..0000000 --- a/core/Workflows/discovery/src/HealthUrlRetrievedRule.csx +++ /dev/null @@ -1,29 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Health URL Retrieved Rule - Checks if health URL was successfully retrieved -/// -public class HealthUrlRetrievedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var healthUrlRetrieved = context.Instance.Data.healthUrlRetrieved; - - if (healthUrlRetrieved == null) - return false; - - return healthUrlRetrieved == true; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/InitialTransitionRule.csx b/core/Workflows/discovery/src/InitialTransitionRule.csx deleted file mode 100644 index b8e7cfb..0000000 --- a/core/Workflows/discovery/src/InitialTransitionRule.csx +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Initial Transition Rule - Always allows transition from initial state -/// This rule always returns true to allow automatic transition from initial state -/// -public class InitialTransitionRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - // Always allow transition from initial state - // Initial state is the entry point, so transition should always proceed - return true; - } - catch (Exception) - { - // On error, still allow transition to prevent workflow from getting stuck - return true; - } - } -} - diff --git a/core/Workflows/discovery/src/MarkUnhealthyRule.csx b/core/Workflows/discovery/src/MarkUnhealthyRule.csx deleted file mode 100644 index 70bdd8a..0000000 --- a/core/Workflows/discovery/src/MarkUnhealthyRule.csx +++ /dev/null @@ -1,45 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Mark Unhealthy Rule - Checks if domain should be marked as unhealthy -/// This rule checks if health URL is missing or health check failed -/// -public class MarkUnhealthyRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return true; // If no data, consider it unhealthy - - // Check if health URL retrieval failed - var healthUrlRetrieved = context.Instance.Data.healthUrlRetrieved; - if (healthUrlRetrieved == false) - return true; - - // Check if health check failed - var healthCheck = context.Instance.Data.healthCheck; - if (healthCheck != null) - { - var isHealthy = healthCheck.isHealthy; - if (isHealthy == false) - return true; - } - - // Check if markUnhealthy flag is explicitly set - var markUnhealthy = context.Instance.Data.markUnhealthy; - if (markUnhealthy == true) - return true; - - // If none of the unhealthy conditions are met, don't transition - return false; - } - catch (Exception) - { - return true; // On error, consider it unhealthy - } - } -} - diff --git a/core/Workflows/discovery/src/NextPageFetchedRule.csx b/core/Workflows/discovery/src/NextPageFetchedRule.csx deleted file mode 100644 index 42840a8..0000000 --- a/core/Workflows/discovery/src/NextPageFetchedRule.csx +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Next Page Fetched Rule - Checks if next page was successfully fetched -/// -public class NextPageFetchedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - // Always return true - mapping handles the logic via Key - return true; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/NoDomainsRule.csx b/core/Workflows/discovery/src/NoDomainsRule.csx deleted file mode 100644 index 5851e4d..0000000 --- a/core/Workflows/discovery/src/NoDomainsRule.csx +++ /dev/null @@ -1,26 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using BBT.Workflow.Scripting; - -/// -/// No Domains Rule - Checks if no domains to process -/// -public class NoDomainsRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return true; - - var pendingDomains = context.Instance.Data.pendingDomains as List; - return pendingDomains == null || pendingDomains.Count == 0; - } - catch (Exception) - { - return true; - } - } -} - diff --git a/core/Workflows/discovery/src/NoNextRule.csx b/core/Workflows/discovery/src/NoNextRule.csx deleted file mode 100644 index c963272..0000000 --- a/core/Workflows/discovery/src/NoNextRule.csx +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// No Next Rule - Checks if there is no next page (opposite of CheckPaginationRule) -/// -public class NoNextRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return true; - - var nextPageUrl = context.Instance.Data.nextPageUrl?.ToString(); - return string.IsNullOrEmpty(nextPageUrl); - } - catch (Exception) - { - return true; - } - } -} - diff --git a/core/Workflows/discovery/src/PageCompleteRule.csx b/core/Workflows/discovery/src/PageCompleteRule.csx deleted file mode 100644 index e809777..0000000 --- a/core/Workflows/discovery/src/PageCompleteRule.csx +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using BBT.Workflow.Scripting; - -/// -/// Page Complete Rule - Checks if current page processing is complete -/// -public class PageCompleteRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var pendingDomains = context.Instance.Data.pendingDomains as List; - var currentDomainIndex = Convert.ToInt32(context.Instance.Data.currentDomainIndex ?? 0); - - if (pendingDomains == null) - return true; - - return currentDomainIndex >= pendingDomains.Count; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/ProcessPageMapping.csx b/core/Workflows/discovery/src/ProcessPageMapping.csx deleted file mode 100644 index 0474f3d..0000000 --- a/core/Workflows/discovery/src/ProcessPageMapping.csx +++ /dev/null @@ -1,103 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using System.Linq; -using BBT.Workflow.Scripting; - -/// -/// Process Page Mapping - Extracts domains from page items and creates pendingDomains queue -/// -public class ProcessPageMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - // No input handling needed for this mapping - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var items = context.Instance?.Data?.items; - - if (items == null) - { - return new ScriptResponse - { - Key = "no-domains", - Data = new - { - pendingDomains = new List(), - processedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "process", "empty" } - }; - } - - // Initialize result lists if first page - var healthyDomains = context.Instance?.Data?.HealthyDomains as List ?? new List(); - var notHealthyDomains = context.Instance?.Data?.NotHealthyDomains as List ?? new List(); - - // Extract domains from items array - var pendingDomains = new List(); - - // Iterate through items and extract domainName and healthUrl - if (items is IEnumerable itemsEnumerable) - { - foreach (var item in itemsEnumerable) - { - if (item is Dictionary itemDict) - { - var data = itemDict.ContainsKey("data") ? itemDict["data"] : null; - if (data is Dictionary dataDict) - { - var domainName = dataDict.ContainsKey("domainName") ? dataDict["domainName"]?.ToString() : null; - var healthUrl = dataDict.ContainsKey("healthUrl") ? dataDict["healthUrl"]?.ToString() : null; - - if (!string.IsNullOrEmpty(domainName) && !string.IsNullOrEmpty(healthUrl)) - { - pendingDomains.Add(new Dictionary - { - { "domainName", domainName }, - { "healthUrl", healthUrl } - }); - } - } - } - } - } - - // Initialize currentDomainIndex - var currentDomainIndex = 0; - - return new ScriptResponse - { - Key = pendingDomains.Count > 0 ? "to-check-health" : "no-domains", - Data = new - { - pendingDomains = pendingDomains, - currentDomainIndex = currentDomainIndex, - HealthyDomains = healthyDomains, - NotHealthyDomains = notHealthyDomains, - processedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "process", "success" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "process-page-error", - Data = new - { - error = "Exception during page processing", - errorDescription = ex.Message, - processedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "process", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/RegisterDomainLifecycleMapping.csx b/core/Workflows/discovery/src/RegisterDomainLifecycleMapping.csx deleted file mode 100644 index 28f4889..0000000 --- a/core/Workflows/discovery/src/RegisterDomainLifecycleMapping.csx +++ /dev/null @@ -1,128 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Register Domain Lifecycle Mapping - Starts domain workflow instance with domain name as key using StartTask -/// -public class RegisterDomainLifecycleMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var startTask = task as StartTask; - if (startTask == null) - { - throw new InvalidOperationException("Task must be a StartTask"); - } - - var domainName = context.Instance?.Data?.domainName; - var baseUrl = context.Instance?.Data?.baseUrl; - var healthUrl = context.Instance?.Data?.healthUrl; - var appId = context.Instance?.Data?.appId; - - // Set instance key to domainName - // This ensures each domain has its own workflow instance - if (!string.IsNullOrEmpty(domainName?.ToString())) - { - startTask.SetKey(domainName.ToString()); - } - - // Prepare initialization data - // Pass domain information to domain workflow (schema compliant) - startTask.SetBody(new - { - domainName = domainName, - baseUrl = baseUrl, - healthUrl = healthUrl, - appId = appId - }); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "register-domain-lifecycle-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // StartTask returns instanceId on success - if (context.Body?.isSuccess == true) - { - - return new ScriptResponse - { - Key = "domain-lifecycle-started", - Data = new - { - domainRegistration = new - { - success = true, - operation = "register", - registeredAt = DateTime.UtcNow - }, - domainLifecycleStarted = true, - startedAt = DateTime.UtcNow, - status = "DOMAIN_LIFECYCLE_WORKFLOW_STARTED" - }, - Tags = new[] { "domain", "lifecycle", "started", "start", "success" } - }; - } - else - { - return new ScriptResponse - { - Key = "domain-lifecycle-start-failed", - Data = new - { - domainRegistration = new - { - success = false, - operation = "register", - error = "Failed to register domain", - statusCode = context.Body?.statusCode ?? 500, - registeredAt = DateTime.UtcNow - }, - domainLifecycleStarted = false, - error = context.Body?.errorMessage ?? "Failed to start domain lifecycle workflow", - startedAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "lifecycle", "start", "error" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "domain-lifecycle-start-exception", - Data = new - { - domainLifecycleStarted = false, - error = "Exception during domain lifecycle start", - errorDescription = ex.Message, - startedAt = DateTime.UtcNow, - domainRegistration = new - { - success = false, - operation = "register", - error = "Exception during domain registration", - errorDescription = ex.Message, - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "lifecycle", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/RegisterDomainMapping.csx b/core/Workflows/discovery/src/RegisterDomainMapping.csx deleted file mode 100644 index dbe6a50..0000000 --- a/core/Workflows/discovery/src/RegisterDomainMapping.csx +++ /dev/null @@ -1,130 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting.Functions; -/// -/// Register Domain Mapping - Creates new domain in Redis -/// -public class RegisterDomainMapping :ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var domainName = context.Instance?.Data?.domainName; - var baseUrl = context.Instance?.Data?.baseUrl; - var healthUrl = context.Instance?.Data?.healthUrl; - var appId = context.Instance?.Data?.appId; - // var flows = context.Instance?.Data?.flows; - var daprHttpPort = GetConfigValue("DAPR_HTTP_PORT"); - var daprStateStore = GetConfigValue("DAPR_STATE_STORE_NAME"); - string url="http://localhost:"+daprHttpPort+"/v1.0/state/"+daprStateStore; - httpTask.SetUrl(url); - // Prepare domain data for Dapr State Store API - // Dapr State Store expects array of state items - var stateItem = new - { - key = $"domain:{domainName}", - value = new - { - name = domainName, - baseUrl = baseUrl, - healthUrl = healthUrl, - appId = appId, - isHealthy = true, - updatedAt = DateTime.UtcNow.ToString("o"), - // flows = flows ?? new { } - } - }; - - // Set body for HTTP POST request - httpTask.SetBody(new[] { stateItem }); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "register-domain-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // Dapr State Store API returns 204 No Content on success - // Check HTTP status code from context - var statusCode = context.Body?.statusCode ?? 500; - var isSuccess = statusCode >= 200 && statusCode < 300; - - // Successful registration (204 No Content is success for state store) - if (isSuccess || statusCode == 204) - { - return new ScriptResponse - { - Key = "domain-registered", - Data = new - { - domainRegistration = new - { - success = true, - operation = "register", - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "registered", "redis", "success" } - }; - } - // Registration failed - else - { - return new ScriptResponse - { - Key = "domain-registration-failed", - Data = new - { - domainRegistration = new - { - success = false, - operation = "register", - error = "Failed to register domain", - statusCode = statusCode, - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "registration-failed", "redis", "error" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "domain-registration-exception", - Data = new - { - domainRegistration = new - { - success = false, - operation = "register", - error = "Exception during domain registration", - errorDescription = ex.Message, - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/RegisterSuccessRule.csx b/core/Workflows/discovery/src/RegisterSuccessRule.csx deleted file mode 100644 index 4c7438b..0000000 --- a/core/Workflows/discovery/src/RegisterSuccessRule.csx +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Register Success Rule - Checks if domain registration was successful -/// -public class RegisterSuccessRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var domainRegistration = context.Instance.Data.domainRegistration; - - if (domainRegistration == null) - return false; - - // Check if registration was successful and operation is "register" - return domainRegistration.success == true && - domainRegistration.operation?.ToString() == "register"; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/ScheduleHealthCheckMapping.csx b/core/Workflows/discovery/src/ScheduleHealthCheckMapping.csx deleted file mode 100644 index 877b20e..0000000 --- a/core/Workflows/discovery/src/ScheduleHealthCheckMapping.csx +++ /dev/null @@ -1,83 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Schedule Health Check Mapping - Triggers domain-health-check workflow as subprocess -/// -public class ScheduleHealthCheckMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var subProcessTask = task as SubProcessTask; - if (subProcessTask == null) - { - throw new InvalidOperationException("Task must be a SubProcessTask"); - } - - var domainName = context.Instance?.Data?.domainName; - var domainData = context.Instance?.Data?.domainData; - var healthUrl = context.Instance?.Data?.healthUrl; - - // Configure subprocess - subProcessTask.SetKey("domain-health-check"); - subProcessTask.SetVersion("1.0.0"); - - // Prepare subprocess initialization data - // Pass domain information to health check workflow - subProcessTask.SetBody(new - { - domainName = domainName, - healthUrl = healthUrl ?? domainData?.healthUrl, - domainData = domainData - }); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "schedule-health-check-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // SubProcess is fire-and-forget - // Just track that it was initiated - return new ScriptResponse - { - Key = "health-check-triggered", - Data = new - { - healthCheckTriggered = true, - triggeredAt = DateTime.UtcNow, - status = "HEALTH_CHECK_SUBPROCESS_LAUNCHED" - }, - Tags = new[] { "domain", "health-check", "triggered", "subprocess", "success" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "health-check-trigger-exception", - Data = new - { - healthCheckTriggered = false, - error = "Exception during health check trigger", - errorDescription = ex.Message, - triggeredAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "health-check", "exception", "error" } - }; - } - } -} diff --git a/core/Workflows/discovery/src/ScheduleHealthCheckTimerMapping.csx b/core/Workflows/discovery/src/ScheduleHealthCheckTimerMapping.csx deleted file mode 100644 index ed54628..0000000 --- a/core/Workflows/discovery/src/ScheduleHealthCheckTimerMapping.csx +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions.Timer; - -/// -/// Schedule Health Check Timer Mapping - Returns timer schedule for 30 seconds delay -/// -public class ScheduleHealthCheckTimerMapping : ITimerMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - // Return timer schedule for 30 seconds from now - return TimerSchedule.FromDateTime(DateTime.UtcNow.AddSeconds(30)); - } - catch (Exception) - { - // Fallback to 30 seconds on error - return TimerSchedule.FromDateTime(DateTime.UtcNow.AddSeconds(30)); - } - } -} - diff --git a/core/Workflows/discovery/src/ScheduleNextRunMapping.csx b/core/Workflows/discovery/src/ScheduleNextRunMapping.csx deleted file mode 100644 index d11974f..0000000 --- a/core/Workflows/discovery/src/ScheduleNextRunMapping.csx +++ /dev/null @@ -1,71 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Schedule Next Run Mapping - Triggers domain-health-check workflow as subprocess for next execution -/// -public class ScheduleNextRunMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var subProcessTask = task as SubProcessTask; - if (subProcessTask == null) - { - throw new InvalidOperationException("Task must be a SubProcessTask"); - } - - // Configure subprocess to trigger the same workflow - subProcessTask.SetKey("domain-health-check"); - subProcessTask.SetVersion("1.0.0"); - - // Prepare subprocess initialization data (empty for scheduled run) - subProcessTask.SetBody(new { }); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "schedule-next-run-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // SubProcess is fire-and-forget, so we just return success - return new ScriptResponse - { - Key = "scheduled", - Data = new - { - scheduledAt = DateTime.UtcNow, - nextRunIn = "1 hour" - }, - Tags = new[] { "domain", "schedule", "health-check", "success" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "schedule-next-run-error", - Data = new - { - error = "Exception during scheduling", - errorDescription = ex.Message, - scheduledAt = DateTime.UtcNow - }, - Tags = new[] { "domain", "schedule", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/ScheduleNextRunTimerMapping.csx b/core/Workflows/discovery/src/ScheduleNextRunTimerMapping.csx deleted file mode 100644 index c50a31c..0000000 --- a/core/Workflows/discovery/src/ScheduleNextRunTimerMapping.csx +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions.Timer; - -/// -/// Schedule Next Run Timer Mapping - Returns timer schedule for 1 hour delay -/// -public class ScheduleNextRunTimerMapping : ITimerMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - // Return timer schedule for 1 hour from now - return TimerSchedule.FromDateTime(DateTime.UtcNow.AddMinutes(3)); - } - catch (Exception) - { - // Fallback to 1 hour on error - return TimerSchedule.FromDateTime(DateTime.UtcNow.AddMinutes(3)); - } - } -} - diff --git a/core/Workflows/discovery/src/ScheduledRule.csx b/core/Workflows/discovery/src/ScheduledRule.csx deleted file mode 100644 index 8674615..0000000 --- a/core/Workflows/discovery/src/ScheduledRule.csx +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Scheduled Rule - Checks if next run was scheduled -/// -public class ScheduledRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - // Always return true - mapping handles the logic via Key - return true; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/ShouldTriggerHealthCheckRule.csx b/core/Workflows/discovery/src/ShouldTriggerHealthCheckRule.csx deleted file mode 100644 index 4c76aef..0000000 --- a/core/Workflows/discovery/src/ShouldTriggerHealthCheckRule.csx +++ /dev/null @@ -1,22 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Should Trigger Health Check Rule - Checks if health check workflow should be triggered -/// Returns true if healthUrl exists AND (new domain OR healthUrl changed) -/// -public class ShouldTriggerHealthCheckRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - return false; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/SkipHealthCheckRule.csx b/core/Workflows/discovery/src/SkipHealthCheckRule.csx deleted file mode 100644 index 8e3787c..0000000 --- a/core/Workflows/discovery/src/SkipHealthCheckRule.csx +++ /dev/null @@ -1,23 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Skip Health Check Rule - Checks if health check should be skipped -/// Returns true if healthUrl is missing OR (existing domain AND healthUrl didn't change) -/// -public class SkipHealthCheckRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - - return true; - } - catch (Exception) - { - return true; // On error, skip - } - } -} - diff --git a/core/Workflows/discovery/src/ToCheckHealthRule.csx b/core/Workflows/discovery/src/ToCheckHealthRule.csx deleted file mode 100644 index 2f5ae1b..0000000 --- a/core/Workflows/discovery/src/ToCheckHealthRule.csx +++ /dev/null @@ -1,26 +0,0 @@ -using System.Threading.Tasks; -using System.Collections.Generic; -using BBT.Workflow.Scripting; - -/// -/// To Check Health Rule - Checks if should proceed to health check -/// -public class ToCheckHealthRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var pendingDomains = context.Instance.Data.pendingDomains as List; - return pendingDomains != null && pendingDomains.Count > 0; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/ToCheckPaginationRule.csx b/core/Workflows/discovery/src/ToCheckPaginationRule.csx deleted file mode 100644 index c4649b7..0000000 --- a/core/Workflows/discovery/src/ToCheckPaginationRule.csx +++ /dev/null @@ -1,21 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// To Check Pagination Rule - Always allows transition to pagination check -/// -public class ToCheckPaginationRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - return true; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/UpdateDomainLifecycleMapping.csx b/core/Workflows/discovery/src/UpdateDomainLifecycleMapping.csx deleted file mode 100644 index 6cfa4a0..0000000 --- a/core/Workflows/discovery/src/UpdateDomainLifecycleMapping.csx +++ /dev/null @@ -1,135 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Update Domain Lifecycle Mapping - Triggers update transition in existing domain workflow instance using DirectTriggerTask -/// -public class UpdateDomainLifecycleMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var directTriggerTask = task as DirectTriggerTask; - if (directTriggerTask == null) - { - throw new InvalidOperationException("Task must be a DirectTriggerTask"); - } - - var domainName = context.Instance?.Data?.domainName; - var baseUrl = context.Instance?.Data?.baseUrl; - var healthUrl = context.Instance?.Data?.healthUrl; - var appId = context.Instance?.Data?.appId; - - // Get ETag from instance data (from check-domain-exists response) - var eTag = context.Instance?.Data?.instanceETag?.ToString() ?? - context.Instance?.Data?.eTag?.ToString(); - - // Set instance key to domainName - // This will find the existing domain workflow instance - if (!string.IsNullOrEmpty(domainName?.ToString())) - { - directTriggerTask.SetKey(domainName.ToString()); - } - - // Set transition name (already in config, but can be set explicitly) - directTriggerTask.SetTransitionName("update"); - - // Prepare update data - // Pass updated domain information to domain workflow (schema compliant) - // Include ETag for optimistic concurrency control - directTriggerTask.SetBody(new - { - domainName = domainName, - baseUrl = baseUrl, - healthUrl = healthUrl, - appId = appId - }); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "update-domain-lifecycle-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // DirectTriggerTask returns success status - if (context.Body?.isSuccess == true) - { - return new ScriptResponse - { - Key = "domain-lifecycle-update-triggered", - Data = new - { - domainLifecycleUpdateTriggered = true, - triggeredAt = DateTime.UtcNow, - status = "DOMAIN_LIFECYCLE_UPDATE_TRIGGERED", - domainRegistration = new - { - success = true, - operation = "update", - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "lifecycle", "update", "triggered", "direct-trigger", "success" } - }; - } - else - { - return new ScriptResponse - { - Key = "domain-lifecycle-update-failed", - Data = new - { - domainLifecycleUpdateTriggered = false, - error = context.Body?.errorMessage ?? "Failed to trigger domain lifecycle update", - triggeredAt = DateTime.UtcNow, - domainRegistration = new - { - success = false, - operation = "update", - error = "Failed to update cache domain", - statusCode = context.Body?.statusCode ?? 500, - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "lifecycle", "update", "direct-trigger", "error" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "domain-lifecycle-update-exception", - Data = new - { - domainLifecycleUpdateTriggered = false, - error = "Exception during domain lifecycle update trigger", - errorDescription = ex.Message, - triggeredAt = DateTime.UtcNow, - domainRegistration = new - { - success = false, - operation = "update", - error = "Exception during domain update", - errorDescription = ex.Message, - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "lifecycle", "update", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/UpdateDomainMapping.csx b/core/Workflows/discovery/src/UpdateDomainMapping.csx deleted file mode 100644 index 69c49cd..0000000 --- a/core/Workflows/discovery/src/UpdateDomainMapping.csx +++ /dev/null @@ -1,130 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting.Functions; -/// -/// Register Domain Mapping - Creates new domain in Redis -/// -public class RegisterDomainMapping :ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var domainName = context.Instance?.Data?.domainName; - var baseUrl = context.Instance?.Data?.baseUrl; - var healthUrl = context.Instance?.Data?.healthUrl; - var appId = context.Instance?.Data?.appId; - // var flows = context.Instance?.Data?.flows; - var daprHttpPort = GetConfigValue("DAPR_HTTP_PORT"); - var daprStateStore = GetConfigValue("DAPR_STATE_STORE_NAME"); - string url="http://localhost:"+daprHttpPort+"/v1.0/state/"+daprStateStore; - httpTask.SetUrl(url); - // Prepare domain data for Dapr State Store API - // Dapr State Store expects array of state items - var stateItem = new - { - key = $"domain:{domainName}", - value = new - { - name = domainName, - baseUrl = baseUrl, - healthUrl = healthUrl, - appId = appId, - isHealthy = true, - updatedAt = DateTime.UtcNow.ToString("o"), - // flows = flows ?? new { } - } - }; - - // Set body for HTTP POST request - httpTask.SetBody(new[] { stateItem }); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "register-domain-update-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // Dapr State Store API returns 204 No Content on success - // Check HTTP status code from context - var statusCode = context.Body?.statusCode ?? 500; - var isSuccess = statusCode >= 200 && statusCode < 300; - - // Successful registration (204 No Content is success for state store) - if (isSuccess || statusCode == 204) - { - return new ScriptResponse - { - Key = "domain-cache-updated", - Data = new - { - domainRegistration = new - { - success = true, - operation = "update", - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "registered", "redis", "success" } - }; - } - // Registration failed - else - { - return new ScriptResponse - { - Key = "domain-cache-update-failed", - Data = new - { - domainRegistration = new - { - success = false, - operation = "update", - error = "Failed to update cache domain", - statusCode = statusCode, - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "update-failed", "redis", "error" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "domain-update-exception", - Data = new - { - domainRegistration = new - { - success = false, - operation = "update", - error = "Exception during domain update", - errorDescription = ex.Message, - registeredAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/UpdateHealthStatusMapping.csx b/core/Workflows/discovery/src/UpdateHealthStatusMapping.csx deleted file mode 100644 index b98600e..0000000 --- a/core/Workflows/discovery/src/UpdateHealthStatusMapping.csx +++ /dev/null @@ -1,171 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting.Functions; -/// -/// Update Health Status Mapping - Updates health status in Redis, preserving other fields -/// -public class UpdateHealthStatusMapping :ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var domainName = context.Instance?.Data?.domainName; - var domainData = context.Instance?.Data?.domainData; - var healthCheck = context.Instance?.Data?.healthCheck; - - // Determine health status - bool isHealthy = false; - if (healthCheck != null) - { - isHealthy = healthCheck.isHealthy == true; - } - // If no healthCheck data but we have domainData, mark as unhealthy - // This happens when health URL is missing or health check couldn't be performed - else if (domainData != null) - { - isHealthy = false; - } - // If no healthCheck and no domainData, check if we're explicitly marking as unhealthy - else if (context.Instance?.Data?.markUnhealthy == true) - { - isHealthy = false; - } - - // Merge existing domain data with health status update - var updateData = new Dictionary(); - - // Copy existing domain data to preserve all fields - if (domainData != null) - { - if (domainData.name != null) updateData["name"] = domainData.name; - if (domainData.baseUrl != null) updateData["baseUrl"] = domainData.baseUrl; - if (domainData.healthUrl != null) updateData["healthUrl"] = domainData.healthUrl; - if (domainData.appId != null) updateData["appId"] = domainData.appId; - if (domainData.flows != null) updateData["flows"] = domainData.flows; - // Preserve any other fields that might exist - foreach (var prop in domainData.GetType().GetProperties()) - { - var propName = prop.Name; - if (propName != "isHealthy" && propName != "updatedAt" && - propName != "name" && propName != "baseUrl" && - propName != "healthUrl" && propName != "appId" && propName != "flows") - { - var value = prop.GetValue(domainData); - if (value != null) - { - updateData[propName] = value; - } - } - } - } - - // Update only health-related fields - updateData["isHealthy"] = isHealthy; - updateData["updatedAt"] = DateTime.UtcNow.ToString("o"); - - // Ensure name is set - if (domainName != null) - { - updateData["name"] = domainName; - } - - // Prepare state item for Dapr State Store API - var stateItem = new - { - key = $"domain:{domainName}", - value = updateData - }; - - // Set body for HTTP POST request - httpTask.SetBody(new[] { stateItem }); - var daprHttpPort = GetConfigValue("DAPR_HTTP_PORT"); - var daprStateStore = GetConfigValue("DAPR_STATE_STORE_NAME"); - string url="http://localhost:"+daprHttpPort+"/v1.0/state/"+daprStateStore; - httpTask.SetUrl(url); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "update-health-status-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // Dapr State Store API returns 204 No Content on success - var statusCode = context.Body?.statusCode ?? 500; - var isSuccess = statusCode >= 200 && statusCode < 300; - - // Successful update (204 No Content is success for state store) - if (isSuccess || statusCode == 204) - { - return new ScriptResponse - { - Key = "health-status-updated", - Data = new - { - healthStatusUpdate = new - { - success = true, - updatedAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "health-check", "updated", "redis", "success" } - }; - } - // Update failed - else - { - return new ScriptResponse - { - Key = "health-status-update-failed", - Data = new - { - healthStatusUpdate = new - { - success = false, - error = "Failed to update health status", - statusCode = statusCode, - updatedAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "health-check", "update-failed", "redis", "error" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "health-status-update-exception", - Data = new - { - healthStatusUpdate = new - { - success = false, - error = "Exception during health status update", - errorDescription = ex.Message, - updatedAt = DateTime.UtcNow - } - }, - Tags = new[] { "domain", "health-check", "exception", "error" } - }; - } - } -} - diff --git a/core/Workflows/discovery/src/UpdateSuccessRule.csx b/core/Workflows/discovery/src/UpdateSuccessRule.csx deleted file mode 100644 index b8858c6..0000000 --- a/core/Workflows/discovery/src/UpdateSuccessRule.csx +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Update Success Rule - Checks if domain update was successful -/// -public class UpdateSuccessRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var domainRegistration = context.Instance.Data.domainRegistration; - - if (domainRegistration == null) - return false; - - // Check if update was successful and operation is "update" - return domainRegistration.success == true && - domainRegistration.operation?.ToString() == "update"; - } - catch (Exception) - { - return false; - } - } -} - diff --git a/core/Workflows/discovery/src/UpsertFailureRule.csx b/core/Workflows/discovery/src/UpsertFailureRule.csx deleted file mode 100644 index 5f8d50c..0000000 --- a/core/Workflows/discovery/src/UpsertFailureRule.csx +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Upsert Failure Rule - Checks if domain registration/update failed -/// -public class UpsertFailureRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return true; // If no data, consider it a failure - - var domainRegistration = context.Instance.Data.domainRegistration; - - if (domainRegistration == null) - return true; // If no registration result, consider it a failure - - return domainRegistration.success == false; - } - catch (Exception) - { - return true; // On error, consider it a failure - } - } -} - - - diff --git a/core/Workflows/discovery/src/UpsertSuccessRule.csx b/core/Workflows/discovery/src/UpsertSuccessRule.csx deleted file mode 100644 index 4753318..0000000 --- a/core/Workflows/discovery/src/UpsertSuccessRule.csx +++ /dev/null @@ -1,31 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Upsert Success Rule - Checks if domain registration/update was successful -/// -public class UpsertSuccessRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - try - { - if (context?.Instance?.Data == null) - return false; - - var domainRegistration = context.Instance.Data.domainRegistration; - - if (domainRegistration == null) - return false; - - return domainRegistration.success == true; - } - catch (Exception) - { - return false; - } - } -} - - - diff --git a/core/Workflows/error-boundary/.meta/test-error-boundary-flow.diagram.json b/core/Workflows/error-boundary/.meta/test-error-boundary-flow.diagram.json deleted file mode 100644 index f861ecb..0000000 --- a/core/Workflows/error-boundary/.meta/test-error-boundary-flow.diagram.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "nodePos": { - "idle": { - "x": 420, - "y": 340 - }, - "conflict-handled": { - "x": 1200, - "y": 40 - }, - "not-found-handled": { - "x": 1220, - "y": 280 - }, - "validation-handled": { - "x": 1200, - "y": 460 - }, - "failure-handled": { - "x": 1180, - "y": 640 - }, - "error-sink": { - "x": 100, - "y": 100 - }, - "__start__": { - "x": 100, - "y": 340 - } - } -} \ No newline at end of file diff --git a/core/Workflows/error-boundary/src/Trigger400Mapping.csx b/core/Workflows/error-boundary/src/Trigger400Mapping.csx deleted file mode 100644 index 850847c..0000000 --- a/core/Workflows/error-boundary/src/Trigger400Mapping.csx +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Trigger400Mapping - Starts a workflow that has schema validation with an empty body. -/// Missing required fields cause the runtime to return 400 Validation, -/// caught by errorCode "Task:400". -/// -public class Trigger400Mapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var startTask = task as StartTask; - if (startTask == null) - throw new InvalidOperationException("Task must be a StartTask"); - - startTask.SetDomain("core"); - startTask.SetFlow("account-opening-workflow"); - startTask.SetKey(Guid.NewGuid().ToString()); - startTask.SetSync(false); - // Empty body → schema required fields are missing → Validation 400 - startTask.SetBody(new { }); - - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - return new ScriptResponse - { - Key = "trigger-400-handled", - Data = new - { - validationTestResult = new - { - errorCode = "Task:400", - action = "Ignore", - handledAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "validation", "400" } - }; - } -} diff --git a/core/Workflows/error-boundary/src/Trigger404Mapping.csx b/core/Workflows/error-boundary/src/Trigger404Mapping.csx deleted file mode 100644 index cfcc9d3..0000000 --- a/core/Workflows/error-boundary/src/Trigger404Mapping.csx +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Trigger404Mapping - Retrieves a deliberately nonexistent instance (dead UUID). -/// The runtime returns 404 NotFound, caught by errorCode "Task:404". -/// -public class Trigger404Mapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var getTask = task as GetInstanceDataTask; - if (getTask == null) - throw new InvalidOperationException("Task must be a GetInstanceDataTask"); - - getTask.SetDomain("core"); - getTask.SetFlow("task-test-subflow"); - // Nonexistent instance → 404 NotFound - getTask.SetInstance("00000000-dead-beef-0000-000000000000"); - - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - return new ScriptResponse - { - Key = "trigger-404-handled", - Data = new - { - notFoundTestResult = new - { - errorCode = "Task:404", - action = "Ignore", - handledAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "not-found", "404" } - }; - } -} \ No newline at end of file diff --git a/core/Workflows/error-boundary/src/Trigger409Mapping.csx b/core/Workflows/error-boundary/src/Trigger409Mapping.csx deleted file mode 100644 index 7d47389..0000000 --- a/core/Workflows/error-boundary/src/Trigger409Mapping.csx +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Trigger409Mapping - Starts a workflow instance with a fixed key. -/// On the second call the runtime returns 409 Conflict, which the -/// task-level ErrorBoundary catches via errorCode "Task:409". -/// -public class Trigger409Mapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var startTask = task as StartTask; - if (startTask == null) - throw new InvalidOperationException("Task must be a StartTask"); - - startTask.SetDomain("core"); - startTask.SetFlow("task-test-subflow"); - startTask.SetKey("fixed-eb-409-key"); - startTask.SetSync(false); - startTask.SetBody(new { source = "error-boundary-409-test" }); - - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - return new ScriptResponse - { - Key = "trigger-409-handled", - Data = new - { - conflictTestResult = new - { - errorCode = "Task:409", - action = "Ignore", - handledAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "conflict", "409" } - }; - } -} diff --git a/core/Workflows/error-boundary/src/Trigger500Mapping.csx b/core/Workflows/error-boundary/src/Trigger500Mapping.csx deleted file mode 100644 index bc83137..0000000 --- a/core/Workflows/error-boundary/src/Trigger500Mapping.csx +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Trigger500Mapping - Triggers a nonexistent transition on a nil-UUID instance. -/// The runtime returns 500 Failure (invalid state/transition), -/// caught by errorCode "Task:500". A wildcard fallback aborts to "error-sink". -/// -public class Trigger500Mapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var directTrigger = task as DirectTriggerTask; - if (directTrigger == null) - throw new InvalidOperationException("Task must be a DirectTriggerTask"); - - directTrigger.SetDomain("core"); - directTrigger.SetFlow("task-test-subflow"); - directTrigger.SetTransitionName("nonexistent-transition"); - // Nil UUID → instance not found or invalid state → 500 - directTrigger.SetInstance("00000000-0000-0000-0000-000000000000"); - directTrigger.SetKey(Guid.NewGuid().ToString()); - directTrigger.SetSync(false); - directTrigger.SetBody(new { source = "error-boundary-500-test" }); - - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - return new ScriptResponse - { - Key = "trigger-500-handled", - Data = new - { - failureTestResult = new - { - errorCode = "Task:500", - action = "Ignore", - handledAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "failure", "500" } - }; - } -} \ No newline at end of file diff --git a/core/Workflows/error-boundary/test-error-boundary-flow.http b/core/Workflows/error-boundary/test-error-boundary-flow.http deleted file mode 100644 index 0bfcd63..0000000 --- a/core/Workflows/error-boundary/test-error-boundary-flow.http +++ /dev/null @@ -1,87 +0,0 @@ -### ============================================================== -### Test Error Boundary Flow - HTTP Test File -### ============================================================== -### Her transition organik olarak farklı bir statusCode üretir: -### trigger-409 → StartTask + fixed key → 409 Conflict → Ignore -### trigger-404 → GetInstanceData + dead UUID → 404 NotFound → Ignore -### trigger-400 → StartTask + empty body → 400 Validation → Ignore -### trigger-500 → DirectTrigger + nil UUID → 500 Failure → Ignore / Abort→error-sink -### -### Debug için MapLocalResultToInvocationResult'a breakpoint koy ve -### TaskExecutionEngine'deki errorCode match mantığını adım adım izle. -### ============================================================== - -@baseUrl = http://localhost:4201 -@apiVersion = 1 -@domain = core -@workflow = test-error-boundary-flow -@instanceKey = eb-flow-test-{{$timestamp}} - -### ============================================================== -### STEP 1: Start instance → idle state -### ============================================================== - -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start -Content-Type: application/json - -{ - "key": "{{instanceKey}}", - "tags": ["error-boundary-test", "statuscode-test"] -} - -### ============================================================== -### STEP 2: Get current state -### ============================================================== - -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state - -### ============================================================== -### SCENARIO A: trigger-409 — Conflict -### Önce task-test-subflow "fixed-eb-409-key" ile başlatılmış olmalı. -### İkinci tetiklemede 409 üretilir; Task:409 → Ignore → conflict-handled -### ============================================================== - -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/trigger-409 -Content-Type: application/json - -{} - -### ============================================================== -### SCENARIO B: trigger-404 — Not Found -### Dead UUID (00000000-dead-beef-...) ile GetInstanceData çağrılır. -### 404 üretilir; Task:404 → Ignore → not-found-handled -### ============================================================== - -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/trigger-404 -Content-Type: application/json - -{} - -### ============================================================== -### SCENARIO C: trigger-400 — Validation -### account-opening-workflow'a boş body ile StartTask çağrılır. -### 400 üretilir; Task:400 → Ignore → validation-handled -### ============================================================== - -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/trigger-400 -Content-Type: application/json - -{} - -### ============================================================== -### SCENARIO D: trigger-500 — Failure -### Nil UUID instance üzerinde geçersiz transition tetiklenir. -### 500 üretilir; Task:500 → Ignore (logOnly) → failure-handled -### Eğer Task:500 match etmezse wildcard (*) → Abort → error-sink -### ============================================================== - -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/trigger-500 -Content-Type: application/json - -{} - -### ============================================================== -### MONITORING: Final instance data -### ============================================================== - -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data diff --git a/core/Workflows/error-boundary/test-error-boundary-flow.json b/core/Workflows/error-boundary/test-error-boundary-flow.json deleted file mode 100644 index dbaebb6..0000000 --- a/core/Workflows/error-boundary/test-error-boundary-flow.json +++ /dev/null @@ -1,391 +0,0 @@ -{ - "key": "test-error-boundary-flow", - "flow": "sys-flows", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "error-boundary", - "test", - "statuscode", - "trigger-task", - "conflict", - "not-found", - "validation", - "failure" - ], - "attributes": { - "type": "F", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Test Error Boundary Flow" - }, - { - "language": "tr-TR", - "label": "ErrorBoundary Test Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "errorBoundary": { - "onError": [ - { - "action": 5, - "priority": 1000, - "logOnly": true - } - ] - }, - "startTransition": { - "key": "start", - "target": "idle", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start" - }, - { - "language": "tr-TR", - "label": "Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "idle", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Idle - Select Test Scenario" - }, - { - "language": "tr-TR", - "label": "Beklemede - Test Senaryosu Seçin" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "trigger-409", - "target": "conflict-handled", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Conflict (409)" - }, - { - "language": "tr-TR", - "label": "Çakışma Testi (409)" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "test-start-workflow", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/Trigger409Mapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUcmlnZ2VyNDA5TWFwcGluZyAtIFN0YXJ0cyBhIHdvcmtmbG93IGluc3RhbmNlIHdpdGggYSBmaXhlZCBrZXkuCi8vLyBPbiB0aGUgc2Vjb25kIGNhbGwgdGhlIHJ1bnRpbWUgcmV0dXJucyA0MDkgQ29uZmxpY3QsIHdoaWNoIHRoZQovLy8gdGFzay1sZXZlbCBFcnJvckJvdW5kYXJ5IGNhdGNoZXMgdmlhIGVycm9yQ29kZSAiVGFzazo0MDkiLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgVHJpZ2dlcjQwOU1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIHN0YXJ0VGFzayA9IHRhc2sgYXMgU3RhcnRUYXNrOwogICAgICAgIGlmIChzdGFydFRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIFN0YXJ0VGFzayIpOwoKICAgICAgICBzdGFydFRhc2suU2V0RG9tYWluKCJjb3JlIik7CiAgICAgICAgc3RhcnRUYXNrLlNldEZsb3coInRhc2stdGVzdC1zdWJmbG93Iik7CiAgICAgICAgc3RhcnRUYXNrLlNldEtleSgiZml4ZWQtZWItNDA5LWtleSIpOwogICAgICAgIHN0YXJ0VGFzay5TZXRTeW5jKGZhbHNlKTsKICAgICAgICBzdGFydFRhc2suU2V0Qm9keShuZXcgeyBzb3VyY2UgPSAiZXJyb3ItYm91bmRhcnktNDA5LXRlc3QiIH0pOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInRyaWdnZXItNDA5LWhhbmRsZWQiLAogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbmZsaWN0VGVzdFJlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9ICJUYXNrOjQwOSIsCiAgICAgICAgICAgICAgICAgICAgYWN0aW9uID0gIklnbm9yZSIsCiAgICAgICAgICAgICAgICAgICAgaGFuZGxlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJlcnJvci1ib3VuZGFyeS10ZXN0IiwgImNvbmZsaWN0IiwgIjQwOSIgfQogICAgICAgIH07CiAgICB9Cn0K" - }, - "errorBoundary": { - "onError": [ - { - "action": 3, - "errorCodes": [ - "409" - ], - "priority": 1, - "logOnly": true - } - ] - } - } - ] - }, - { - "key": "trigger-404", - "target": "not-found-handled", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Not Found (404)" - }, - { - "language": "tr-TR", - "label": "Bulunamadı Testi (404)" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "test-get-instance-data", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/Trigger404Mapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUcmlnZ2VyNDA0TWFwcGluZyAtIFJldHJpZXZlcyBhIGRlbGliZXJhdGVseSBub25leGlzdGVudCBpbnN0YW5jZSAoZGVhZCBVVUlEKS4KLy8vIFRoZSBydW50aW1lIHJldHVybnMgNDA0IE5vdEZvdW5kLCBjYXVnaHQgYnkgZXJyb3JDb2RlICJUYXNrOjQwNCIuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBUcmlnZ2VyNDA0TWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgZ2V0VGFzayA9IHRhc2sgYXMgR2V0SW5zdGFuY2VEYXRhVGFzazsKICAgICAgICBpZiAoZ2V0VGFzayA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgR2V0SW5zdGFuY2VEYXRhVGFzayIpOwoKICAgICAgICBnZXRUYXNrLlNldERvbWFpbigiY29yZSIpOwogICAgICAgIGdldFRhc2suU2V0RmxvdygidGFzay10ZXN0LXN1YmZsb3ciKTsKICAgICAgICAvLyBOb25leGlzdGVudCBpbnN0YW5jZSDihpIgNDA0IE5vdEZvdW5kCiAgICAgICAgZ2V0VGFzay5TZXRJbnN0YW5jZSgiMDAwMDAwMDAtZGVhZC1iZWVmLTAwMDAtMDAwMDAwMDAwMDAwIik7CgogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBLZXkgPSAidHJpZ2dlci00MDQtaGFuZGxlZCIsCiAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbm90Rm91bmRUZXN0UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gIlRhc2s6NDA0IiwKICAgICAgICAgICAgICAgICAgICBhY3Rpb24gPSAiSWdub3JlIiwKICAgICAgICAgICAgICAgICAgICBoYW5kbGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImVycm9yLWJvdW5kYXJ5LXRlc3QiLCAibm90LWZvdW5kIiwgIjQwNCIgfQogICAgICAgIH07CiAgICB9Cn0=" - }, - "errorBoundary": { - "onError": [ - { - "action": 1, - "errorCodes": [ - "404" - ], - "priority": 1, - "retryPolicy": { - "maxRetries": 3, - "initialDelay": "PT2S", - "backoffType": 1, - "backoffMultiplier": 2, - "maxDelay": "PT6S" - } - } - ] - } - } - ] - }, - { - "key": "trigger-400", - "target": "validation-handled", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Validation (400)" - }, - { - "language": "tr-TR", - "label": "Doğrulama Testi (400)" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "test-start-workflow", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/Trigger400Mapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUcmlnZ2VyNDAwTWFwcGluZyAtIFN0YXJ0cyBhIHdvcmtmbG93IHRoYXQgaGFzIHNjaGVtYSB2YWxpZGF0aW9uIHdpdGggYW4gZW1wdHkgYm9keS4KLy8vIE1pc3NpbmcgcmVxdWlyZWQgZmllbGRzIGNhdXNlIHRoZSBydW50aW1lIHRvIHJldHVybiA0MDAgVmFsaWRhdGlvbiwKLy8vIGNhdWdodCBieSBlcnJvckNvZGUgIlRhc2s6NDAwIi4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFRyaWdnZXI0MDBNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBzdGFydFRhc2sgPSB0YXNrIGFzIFN0YXJ0VGFzazsKICAgICAgICBpZiAoc3RhcnRUYXNrID09IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYSBTdGFydFRhc2siKTsKCiAgICAgICAgc3RhcnRUYXNrLlNldERvbWFpbigiY29yZSIpOwogICAgICAgIHN0YXJ0VGFzay5TZXRGbG93KCJhY2NvdW50LW9wZW5pbmctd29ya2Zsb3ciKTsKICAgICAgICBzdGFydFRhc2suU2V0S2V5KEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCkpOwogICAgICAgIHN0YXJ0VGFzay5TZXRTeW5jKGZhbHNlKTsKICAgICAgICAvLyBFbXB0eSBib2R5IOKGkiBzY2hlbWEgcmVxdWlyZWQgZmllbGRzIGFyZSBtaXNzaW5nIOKGkiBWYWxpZGF0aW9uIDQwMAogICAgICAgIHN0YXJ0VGFzay5TZXRCb2R5KG5ldyB7IH0pOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInRyaWdnZXItNDAwLWhhbmRsZWQiLAogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhbGlkYXRpb25UZXN0UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gIlRhc2s6NDAwIiwKICAgICAgICAgICAgICAgICAgICBhY3Rpb24gPSAiSWdub3JlIiwKICAgICAgICAgICAgICAgICAgICBoYW5kbGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImVycm9yLWJvdW5kYXJ5LXRlc3QiLCAidmFsaWRhdGlvbiIsICI0MDAiIH0KICAgICAgICB9OwogICAgfQp9Cg==" - }, - "errorBoundary": { - "onError": [ - { - "action": 0, - "errorCodes": [ - "400" - ], - "priority": 1, - "logOnly": true - } - ] - } - } - ] - }, - { - "key": "trigger-500", - "target": "failure-handled", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Failure (500)" - }, - { - "language": "tr-TR", - "label": "Hata Testi (500)" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "test-direct-transition", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/Trigger500Mapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUcmlnZ2VyNTAwTWFwcGluZyAtIFRyaWdnZXJzIGEgbm9uZXhpc3RlbnQgdHJhbnNpdGlvbiBvbiBhIG5pbC1VVUlEIGluc3RhbmNlLgovLy8gVGhlIHJ1bnRpbWUgcmV0dXJucyA1MDAgRmFpbHVyZSAoaW52YWxpZCBzdGF0ZS90cmFuc2l0aW9uKSwKLy8vIGNhdWdodCBieSBlcnJvckNvZGUgIlRhc2s6NTAwIi4gQSB3aWxkY2FyZCBmYWxsYmFjayBhYm9ydHMgdG8gImVycm9yLXNpbmsiLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgVHJpZ2dlcjUwME1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIGRpcmVjdFRyaWdnZXIgPSB0YXNrIGFzIERpcmVjdFRyaWdnZXJUYXNrOwogICAgICAgIGlmIChkaXJlY3RUcmlnZ2VyID09IG51bGwpCiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYSBEaXJlY3RUcmlnZ2VyVGFzayIpOwoKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldERvbWFpbigiY29yZSIpOwogICAgICAgIGRpcmVjdFRyaWdnZXIuU2V0RmxvdygidGFzay10ZXN0LXN1YmZsb3ciKTsKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldFRyYW5zaXRpb25OYW1lKCJub25leGlzdGVudC10cmFuc2l0aW9uIik7CiAgICAgICAgLy8gTmlsIFVVSUQg4oaSIGluc3RhbmNlIG5vdCBmb3VuZCBvciBpbnZhbGlkIHN0YXRlIOKGkiA1MDAKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldEluc3RhbmNlKCIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAiKTsKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldEtleShHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpKTsKICAgICAgICBkaXJlY3RUcmlnZ2VyLlNldFN5bmMoZmFsc2UpOwogICAgICAgIGRpcmVjdFRyaWdnZXIuU2V0Qm9keShuZXcgeyBzb3VyY2UgPSAiZXJyb3ItYm91bmRhcnktNTAwLXRlc3QiIH0pOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInRyaWdnZXItNTAwLWhhbmRsZWQiLAogICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZhaWx1cmVUZXN0UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gIlRhc2s6NTAwIiwKICAgICAgICAgICAgICAgICAgICBhY3Rpb24gPSAiSWdub3JlIiwKICAgICAgICAgICAgICAgICAgICBoYW5kbGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImVycm9yLWJvdW5kYXJ5LXRlc3QiLCAiZmFpbHVyZSIsICI1MDAiIH0KICAgICAgICB9OwogICAgfQp9" - }, - "errorBoundary": { - "onError": [ - { - "action": 3, - "errorCodes": [ - "500" - ], - "priority": 1, - "logOnly": true - }, - { - "action": 0, - "errorCodes": [ - "*" - ], - "priority": 999 - } - ] - } - } - ] - } - ] - }, - { - "key": "conflict-handled", - "stateType": 3, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Conflict Handled (409)" - }, - { - "language": "tr-TR", - "label": "Çakışma Yakalandı (409)" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "not-found-handled", - "stateType": 3, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Not Found Handled (404)" - }, - { - "language": "tr-TR", - "label": "Bulunamadı Yakalandı (404)" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "validation-handled", - "stateType": 3, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Validation Handled (400)" - }, - { - "language": "tr-TR", - "label": "Doğrulama Yakalandı (400)" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "failure-handled", - "stateType": 3, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Failure Handled (500)" - }, - { - "language": "tr-TR", - "label": "Hata Yakalandı (500)" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "error-sink", - "stateType": 3, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Error Sink (Unhandled)" - }, - { - "language": "tr-TR", - "label": "Hata Havuzu (Yakalanmadı)" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/morph-touch/absence-entry.json b/core/Workflows/morph-touch/absence-entry.json deleted file mode 100644 index b3b148f..0000000 --- a/core/Workflows/morph-touch/absence-entry.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "key": "absence-entry", - "flow": "sys-flows", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "new" - ], - "attributes": { - "type": "S", - "labels": [ - { - "label": "Absence Entry", - "language": "en-US" - }, - { - "label": "Yokluk Kaydı", - "language": "tr-TR" - } - ], - "functions": [], - "features": [], - "extensions": [], - "cancel": { - "key": "cancel", - "target": "cancelled", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "label": "Cancel", - "language": "en-US" - }, - { - "label": "İptal Et", - "language": "tr-TR" - } - ] - }, - "startTransition": { - "key": "start", - "target": "complete", - "versionStrategy": "Major", - "triggerType": 0, - "labels": [ - { - "label": "Start", - "language": "en-US" - }, - { - "label": "Başla", - "language": "tr-TR" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "complete", - "stateType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "label": "Complete", - "language": "en-US" - }, - { - "label": "Tamamlandı", - "language": "tr-TR" - } - ], - "transitions": [ - { - "key": "update", - "target": "complete", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "label": "Update", - "language": "en-US" - }, - { - "label": "Güncelle", - "language": "tr-TR" - } - ] - }, - { - "key": "start-transfer", - "target": "complete", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "label": "Start Transfer", - "language": "en-US" - }, - { - "label": "Transferi Başlat", - "language": "tr-TR" - } - ], - "rule": { - "location": "./src/CanStartTransferMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIENvbmRpdGlvbiBmb3IgY2hlY2stdGltZTogc3RhdGU9YWN0aXZlIC0+IGNyZWF0ZS1yb29tLWFuZC10cmlnZ2VyLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgQ2FuU3RhcnRUcmFuc2Zlck1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgYWJzZW5jZVR5cGUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5hYnNlbmNlVHlwZT8uVG9TdHJpbmcoKT8uVHJpbSgpOwogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQoYWJzZW5jZVR5cGUgPT0gInBlcnNvbmVsLWxlYXZlIik7CiAgICB9Cn0=" - }, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "domain": "core", - "flow": "sys-tasks", - "key": "start-transfer-from-absence-entry", - "version": "1.0.0" - }, - "mapping": { - "location": "./src/StartTransferFromAbsenceEntryMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CgovLy8gPHN1bW1hcnk+Ci8vLyBNYXBwaW5nIGZvciBzdGFydC10cmFuc2Zlci1mcm9tLWFic2VuY2UtZW50cnkgU3RhcnRUYXNrIChUeXBlIDExKS4KLy8vIENvbmRpdGlvbmFsbHkgc3RhcnRzIGEgcmV6ZXJ2YXRpb24tdHJhbnNmZXIgc3ViZmxvdyB3aGVuIGFic2VuY2VUeXBlIGlzIHBlcnNvbmFsLWxlYXZlLgovLy8gRGV0ZXJtaW5lcyB0cmFuc2ZlciB0eXBlOiBhbm51YWwtbGVhdmUgKGVuZERhdGVUaW1lIHByZXNlbnQpIG9yIHRlcm1pbmF0aW9uIChlbmREYXRlVGltZSBudWxsKS4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFN0YXJ0VHJhbnNmZXJGcm9tQWJzZW5jZUVudHJ5TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgc3RhcnRUYXNrID0gdGFzayBhcyBTdGFydFRhc2s7CiAgICAgICAgaWYgKHN0YXJ0VGFzayA9PSBudWxsKQogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgU3RhcnRUYXNrIik7CgogICAgICAgIHZhciBkYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKICAgICAgICBpZiAoZGF0YSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSB7IERhdGEgPSBuZXcgeyBza2lwcGVkID0gdHJ1ZSwgcmVhc29uID0gIm5vLWluc3RhbmNlLWRhdGEiIH0gfSk7CgogICAgICAgIHZhciBhYnNlbmNlVHlwZSA9IEdldFN0cmluZyhkYXRhLCAiYWJzZW5jZVR5cGUiKTsKICAgICAgICBpZiAoYWJzZW5jZVR5cGUgIT0gInBlcnNvbmFsLWxlYXZlIikKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UgeyBEYXRhID0gbmV3IHsgc2tpcHBlZCA9IHRydWUsIHJlYXNvbiA9ICJub3QtcGVyc29uYWwtbGVhdmUiIH0gfSk7CgogICAgICAgIHZhciBhZHZpc29yID0gR2V0U3RyaW5nKGRhdGEsICJhZHZpc29yIik7CiAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KGFkdmlzb3IpKQogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSB7IERhdGEgPSBuZXcgeyBza2lwcGVkID0gdHJ1ZSwgcmVhc29uID0gIm5vLWFkdmlzb3IiIH0gfSk7CgogICAgICAgIHZhciBzdGFydERhdGVUaW1lID0gR2V0U3RyaW5nKGRhdGEsICJzdGFydERhdGVUaW1lIik7CiAgICAgICAgaWYgKHN0cmluZy5Jc051bGxPckVtcHR5KHN0YXJ0RGF0ZVRpbWUpKQogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSB7IERhdGEgPSBuZXcgeyBza2lwcGVkID0gdHJ1ZSwgcmVhc29uID0gIm5vLXN0YXJ0RGF0ZVRpbWUiIH0gfSk7CgogICAgICAgIHZhciBlbmREYXRlVGltZSA9IEdldFN0cmluZyhkYXRhLCAiZW5kRGF0ZVRpbWUiKTsKCiAgICAgICAgdmFyIGFkdmlzb3JUeXBlID0gRXh0cmFjdEFkdmlzb3JUeXBlKGFkdmlzb3IpOwogICAgICAgIHZhciB0cmFuc2ZlclR5cGUgPSBzdHJpbmcuSXNOdWxsT3JFbXB0eShlbmREYXRlVGltZSkgPyAidGVybWluYXRpb24iIDogImFubnVhbC1sZWF2ZSI7CgogICAgICAgIHZhciBzYWZlU3RhcnQgPSBzdGFydERhdGVUaW1lLlJlcGxhY2UoIjoiLCAiLSIpOwogICAgICAgIHZhciB0cmFuc2ZlcktleSA9ICQidHJhbnNmZXItbGVhdmUte2Fkdmlzb3J9LXtzYWZlU3RhcnR9IjsKCiAgICAgICAgc3RhcnRUYXNrLlNldERvbWFpbigidG91Y2giKTsKICAgICAgICBzdGFydFRhc2suU2V0RmxvdygicmV6ZXJ2YXRpb24tdHJhbnNmZXIiKTsKICAgICAgICBzdGFydFRhc2suU2V0S2V5KHRyYW5zZmVyS2V5KTsKCiAgICAgICAgdmFyIGJvZHkgPSBuZXcgU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD4KICAgICAgICB7CiAgICAgICAgICAgIFsic291cmNlQWR2aXNvcklkIl0gPSBhZHZpc29yLAogICAgICAgICAgICBbImFkdmlzb3JUeXBlIl0gPSBhZHZpc29yVHlwZSwKICAgICAgICAgICAgWyJzdGFydERhdGUiXSA9IHN0YXJ0RGF0ZVRpbWUKICAgICAgICB9OwogICAgICAgIGlmICghc3RyaW5nLklzTnVsbE9yRW1wdHkoZW5kRGF0ZVRpbWUpKQogICAgICAgICAgICBib2R5WyJlbmREYXRlIl0gPSBlbmREYXRlVGltZTsKCiAgICAgICAgc3RhcnRUYXNrLlNldEJvZHkoYm9keSk7CgogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBEYXRhID0gbmV3IHsgc2tpcHBlZCA9IGZhbHNlLCB0cmFuc2ZlclR5cGUsIHRyYW5zZmVyS2V5IH0KICAgICAgICB9KTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHJpdmF0ZSBzdHJpbmcgRXh0cmFjdEFkdmlzb3JUeXBlKHN0cmluZyBhZHZpc29yKQogICAgewogICAgICAgIGlmIChzdHJpbmcuSXNOdWxsT3JFbXB0eShhZHZpc29yKSkgcmV0dXJuIG51bGw7CiAgICAgICAgdmFyIHBhcnRzID0gYWR2aXNvci5TcGxpdCgnLicpOwogICAgICAgIGlmIChwYXJ0cy5MZW5ndGggPj0gMykKICAgICAgICAgICAgcmV0dXJuIHBhcnRzWzFdOwogICAgICAgIGlmIChwYXJ0cy5MZW5ndGggPT0gMikKICAgICAgICAgICAgcmV0dXJuIHBhcnRzWzBdOwogICAgICAgIHJldHVybiBhZHZpc29yOwogICAgfQoKICAgIHByaXZhdGUgc3RyaW5nIEdldFN0cmluZyhkeW5hbWljIG9iaiwgc3RyaW5nIG5hbWUpCiAgICB7CiAgICAgICAgaWYgKG9iaiA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChIYXNQcm9wZXJ0eShvYmosIG5hbWUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgdiA9IEdldFByb3BlcnR5VmFsdWUob2JqLCBuYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiB2Py5Ub1N0cmluZygpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNhdGNoIHsgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9" - } - } - ] - } - ] - }, - { - "key": "cancelled", - "stateType": 3, - "versionStrategy": "Minor", - "labels": [ - { - "label": "Cancelled", - "language": "en-US" - }, - { - "label": "İptal Edildi", - "language": "tr-TR" - } - ] - } - ], - "subFlowType": "S", - "timeout": null - } -} \ No newline at end of file diff --git a/core/Workflows/morph-touch/src/CanStartTransferMapping.csx b/core/Workflows/morph-touch/src/CanStartTransferMapping.csx deleted file mode 100644 index c7a1348..0000000 --- a/core/Workflows/morph-touch/src/CanStartTransferMapping.csx +++ /dev/null @@ -1,14 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Condition for check-time: state=active -> create-room-and-trigger. -/// -public class CanStartTransferMapping : ScriptBase, IConditionMapping -{ - public Task Handler(ScriptContext context) - { - var absenceType = context.Instance?.Data?.absenceType?.ToString()?.Trim(); - return Task.FromResult(absenceType == "personel-leave"); - } -} \ No newline at end of file diff --git a/core/Workflows/morph-touch/src/StartTransferFromAbsenceEntryMapping.csx b/core/Workflows/morph-touch/src/StartTransferFromAbsenceEntryMapping.csx deleted file mode 100644 index c5fe260..0000000 --- a/core/Workflows/morph-touch/src/StartTransferFromAbsenceEntryMapping.csx +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Mapping for start-transfer-from-absence-entry StartTask (Type 11). -/// Conditionally starts a rezervation-transfer subflow when absenceType is personal-leave. -/// Determines transfer type: annual-leave (endDateTime present) or termination (endDateTime null). -/// -public class StartTransferFromAbsenceEntryMapping : ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var startTask = task as StartTask; - if (startTask == null) - throw new InvalidOperationException("Task must be a StartTask"); - - var data = context.Instance?.Data; - if (data == null) - return Task.FromResult(new ScriptResponse { Data = new { skipped = true, reason = "no-instance-data" } }); - - var absenceType = GetString(data, "absenceType"); - if (absenceType != "personal-leave") - return Task.FromResult(new ScriptResponse { Data = new { skipped = true, reason = "not-personal-leave" } }); - - var advisor = GetString(data, "advisor"); - if (string.IsNullOrEmpty(advisor)) - return Task.FromResult(new ScriptResponse { Data = new { skipped = true, reason = "no-advisor" } }); - - var startDateTime = GetString(data, "startDateTime"); - if (string.IsNullOrEmpty(startDateTime)) - return Task.FromResult(new ScriptResponse { Data = new { skipped = true, reason = "no-startDateTime" } }); - - var endDateTime = GetString(data, "endDateTime"); - - var advisorType = ExtractAdvisorType(advisor); - var transferType = string.IsNullOrEmpty(endDateTime) ? "termination" : "annual-leave"; - - var safeStart = startDateTime.Replace(":", "-"); - var transferKey = $"transfer-leave-{advisor}-{safeStart}"; - - startTask.SetDomain("touch"); - startTask.SetFlow("rezervation-transfer"); - startTask.SetKey(transferKey); - - var body = new System.Collections.Generic.Dictionary - { - ["sourceAdvisorId"] = advisor, - ["advisorType"] = advisorType, - ["startDate"] = startDateTime - }; - if (!string.IsNullOrEmpty(endDateTime)) - body["endDate"] = endDateTime; - - startTask.SetBody(body); - - return Task.FromResult(new ScriptResponse - { - Data = new { skipped = false, transferType, transferKey } - }); - } - - public Task OutputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - private string ExtractAdvisorType(string advisor) - { - if (string.IsNullOrEmpty(advisor)) return null; - var parts = advisor.Split('.'); - if (parts.Length >= 3) - return parts[1]; - if (parts.Length == 2) - return parts[0]; - return advisor; - } - - private string GetString(dynamic obj, string name) - { - if (obj == null) return null; - try - { - if (HasProperty(obj, name)) - { - var v = GetPropertyValue(obj, name); - return v?.ToString(); - } - } - catch { } - return null; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/.meta/password-subflow.diagram.json b/core/Workflows/oauth/.meta/password-subflow.diagram.json deleted file mode 100644 index 89868f0..0000000 --- a/core/Workflows/oauth/.meta/password-subflow.diagram.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "nodePos": { - "validate-user-credentials": { - "x": 100, - "y": 200 - }, - "password-success": { - "x": 621, - "y": 100 - }, - "password-failed": { - "x": 621, - "y": 300 - }, - "__start__": { - "x": -296, - "y": 200 - } - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/authorization-code-subflow.json b/core/Workflows/oauth/authorization-code-subflow.json deleted file mode 100644 index d1b0e22..0000000 --- a/core/Workflows/oauth/authorization-code-subflow.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "key": "authorization-code-subflow", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "oauth2", - "authorization-code", - "subflow", - "authentication", - "redirect" - ], - "attributes": { - "type": "S", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Authorization Code Grant Subflow" - }, - { - "language": "tr-TR", - "label": "Authorization Code Grant Alt Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-authorization-code", - "target": "validate-authorization-code", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Authorization Code Flow" - }, - { - "language": "tr-TR", - "label": "Authorization Code Akışını Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "validate-authorization-code", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Validate Authorization Code" - }, - { - "language": "tr-TR", - "label": "Authorization Code Doğrulama" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "validate-authorization-code", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ValidateAuthorizationCodeMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIFZhbGlkYXRlQXV0aG9yaXphdGlvbkNvZGVNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgdmFyIGF1dGhDb2RlRGF0YSA9IG5ldwogICAgICAgIHsKICAgICAgICAgICAgY29kZSA9IGNvbnRleHQuQm9keS5jb2RlLAogICAgICAgICAgICBjbGllbnRJZCA9IGNvbnRleHQuQm9keS5jbGllbnRfaWQsCiAgICAgICAgICAgIGNsaWVudFNlY3JldCA9IGNvbnRleHQuQm9keS5jbGllbnRfc2VjcmV0LAogICAgICAgICAgICByZWRpcmVjdFVyaSA9IGNvbnRleHQuQm9keS5yZWRpcmVjdF91cmksCiAgICAgICAgICAgIGNvZGVWZXJpZmllciA9IGNvbnRleHQuQm9keS5jb2RlX3ZlcmlmaWVyIC8vIFBLQ0UgZm9yIGVuaGFuY2VkIHNlY3VyaXR5CiAgICAgICAgfTsKICAgICAgICBodHRwVGFzay5TZXRCb2R5KGF1dGhDb2RlRGF0YSk7CiAgICAgICAgdmFyIGhlYWRlcnMgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIHN0cmluZz8+CiAgICAgICAgewogICAgICAgICAgICBbIkNvbnRlbnQtVHlwZSJdID0gImFwcGxpY2F0aW9uL2pzb24iLAogICAgICAgICAgICBbIlgtUmVxdWVzdC1JZCJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucmVxdWVzdElkLAogICAgICAgIH07CiAgICAgICAgaHR0cFRhc2suU2V0SGVhZGVycyhoZWFkZXJzKTsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIHJlc3BvbnNlID0gbmV3IFNjcmlwdFJlc3BvbnNlKCk7CiAgICAgICAgdmFyIHN0YXR1c0NvZGUgPSBjb250ZXh0LkJvZHkuc3RhdHVzQ29kZSA/PyA1MDA7CgogICAgICAgIGlmIChzdGF0dXNDb2RlID09IDIwMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3BvbnNlLkRhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXV0aGVudGljYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICB1c2VySWQgPSBjb250ZXh0LkJvZHkuZGF0YT8udXNlcklkLAogICAgICAgICAgICAgICAgICAgIGdyYW50VHlwZSA9ICJhdXRob3JpemF0aW9uX2NvZGUiLAogICAgICAgICAgICAgICAgICAgIHJlZGlyZWN0VXJpID0gY29udGV4dC5Cb2R5LmRhdGE/LnJlZGlyZWN0VXJpLAogICAgICAgICAgICAgICAgICAgIGNvZGVDaGFsbGVuZ2UgPSBjb250ZXh0LkJvZHkuZGF0YT8uY29kZUNoYWxsZW5nZSwKICAgICAgICAgICAgICAgICAgICBjb2RlQ2hhbGxlbmdlTWV0aG9kID0gY29udGV4dC5Cb2R5LmRhdGE/LmNvZGVDaGFsbGVuZ2VNZXRob2QsCiAgICAgICAgICAgICAgICAgICAgaXNWYWxpZGF0aW9uU3VjY2VzcyA9IGNvbnRleHQuQm9keS5kYXRhPy5pc1ZhbGlkLAogICAgICAgICAgICAgICAgICAgIGV4cGlyZXNBdCA9IGNvbnRleHQuQm9keS5kYXRhPy5leHBpcmVzQXQsCiAgICAgICAgICAgICAgICAgICAgYXV0aG9yaXphdGlvbkNvZGUgPSBjb250ZXh0LkJvZHkuZGF0YT8uY29kZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID09IDQwMCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3BvbnNlLkRhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXV0aGVudGljYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiSW52YWxpZCBhdXRob3JpemF0aW9uIGNvZGUiLAogICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9ICJpbnZhbGlkX2dyYW50IgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICByZXNwb25zZS5EYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIlNlcnZlciBlcnJvciBvY2N1cnJlZCIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gInNlcnZlcl9lcnJvciIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXNwb25zZTsKICAgIH0KfQ==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "code-valid", - "target": "authorization-code-success", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authorization Code Valid" - }, - { - "language": "tr-TR", - "label": "Authorization Code Geçerli" - } - ], - "schema": null, - "rule": { - "location": "./src/AuthorizationSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uU3VjY2Vzc1J1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gY29udGV4dC5JbnN0YW5jZS5EYXRhLmF1dGhlbnRpY2F0aW9uLnN1Y2Nlc3MgPT0gdHJ1ZTsKICAgIH0KfQo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "code-invalid", - "target": "authorization-code-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authorization Code Invalid" - }, - { - "language": "tr-TR", - "label": "Authorization Code Geçersiz" - } - ], - "schema": null, - "rule": { - "location": "./src/AuthorizationFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uRmFpbGVkUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEuYXV0aGVudGljYXRpb24uc3VjY2VzcyA9PSBmYWxzZTsKICAgIH0KfQo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "authorization-code-success", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authorization Code Success" - }, - { - "language": "tr-TR", - "label": "Authorization Code Başarılı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "authorization-code-failed", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authorization Code Failed" - }, - { - "language": "tr-TR", - "label": "Authorization Code Başarısız" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/oauth-authentication-workflow.http b/core/Workflows/oauth/oauth-authentication-workflow.http deleted file mode 100644 index e90ef7d..0000000 --- a/core/Workflows/oauth/oauth-authentication-workflow.http +++ /dev/null @@ -1,120 +0,0 @@ -############################################################################### -# OAuth Authentication Workflow - HTTP Test File -# -# This file tests the oauth-authentication workflow which handles OAuth2.0 -# authentication flow including: -# - Password grant type authentication -# - Push notification MFA -# - OTP MFA fallback -# - Token generation -# -# Prerequisites: -# 1. vNext Runtime running on localhost:4201 -# 2. Mockoon running on localhost:3001 -############################################################################### - -@baseUrl = http://localhost:4201 -@apiVersion = 1 -@domain = core -@workflow = oauth-authentication -@instanceKey = oauth-{{$timestamp}} - -############################################################################### -# Step 1: Start OAuth Authentication Workflow -# Initiates the OAuth flow with user credentials -############################################################################### - -### Start OAuth Instance -# @name startOAuthWorkflow -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start?sync=true -Content-Type: application/json -Accept-Language: tr-TR -X-Request-Id: {{$guid}} -X-Device-Id: {{$guid}} -X-Token-Id: {{$guid}} -X-Device-Info: IOS 16 -X-Forwarded-For: 192.168.2.1 - -{ - "key": "{{instanceKey}}", - "tags": [ - "test", - "oauth", - "authentication" - ], - "attributes": { - "username": "112233445566", - "password": "112233", - "grant_type": "password", - "client_id": "acme", - "client_secret": "1q2w3e*", - "scope": "openid profile product-api" - } -} - -############################################################################### -# Step 2: Get Instance Data -# Retrieve current workflow instance data -############################################################################### - -### Get Instance Data -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}} -Content-Type: application/json - -### Get Current State -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -############################################################################### -# Step 3: Push Notification MFA - Approval -# User approves the push notification on their device -############################################################################### - -### Push Send Approval -# @name pushApproved -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/push-approved?sync=true -Content-Type: application/json - -############################################################################### -# Step 3.1: Push Notification MFA - Denied (Alternative) -# User denies the push notification - falls back to OTP -############################################################################### - -### Push Send Denied (Optional - triggers OTP fallback) -# @name pushDenied -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/push-denied?sync=true -Content-Type: application/json - -############################################################################### -# Step 4: Get Current State (Long Polling) -# Check the current state of the workflow -############################################################################### - -### Get Current State -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -############################################################################### -# Step 5: Get Instance Data (Final) -# Retrieve all accumulated data including tokens -############################################################################### - -### Get Final Instance Data -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -############################################################################### -# OAuth Flow Summary -############################################################################### -# -# | Step | Transition | Description | -# |------|--------------------|------------------------------------------| -# | 1 | start | Start with username/password credentials | -# | 2 | (auto) | Validate client and user credentials | -# | 3a | push-approved | User approves push notification | -# | 3b | push-denied | User denies push, fallback to OTP | -# | 4 | (auto) | Generate tokens on successful auth | -# | 5 | (complete) | Workflow completes with tokens | -# -############################################################################### - diff --git a/core/Workflows/oauth/oauth-authentication-workflow.json b/core/Workflows/oauth/oauth-authentication-workflow.json deleted file mode 100644 index 46486db..0000000 --- a/core/Workflows/oauth/oauth-authentication-workflow.json +++ /dev/null @@ -1,840 +0,0 @@ -{ - "key": "oauth-authentication", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "oauth2", - "authentication", - "security", - "mfa", - "grant-types" - ], - "attributes": { - "type": "F", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "OAuth2.0 Authentication Workflow " - }, - { - "language": "tr-TR", - "label": "OAuth2.0 Kimlik Doğrulama İş Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "initiate-auth", - "target": "client-validation", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Initiate Authentication" - }, - { - "language": "tr-TR", - "label": "Kimlik Doğrulama Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "client-validation", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Client Validation" - }, - { - "language": "tr-TR", - "label": "İstemci Doğrulama" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "validate-client", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/HeaderInitialMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gT0F1dGgyIENsaWVudCBWYWxpZGF0aW9uIE1hcHBpbmcgLSBDbGllbnQgdmFsaWRhdGlvbiBtYXBwaW5nCi8vIFRoaXMgbWFwcGluZyBpcyB1c2VkIHRvIHZhbGlkYXRlIE9BdXRoMiBjbGllbnQgY3JlZGVudGlhbHMuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBIZWFkZXJJbml0aWFsTWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gUHJvY2VzcyB0aGUgY2xpZW50IGF1dGhlbnRpY2F0aW9uIHJlc3VsdCBhbmQgbWVyZ2UgaXQgaW50byB0aGUgd29ya2Zsb3cgaW5zdGFuY2UKICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgTG9nSW5mb3JtYXRpb24oIkhlYWRlciBJbml0aWFsIE1hcHBpbmciKTsKICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJoZWFkZXItaW5pdGlhbC1tYXBwaW5nIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSAiaW5pdGlhbC1oZWFkZXIiLAogICAgICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RJZCA9IGNvbnRleHQuSGVhZGVycz9bIngtcmVxdWVzdC1pZCJdLAogICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VJbmZvID0gY29udGV4dC5IZWFkZXJzP1sieC1kZXZpY2UtaW5mbyJdLAogICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VJZCA9IGNvbnRleHQuSGVhZGVycz9bIngtZGV2aWNlLWlkIl0sCiAgICAgICAgICAgICAgICAgICAgICAgIGFjY2VwdExhbmd1YWdlID0gY29udGV4dC5IZWFkZXJzP1siYWNjZXB0LWxhbmd1YWdlIl0sCiAgICAgICAgICAgICAgICAgICAgICAgIGZvcndhcmRlZEZvciA9IGNvbnRleHQuSGVhZGVycz9bIngtZm9yd2FyZGVkLWZvciJdCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgfQp9" - } - }, - { - "order": 2, - "task": { - "key": "validate-client", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ValidateClientMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gT0F1dGgyIENsaWVudCBWYWxpZGF0aW9uIE1hcHBpbmcgLSBDbGllbnQgdmFsaWRhdGlvbiBtYXBwaW5nCi8vIFRoaXMgbWFwcGluZyBpcyB1c2VkIHRvIHZhbGlkYXRlIE9BdXRoMiBjbGllbnQgY3JlZGVudGlhbHMuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBWYWxpZGF0ZUNsaWVudE1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiQ2xpZW50IFZhbGlkYXRpb24gSW5wdXQgSGFuZGxlciIpOwogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiU3RhdHVzOiB7c3RhdHVzfSIsIGFyZ3M6IG5ldyBvYmplY3Q/W10geyBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5zdGF0dXMgfSk7CiAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJSZXF1ZXN0IENsaWVudElkOiB7Q2xpZW50SWR9IiwgYXJnczogbmV3IG9iamVjdD9bXSB7IEdldFByb3BlcnR5VmFsdWU8c3RyaW5nPihjb250ZXh0LkJvZHksICJjbGllbnRfaWQiKSB9KTsKICAgICAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2sgZm9yIGNsaWVudCB2YWxpZGF0aW9uIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFByZXBhcmUgdGhlIHJlcXVlc3QgYm9keSAtIFJlcXVpcmVkIHBhcmFtZXRlcnMgZm9yIE9BdXRoMiBjbGllbnQgdmFsaWRhdGlvbgogICAgICAgICAgICB2YXIgcmVxdWVzdEJvZHkgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2xpZW50X2lkID0gY29udGV4dC5Cb2R5Py5jbGllbnRfaWQsCiAgICAgICAgICAgICAgICBjbGllbnRfc2VjcmV0ID0gY29udGV4dC5Cb2R5Py5jbGllbnRfc2VjcmV0LAogICAgICAgICAgICAgICAgZ3JhbnRfdHlwZSA9IGNvbnRleHQuQm9keT8uZ3JhbnRfdHlwZSwKICAgICAgICAgICAgICAgIHNjb3BlID0gY29udGV4dC5Cb2R5Py5zY29wZSwKICAgICAgICAgICAgICAgIHVzZXJuYW1lID0gY29udGV4dC5Cb2R5Py51c2VybmFtZSwKICAgICAgICAgICAgICAgIHBhc3N3b3JkID0gY29udGV4dC5Cb2R5Py5wYXNzd29yZAogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaHR0cFRhc2suU2V0Qm9keShyZXF1ZXN0Qm9keSk7CgogICAgICAgICAgICAvLyBTZXQgSGVhZGVycwogICAgICAgICAgICB2YXIgaGVhZGVycyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi9qc29uIiwKICAgICAgICAgICAgICAgIFsiWC1Xb3JrZmxvdy1JbnN0YW5jZSJdID0gY29udGV4dC5JbnN0YW5jZT8uSWQuVG9TdHJpbmcoKQogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaHR0cFRhc2suU2V0SGVhZGVycyhoZWFkZXJzKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlICgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHRocm93OwogICAgICAgICAgICAvL3JldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlICgpKTsKICAgICAgICB9CiAgICB9CgogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIFByb2Nlc3MgdGhlIGNsaWVudCBhdXRoZW50aWNhdGlvbiByZXN1bHQgYW5kIG1lcmdlIGl0IGludG8gdGhlIHdvcmtmbG93IGluc3RhbmNlCiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHN0YXR1c0NvZGUgPSBHZXRTdGF0dXNDb2RlRnJvbVJlc3BvbnNlKGNvbnRleHQpOwogICAgICAgICAgICB2YXIgcmVzcG9uc2VEYXRhID0gR2V0UmVzcG9uc2VEYXRhRnJvbUNvbnRleHQoY29udGV4dCk7CgogICAgICAgICAgICAvLyBTdWNjZXNzZnVsIHZlcmlmaWNhdGlvbgogICAgICAgICAgICBpZiAoc3RhdHVzQ29kZSA+PSAyMDAgJiYgc3RhdHVzQ29kZSA8IDMwMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGNsaWVudFZhbGlkYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICBjbGllbnRJZCA9IHJlc3BvbnNlRGF0YT8uY2xpZW50SWQsCiAgICAgICAgICAgICAgICAgICAgZ3JhbnRUeXBlcyA9IHJlc3BvbnNlRGF0YT8uZ3JhbnRUeXBlcywKICAgICAgICAgICAgICAgICAgICByZWRpcmVjdFVyaXMgPSByZXNwb25zZURhdGE/LnJlZGlyZWN0VXJpcywKICAgICAgICAgICAgICAgICAgICBzY29wZXMgPSByZXNwb25zZURhdGE/LnNjb3BlcywKICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZSA9IHJlc3BvbnNlRGF0YT8uaXNBY3RpdmUKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJjbGllbnQtdmFsaWRhdGlvbi1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSAiY2xpZW50LXZhbGlkYXRpb24tc3VjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudFZhbGlkYXRpb24gPSBjbGllbnRWYWxpZGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VJZCA9IGNvbnRleHQuSGVhZGVycz9bIngtZGV2aWNlLWlkIl0sCiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RJZCA9IGNvbnRleHQuSGVhZGVycz9bIngtcmVxdWVzdC1pZCJdLAogICAgICAgICAgICAgICAgICAgICAgICB1c2VyQWdlbnQgPSBjb250ZXh0LkhlYWRlcnM/WyJ1c2VyLWFnZW50Il0sCiAgICAgICAgICAgICAgICAgICAgICAgIGlwQWRkcmVzcyA9IGNvbnRleHQuSGVhZGVycz9bIngtZm9yd2FyZGVkLWZvciJdID8/IGNvbnRleHQuSGVhZGVycz9bIngtcmVhbC1pcCJdCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAib2F1dGgyIiwgImNsaWVudC12YWxpZGF0aW9uIiwgInN1Y2Nlc3MiLCAiYXV0aGVudGljYXRlZCIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvLyBGYWlsZWQgdmVyaWZpY2F0aW9uCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGVycm9ySW5mbyA9IEV4dHJhY3RFcnJvckluZm9ybWF0aW9uKGNvbnRleHQsIHN0YXR1c0NvZGUpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgY2xpZW50VmFsaWRhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICB2YWxpZGF0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGVycm9ySW5mby5tZXNzYWdlLAogICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9IGVycm9ySW5mby5jb2RlLAogICAgICAgICAgICAgICAgICAgIGVycm9yRGVzY3JpcHRpb24gPSBlcnJvckluZm8uZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJjbGllbnQtdmFsaWRhdGlvbi1mYWlsdXJlIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRWYWxpZGF0aW9uID0gY2xpZW50VmFsaWRhdGlvbgogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgIm9hdXRoMiIsICJjbGllbnQtdmFsaWRhdGlvbiIsICJmYWlsdXJlIiwgImVycm9yIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJjbGllbnQtdmFsaWRhdGlvbi1vdXRwdXQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNsaWVudFZhbGlkYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiSW50ZXJuYWwgcHJvY2Vzc2luZyBlcnJvciIsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9ICJwcm9jZXNzaW5nX2Vycm9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JEZXNjcmlwdGlvbiA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHZhbGlkYXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJvYXV0aDIiLCAiY2xpZW50LXZhbGlkYXRpb24iLCAiZXJyb3IiLCAiZXhjZXB0aW9uIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQoKICAgICNyZWdpb24gSGVscGVyIE1ldGhvZHMKCiAgICBwcml2YXRlIHN0YXRpYyBpbnQgR2V0U3RhdHVzQ29kZUZyb21SZXNwb25zZShTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgLy8gR2V0IHN0YXR1cyBjb2RlIGZyb20gc3RhbmRhcmQgcmVzcG9uc2Ugc3RydWN0dXJlCiAgICAgICAgaWYgKGNvbnRleHQuQm9keT8uc3RhdHVzQ29kZSAhPSBudWxsKQogICAgICAgICAgICByZXR1cm4gKGludCljb250ZXh0LkJvZHkuc3RhdHVzQ29kZTsKCiAgICAgICAgLy8gQWNjZXB0IHN1Y2Nlc3MgYnkgZGVmYXVsdAogICAgICAgIHJldHVybiAyMDA7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZHluYW1pYz8gR2V0UmVzcG9uc2VEYXRhRnJvbUNvbnRleHQoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIC8vIEdldCBkYXRhIGZyb20gQm9keQogICAgICAgIGlmIChjb250ZXh0LkJvZHk/LmRhdGEgIT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuQm9keS5kYXRhOwoKICAgICAgICAvLyBEaXJlY3QgYm9keSBjb250ZW50CiAgICAgICAgaWYgKGNvbnRleHQuQm9keSAhPSBudWxsICYmIGNvbnRleHQuQm9keS5zdGF0dXNDb2RlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LkJvZHk7CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIChzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGNvZGUsIHN0cmluZyBkZXNjcmlwdGlvbikgRXh0cmFjdEVycm9ySW5mb3JtYXRpb24oU2NyaXB0Q29udGV4dCBjb250ZXh0LCBpbnQgc3RhdHVzQ29kZSkKICAgIHsKICAgICAgICB2YXIgZXJyb3JEYXRhID0gY29udGV4dC5Cb2R5Py5kYXRhPy5lcnJvciA/PyBudWxsOwogICAgICAgIAogICAgICAgIHN0cmluZyBtZXNzYWdlID0gIkNsaWVudCB2YWxpZGF0aW9uIGZhaWxlZCI7CiAgICAgICAgc3RyaW5nIGNvZGUgPSAiaW52YWxpZF9jbGllbnQiOwogICAgICAgIHN0cmluZyBkZXNjcmlwdGlvbiA9ICJUaGUgY2xpZW50IGNyZWRlbnRpYWxzIHByb3ZpZGVkIGFyZSBpbnZhbGlkIjsKCiAgICAgICAgaWYgKGVycm9yRGF0YSAhPSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9yRGF0YS5tZXNzYWdlID8/IG1lc3NhZ2U7CiAgICAgICAgICAgIGNvZGUgPSBlcnJvckRhdGEuY29kZSA/PyBjb2RlOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9IGVycm9yRGF0YS5kZXNjcmlwdGlvbiA/PyBkZXNjcmlwdGlvbjsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoc3RhdHVzQ29kZSA9PSA0MDEpCiAgICAgICAgewogICAgICAgICAgICBjb2RlID0gInVuYXV0aG9yaXplZF9jbGllbnQiOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJDbGllbnQgYXV0aGVudGljYXRpb24gZmFpbGVkIjsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoc3RhdHVzQ29kZSA9PSA0MDMpCiAgICAgICAgewogICAgICAgICAgICBjb2RlID0gImFjY2Vzc19kZW5pZWQiOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJDbGllbnQgYWNjZXNzIGRlbmllZCI7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHN0YXR1c0NvZGUgPj0gNTAwKQogICAgICAgIHsKICAgICAgICAgICAgY29kZSA9ICJzZXJ2ZXJfZXJyb3IiOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJJbnRlcm5hbCBzZXJ2ZXIgZXJyb3IgZHVyaW5nIGNsaWVudCB2YWxpZGF0aW9uIjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAobWVzc2FnZSwgY29kZSwgZGVzY3JpcHRpb24pOwogICAgfQoKICAgICNlbmRyZWdpb24KfQ==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "client-valid", - "target": "grant-type-selection", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Client Valid" - }, - { - "language": "tr-TR", - "label": "İstemci Geçerli" - } - ], - "schema": null, - "rule": { - "location": "./src/ClientValidRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIENsaWVudCBWYWxpZCBSdWxlIC0gQ2xpZW50IHZhbGlkYXRpb24gc3VjY2VzcyBjb25kaXRpb24gbWFwcGluZwovLy8gVGhpcyBydWxlIGNoZWNrcyBpZiB0aGUgY2xpZW50IHZhbGlkYXRpb24gd2FzIHN1Y2Nlc3NmdWwuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBDbGllbnRWYWxpZFJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gQ2hlY2sgaWYgdGhlIGNsaWVudCB2YWxpZGF0aW9uIHdhcyBzdWNjZXNzZnVsLgogICAgLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgLy8gTnVsbCBjaGVjawogICAgICAgICAgICBpZiAoY29udGV4dD8uSW5zdGFuY2U/LkRhdGEgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDbGllbnQgdmFsaWRhdGlvbiBkYXRhCiAgICAgICAgICAgIHZhciBjbGllbnRWYWxpZGF0aW9uID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmNsaWVudFZhbGlkYXRpb247CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoY2xpZW50VmFsaWRhdGlvbiA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoZSBjbGllbnQgdmFsaWRhdGlvbiB3YXMgc3VjY2Vzc2Z1bC4KICAgICAgICAgICAgcmV0dXJuIGNsaWVudFZhbGlkYXRpb24uc3VjY2VzcyA9PSB0cnVlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgLy8gSWYgYW4gZXhjZXB0aW9uIG9jY3VycywgcmV0dXJuIGZhbHNlIGFuZCB3cml0ZSB0byBhdWRpdCBsb2cKICAgICAgICAgICAgaWYgKGNvbnRleHQ/Lk1ldGFEYXRhICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnRleHQuTWV0YURhdGFbImNsaWVudF92YWxpZF9ydWxlX2Vycm9yIl0gPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgdHlwZSA9IGV4LkdldFR5cGUoKS5OYW1lLAogICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "client-invalid", - "target": "authentication-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Client Invalid" - }, - { - "language": "tr-TR", - "label": "İstemci Geçersiz" - } - ], - "schema": null, - "rule": { - "location": "./src/ClientInvalidRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIENsaWVudCBJbnZhbGlkIFJ1bGUgLSBDbGllbnQgdmFsaWRhdGlvbiBmYWlsdXJlIGNvbmRpdGlvbiBtYXBwaW5nCi8vLyBUaGlzIHJ1bGUgY2hlY2tzIGlmIHRoZSBjbGllbnQgdmFsaWRhdGlvbiB3YXMgc3VjY2Vzc2Z1bC4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIENsaWVudEludmFsaWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIENoZWNrIGlmIHRoZSBjbGllbnQgdmFsaWRhdGlvbiB3YXMgc3VjY2Vzc2Z1bC4KICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIE51bGwgY2hlY2sKICAgICAgICAgICAgaWYgKGNvbnRleHQ/Lkluc3RhbmNlPy5EYXRhID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDbGllbnQgdmFsaWRhdGlvbiBkYXRhCiAgICAgICAgICAgIHZhciBjbGllbnRWYWxpZGF0aW9uID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmNsaWVudFZhbGlkYXRpb247CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoY2xpZW50VmFsaWRhdGlvbiA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGNsaWVudCB2YWxpZGF0aW9uIHdhcyBzdWNjZXNzZnVsLgogICAgICAgICAgICByZXR1cm4gY2xpZW50VmFsaWRhdGlvbi5zdWNjZXNzID09IGZhbHNlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgLy8gRXhjZXB0aW9uIGR1cnVtdW5kYSB0cnVlIGTDtm5kw7xyIChpbnZhbGlkKQogICAgICAgICAgICBpZiAoY29udGV4dD8uTWV0YURhdGEgIT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29udGV4dC5NZXRhRGF0YVsiY2xpZW50X2ludmFsaWRfcnVsZV9lcnJvciJdID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBleC5NZXNzYWdlLAogICAgICAgICAgICAgICAgICAgIHR5cGUgPSBleC5HZXRUeXBlKCkuTmFtZSwKICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXAgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOyAvLyBIYXRhIHZhcnNhIGludmFsaWQga2FidWwgZXQKICAgICAgICB9CiAgICB9Cn0=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "grant-type-selection", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Grant Type Selection" - }, - { - "language": "tr-TR", - "label": "Grant Type Seçimi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "client-credentials-flow", - "target": "token-generation", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Client Credentials Flow" - }, - { - "language": "tr-TR", - "label": "Client Credentials Akışı" - } - ], - "schema": null, - "rule": { - "location": "./src/ClientCredentialsFlowRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBDbGllbnRDcmVkZW50aWFsc0Zsb3dSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnRleHQuSW5zdGFuY2UuRGF0YS5ncmFudF90eXBlID09ICJjbGllbnRfY3JlZGVudGlhbHMiOwogICAgfQp9" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "password-flow", - "target": "password-auth", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Password Flow" - }, - { - "language": "tr-TR", - "label": "Password Akışı" - } - ], - "schema": null, - "rule": { - "location": "./src/PasswordFlowRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBQYXNzd29yZEZsb3dSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnRleHQuSW5zdGFuY2UuRGF0YS5ncmFudF90eXBlID09ICJwYXNzd29yZCI7CiAgICB9Cn0=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "authorization-code-flow", - "target": "authorization-code-auth", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authorization Code Flow" - }, - { - "language": "tr-TR", - "label": "Authorization Code Akışı" - } - ], - "schema": null, - "rule": { - "location": "./src/AuthorizationCodeFlowRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uQ29kZUZsb3dSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnRleHQuSW5zdGFuY2UuRGF0YS5ncmFudF90eXBlID09ICJhdXRob3JpemF0aW9uX2NvZGUiOwogICAgfQp9" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "password-auth", - "stateType": 4, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Password Authentication" - }, - { - "language": "tr-TR", - "label": "Password Kimlik Doğrulama" - } - ], - "view": null, - "subFlow": { - "type": "S", - "process": { - "key": "password-subflow", - "domain": "core", - "version": "1.0.0", - "flow": "sys-flows" - }, - "mapping": { - "location": "./src/PasswordSubflowMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBQYXNzd29yZFN1YmZsb3dNYXBwaW5nIDogSVN1YkZsb3dNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBEYXRhID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLAogICAgICAgICAgICBIZWFkZXJzID0gbnVsbAogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgRGF0YSA9IGNvbnRleHQuQm9keSwKICAgICAgICAgICAgSGVhZGVycyA9IG51bGwKICAgICAgICB9KTsKICAgIH0KfQoKCgoKCg==" - } - }, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "password-success", - "target": "mfa-check", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Password Success - Check MFA" - }, - { - "language": "tr-TR", - "label": "Password Başarılı - MFA Kontrol" - } - ], - "schema": null, - "rule": { - "location": "./src/AuthorizationSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uU3VjY2Vzc1J1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gY29udGV4dC5JbnN0YW5jZS5EYXRhLmF1dGhlbnRpY2F0aW9uLnN1Y2Nlc3MgPT0gdHJ1ZTsKICAgIH0KfQo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "password-failed", - "target": "authentication-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Password Failed" - }, - { - "language": "tr-TR", - "label": "Password Başarısız" - } - ], - "schema": null, - "rule": { - "location": "./src/AuthorizationFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uRmFpbGVkUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEuYXV0aGVudGljYXRpb24uc3VjY2VzcyA9PSBmYWxzZTsKICAgIH0KfQo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "authorization-code-auth", - "stateType": 4, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authorization Code Authentication" - }, - { - "language": "tr-TR", - "label": "Authorization Code Kimlik Doğrulama" - } - ], - "view": null, - "subFlow": { - "type": "S", - "process": { - "key": "authorization-code-subflow", - "domain": "core", - "version": "1.0.0", - "flow": "sys-flows" - }, - "mapping": { - "location": "./src/AuthorizationCodeSubflowMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uQ29kZVN1YmZsb3dNYXBwaW5nIDogSVN1YkZsb3dNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBEYXRhID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLAogICAgICAgICAgICBIZWFkZXJzID0gbnVsbAogICAgICAgIH0pOwogICAgfQoKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgRGF0YSA9IGNvbnRleHQuQm9keSwKICAgICAgICAgICAgSGVhZGVycyA9IG51bGwKICAgICAgICB9KTsKICAgIH0KfQ==" - } - }, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "authorization-code-success", - "target": "mfa-check", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authorization Code Success - Check MFA" - }, - { - "language": "tr-TR", - "label": "Authorization Code Başarılı - MFA Kontrol" - } - ], - "schema": null, - "rule": { - "location": "./src/AuthorizationSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uU3VjY2Vzc1J1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gY29udGV4dC5JbnN0YW5jZS5EYXRhLmF1dGhlbnRpY2F0aW9uLnN1Y2Nlc3MgPT0gdHJ1ZTsKICAgIH0KfQo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "authorization-code-failed", - "target": "authentication-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authorization Code Failed" - }, - { - "language": "tr-TR", - "label": "Authorization Code Başarısız" - } - ], - "schema": null, - "rule": { - "location": "./src/AuthorizationFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uRmFpbGVkUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEuYXV0aGVudGljYXRpb24uc3VjY2VzcyA9PSBmYWxzZTsKICAgIH0KfQo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "mfa-check", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Multi-Factor Authentication Check" - }, - { - "language": "tr-TR", - "label": "Çok Faktörlü Kimlik Doğrulama Kontrolü" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "check-device-registration", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/CheckDeviceRegistrationMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gRGV2aWNlIFJlZ2lzdHJhdGlvbiBDaGVjayBNYXBwaW5nIC0gRGV2aWNlIHJlZ2lzdHJhdGlvbiBzdGF0dXMgY2hlY2sgbWFwcGluZwovLy8gVGhpcyBtYXBwaW5nIGlzIHVzZWQgdG8gY2hlY2sgd2hldGhlciB0aGUgZGV2aWNlIGlzIHJlZ2lzdGVyZWQgZHVyaW5nIHRoZSBNRkEgcHJvY2Vzcy4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIENoZWNrRGV2aWNlUmVnaXN0cmF0aW9uTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIC8vLyA8c3VtbWFyeT4KICAgIC8vLyBQcmVwYXJlIGlucHV0IGZvciBkZXZpY2UgcmVnaXN0cmF0aW9uIGNoZWNrCiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2sgZm9yIGRldmljZSByZWdpc3RyYXRpb24gY2hlY2siKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLy8gR2V0IGluZm9ybWF0aW9uIGZyb20gYXV0aGVudGljYXRpb24gY29udGV4dAogICAgICAgICAgICB2YXIgYXV0aERhdGEgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5hdXRoZW50aWNhdGlvbjsKICAgICAgICAgICAgdmFyIGNsaWVudERhdGEgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5jbGllbnRWYWxpZGF0aW9uOwoKICAgICAgICAgICAgLy8gUXVlcnkgcGFyYW1ldGVycyB0byBiZSBzZW50CiAgICAgICAgICAgIHZhciBxdWVyeVBhcmFtcyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJ1c2VyX2lkIl0gPSBhdXRoRGF0YT8udXNlcklkPy5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgWyJkZXZpY2VfaWQiXSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmRldmljZUlkLAogICAgICAgICAgICAgICAgWyJjbGllbnRfaWQiXSA9IGNsaWVudERhdGE/LmNsaWVudElkPy5Ub1N0cmluZygpID8/IGNsaWVudERhdGE/LmNsaWVudElkPy5Ub1N0cmluZygpCiAgICAgICAgICAgIH07CgogICAgICAgICAgICAvLyBVcGRhdGUgVVJMIHdpdGggcXVlcnkgcGFyYW1ldGVycwogICAgICAgICAgICB2YXIgYmFzZVVybCA9IGh0dHBUYXNrLlVybDsKICAgICAgICAgICAgdmFyIHF1ZXJ5U3RyaW5nID0gc3RyaW5nLkpvaW4oIiYiLCBxdWVyeVBhcmFtcy5XaGVyZShrdnAgPT4gIXN0cmluZy5Jc051bGxPckVtcHR5KGt2cC5WYWx1ZSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5TZWxlY3Qoa3ZwID0+ICQie2t2cC5LZXl9PXtVcmkuRXNjYXBlRGF0YVN0cmluZyhrdnAuVmFsdWUhKX0iKSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KHF1ZXJ5U3RyaW5nKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaHR0cFRhc2suVXJsID0gJCJ7YmFzZVVybH0/e3F1ZXJ5U3RyaW5nfSI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIFNldCBoZWFkZXJzCiAgICAgICAgICAgIHZhciBoZWFkZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbIlgtRGV2aWNlLUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kZXZpY2VJZCwKICAgICAgICAgICAgICAgIFsiWC1SZXF1ZXN0LUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5yZXF1ZXN0SWQsCiAgICAgICAgICAgICAgICBbIlgtV29ya2Zsb3ctSW5zdGFuY2UiXSA9IGNvbnRleHQuSW5zdGFuY2U/LklkLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIkNvbnRlbnQtVHlwZSJdID0gImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKGhlYWRlcnMpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICB9CgogICAgLy8vIDxzdW1tYXJ5PgogICAgLy8vIFByb2Nlc3MgZGV2aWNlIHJlZ2lzdHJhdGlvbiBjaGVjayByZXN1bHQgYW5kIG1lcmdlIGl0IGludG8gdGhlIHdvcmtmbG93IGluc3RhbmNlCiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHN0YXR1c0NvZGUgPSBHZXRTdGF0dXNDb2RlRnJvbVJlc3BvbnNlKGNvbnRleHQpOwogICAgICAgICAgICB2YXIgcmVzcG9uc2VEYXRhID0gR2V0UmVzcG9uc2VEYXRhRnJvbUNvbnRleHQoY29udGV4dCk7CgogICAgICAgICAgICAvLyBTdWNjZXNzZnVsIGNoZWNrCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDwgMzAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgZGV2aWNlUmVnaXN0cmF0aW9uID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIGlzUmVnaXN0ZXJlZCA9IHJlc3BvbnNlRGF0YT8uaXNSZWdpc3RlcmVkID8/IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGRldmljZUlkID0gcmVzcG9uc2VEYXRhPy5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICBkZXZpY2VOYW1lID0gcmVzcG9uc2VEYXRhPy5kZXZpY2VOYW1lLAogICAgICAgICAgICAgICAgICAgIGRldmljZVR5cGUgPSByZXNwb25zZURhdGE/LmRldmljZVR5cGUgPz8gIm1vYmlsZSIsCiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydHNQdXNoID0gcmVzcG9uc2VEYXRhPy5zdXBwb3J0c1B1c2ggPz8gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXJlZEF0ID0gcmVzcG9uc2VEYXRhPy5yZWdpc3RlcmVkQXQsCiAgICAgICAgICAgICAgICAgICAgbGFzdFNlZW5BdCA9IHJlc3BvbnNlRGF0YT8ubGFzdFNlZW5BdAogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlUmVnaXN0cmF0aW9uID0gZGV2aWNlUmVnaXN0cmF0aW9uCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBlcnJvckluZm8gPSBFeHRyYWN0RXJyb3JJbmZvcm1hdGlvbihjb250ZXh0LCBzdGF0dXNDb2RlKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGRldmljZVJlZ2lzdHJhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNoZWNrZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICBpc1JlZ2lzdGVyZWQgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGVycm9ySW5mby5tZXNzYWdlLAogICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9IGVycm9ySW5mby5jb2RlLAogICAgICAgICAgICAgICAgICAgIGVycm9yRGVzY3JpcHRpb24gPSBlcnJvckluZm8uZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUKICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZVJlZ2lzdHJhdGlvbiA9IGRldmljZVJlZ2lzdHJhdGlvbgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRldmljZVJlZ2lzdHJhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICBpc1JlZ2lzdGVyZWQgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiSW50ZXJuYWwgcHJvY2Vzc2luZyBlcnJvciIsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9ICJwcm9jZXNzaW5nX2Vycm9yIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JEZXNjcmlwdGlvbiA9IGV4Lk1lc3NhZ2UKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQoKICAgICNyZWdpb24gSGVscGVyIE1ldGhvZHMKCiAgICBwcml2YXRlIHN0YXRpYyBpbnQgR2V0U3RhdHVzQ29kZUZyb21SZXNwb25zZShTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgaWYgKGNvbnRleHQuQm9keT8uc3RhdHVzQ29kZSAhPSBudWxsKQogICAgICAgICAgICByZXR1cm4gKGludCljb250ZXh0LkJvZHkuc3RhdHVzQ29kZTsKCiAgICAgICAgcmV0dXJuIDIwMDsKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBkeW5hbWljPyBHZXRSZXNwb25zZURhdGFGcm9tQ29udGV4dChTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgaWYgKGNvbnRleHQuQm9keT8uZGF0YSAhPSBudWxsKQogICAgICAgICAgICByZXR1cm4gY29udGV4dC5Cb2R5LmRhdGE7CgogICAgICAgIGlmIChjb250ZXh0LkJvZHkgIT0gbnVsbCAmJiBjb250ZXh0LkJvZHkuc3RhdHVzQ29kZSA9PSBudWxsKQogICAgICAgICAgICByZXR1cm4gY29udGV4dC5Cb2R5OwoKICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIAogICAgcHJpdmF0ZSBzdGF0aWMgKHN0cmluZyBtZXNzYWdlLCBzdHJpbmcgY29kZSwgc3RyaW5nIGRlc2NyaXB0aW9uKSBFeHRyYWN0RXJyb3JJbmZvcm1hdGlvbihTY3JpcHRDb250ZXh0IGNvbnRleHQsIGludCBzdGF0dXNDb2RlKQogICAgewogICAgICAgIHZhciBlcnJvckRhdGEgPSBjb250ZXh0LkJvZHk/LmRhdGE/LmVycm9yID8/IG51bGw7CiAgICAgICAgCiAgICAgICAgc3RyaW5nIG1lc3NhZ2UgPSAiRGV2aWNlIHZhbGlkYXRpb24gZmFpbGVkIjsKICAgICAgICBzdHJpbmcgY29kZSA9ICJpbnZhbGlkX2RldmljZSI7CiAgICAgICAgc3RyaW5nIGRlc2NyaXB0aW9uID0gIlRoZSBkZXZpY2UgY3JlZGVudGlhbHMgcHJvdmlkZWQgYXJlIGludmFsaWQiOwoKICAgICAgICBpZiAoZXJyb3JEYXRhICE9IG51bGwpCiAgICAgICAgewogICAgICAgICAgICBtZXNzYWdlID0gZXJyb3JEYXRhLm1lc3NhZ2UgPz8gbWVzc2FnZTsKICAgICAgICAgICAgY29kZSA9IGVycm9yRGF0YS5jb2RlID8/IGNvZGU7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gZXJyb3JEYXRhLmRlc2NyaXB0aW9uID8/IGRlc2NyaXB0aW9uOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID09IDQwMSkKICAgICAgICB7CiAgICAgICAgICAgIGNvZGUgPSAidW5hdXRob3JpemVkX2RldmljZSI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIkRldmljZSBhdXRoZW50aWNhdGlvbiBmYWlsZWQiOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID09IDQwMykKICAgICAgICB7CiAgICAgICAgICAgIGNvZGUgPSAiYWNjZXNzX2RlbmllZCI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIkRldmljZSBhY2Nlc3MgZGVuaWVkIjsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoc3RhdHVzQ29kZSA+PSA1MDApCiAgICAgICAgewogICAgICAgICAgICBjb2RlID0gInNlcnZlcl9lcnJvciI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIkludGVybmFsIHNlcnZlciBlcnJvciBkdXJpbmcgZGV2aWNlIHZhbGlkYXRpb24iOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIChtZXNzYWdlLCBjb2RlLCBkZXNjcmlwdGlvbik7CiAgICB9CiAgICAKCiAgICAjZW5kcmVnaW9uCn0=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "device-registered-push", - "target": "push-notification-mfa", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Device Registered - Push Notification" - }, - { - "language": "tr-TR", - "label": "Cihaz Kayıtlı - Push Bildirimi" - } - ], - "schema": null, - "rule": { - "location": "./src/DeviceRegisteredPushRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIERldmljZSBSZWdpc3RlcmVkIFB1c2ggUnVsZSAtIERldmljZSByZWdpc3RlcmVkIGFuZCBwdXNoIHN1cHBvcnRlZCBjb25kaXRpb24gbWFwcGluZwovLyBUaGlzIHJ1bGUgY2hlY2tzIHdoZXRoZXIgdGhlIGRldmljZSBpcyByZWdpc3RlcmVkIGFuZCBzdXBwb3J0cyBwdXNoIG5vdGlmaWNhdGlvbnMuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBEZXZpY2VSZWdpc3RlcmVkUHVzaFJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gQ2hlY2sgaWYgdGhlIGRldmljZSBpcyByZWdpc3RlcmVkIGFuZCBzdXBwb3J0cyBwdXNoIG5vdGlmaWNhdGlvbnMKICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIE51bGwgY2hlY2sKICAgICAgICAgICAgaWYgKGNvbnRleHQ/Lkluc3RhbmNlPy5EYXRhID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gR2V0IGRldmljZSByZWdpc3RyYXRpb24gZGF0YQogICAgICAgICAgICB2YXIgZGV2aWNlUmVnaXN0cmF0aW9uID0gY29udGV4dC5JbnN0YW5jZS5EYXRhLmRldmljZVJlZ2lzdHJhdGlvbjsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmIChkZXZpY2VSZWdpc3RyYXRpb24gPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBCYXNpYyByZWdpc3RyYXRpb24gY2hlY2sKICAgICAgICAgICAgdmFyIGlzUmVnaXN0ZXJlZCA9IGRldmljZVJlZ2lzdHJhdGlvbi5pc1JlZ2lzdGVyZWQ7CiAgICAgICAgICAgIGlmIChpc1JlZ2lzdGVyZWQgIT0gdHJ1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBQdXNoIHN1cHBvcnQgY2hlY2sKICAgICAgICAgICAgdmFyIHN1cHBvcnRzUHVzaCA9IGRldmljZVJlZ2lzdHJhdGlvbi5zdXBwb3J0c1B1c2g7CiAgICAgICAgICAgIGlmIChzdXBwb3J0c1B1c2ggIT0gdHJ1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBBZGRpdGlvbmFsIHNlY3VyaXR5IGNoZWNrcwogICAgICAgICAgICAvLyBEZXZpY2UgSUQgY2hlY2sKICAgICAgICAgICAgdmFyIGRldmljZUlkID0gZGV2aWNlUmVnaXN0cmF0aW9uLmRldmljZUlkOwogICAgICAgICAgICBpZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkoZGV2aWNlSWQ/LlRvU3RyaW5nKCkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIExhc3Qgc2VlbiB0aW1lIGNoZWNrICgzMCBkYXlzKQogICAgICAgICAgICAvLyB2YXIgbGFzdFNlZW5BdCA9IGRldmljZVJlZ2lzdHJhdGlvbi5sYXN0U2VlbkF0OwogICAgICAgICAgICAvLyBpZiAobGFzdFNlZW5BdCAhPSBudWxsKQogICAgICAgICAgICAvLyB7CiAgICAgICAgICAgIC8vICAgICBpZiAoRGF0ZVRpbWUuVHJ5UGFyc2UobGFzdFNlZW5BdC5Ub1N0cmluZygpLCBvdXQgRGF0ZVRpbWUgbGFzdFNlZW4pKQogICAgICAgICAgICAvLyAgICAgewogICAgICAgICAgICAvLyAgICAgICAgIGlmIChEYXRlVGltZS5VdGNOb3cuU3VidHJhY3QobGFzdFNlZW4pLlRvdGFsRGF5cyA+IDMwKQogICAgICAgICAgICAvLyAgICAgICAgIHsKICAgICAgICAgICAgLy8gICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAvLyAgICAgICAgIH0KICAgICAgICAgICAgLy8gICAgIH0KICAgICAgICAgICAgLy8gfQoKICAgICAgICAgICAgLy8gLy8gUmVnaXN0cmF0aW9uIHRpbWUgY2hlY2sgKDYgbW9udGhzKQogICAgICAgICAgICAvLyB2YXIgcmVnaXN0ZXJlZEF0ID0gZGV2aWNlUmVnaXN0cmF0aW9uLnJlZ2lzdGVyZWRBdDsKICAgICAgICAgICAgLy8gaWYgKHJlZ2lzdGVyZWRBdCAhPSBudWxsKQogICAgICAgICAgICAvLyB7CiAgICAgICAgICAgIC8vICAgICBpZiAoRGF0ZVRpbWUuVHJ5UGFyc2UocmVnaXN0ZXJlZEF0LlRvU3RyaW5nKCksIG91dCBEYXRlVGltZSByZWdUaW1lKSkKICAgICAgICAgICAgLy8gICAgIHsKICAgICAgICAgICAgLy8gICAgICAgICBpZiAoRGF0ZVRpbWUuVXRjTm93LlN1YnRyYWN0KHJlZ1RpbWUpLlRvdGFsRGF5cyA+IDE4MCkKICAgICAgICAgICAgLy8gICAgICAgICB7CiAgICAgICAgICAgIC8vICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgLy8gICAgICAgICB9CiAgICAgICAgICAgIC8vICAgICB9CiAgICAgICAgICAgIC8vIH0KCiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgLy8gSWYgYW4gZXhjZXB0aW9uIG9jY3VycywgcmV0dXJuIGZhbHNlIGFuZCB3cml0ZSB0byBhdWRpdCBsb2cKICAgICAgICAgICAgaWYgKGNvbnRleHQ/Lk1ldGFEYXRhICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnRleHQuTWV0YURhdGFbImRldmljZV9yZWdpc3RlcmVkX3B1c2hfcnVsZV9lcnJvciJdID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBleC5NZXNzYWdlLAogICAgICAgICAgICAgICAgICAgIHR5cGUgPSBleC5HZXRUeXBlKCkuTmFtZSwKICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXAgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICB9CiAgICB9Cn0=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "device-not-registered-otp", - "target": "otp-mfa", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Device Not Registered - OTP" - }, - { - "language": "tr-TR", - "label": "Cihaz Kayıtlı Değil - OTP" - } - ], - "schema": null, - "rule": { - "location": "./src/DeviceNotRegisteredOtpRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBEZXZpY2VOb3RSZWdpc3RlcmVkT3RwUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZGV2aWNlUmVnaXN0cmF0aW9uLmlzUmVnaXN0ZXJlZCA9PSBmYWxzZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "push-notification-mfa", - "stateType": 4, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push Notification MFA" - }, - { - "language": "tr-TR", - "label": "Push Bildirimi MFA" - } - ], - "view": null, - "subFlow": { - "type": "S", - "process": { - "key": "push-notification-mfa-subflow", - "domain": "core", - "version": "1.0.0", - "flow": "sys-flows" - }, - "mapping": { - "location": "./src/PushNotificationMfaSubflowMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBQdXNoTm90aWZpY2F0aW9uTWZhU3ViZmxvd01hcHBpbmcgOiBJU3ViRmxvd01hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICB7CiAgICAgICAgICAgIERhdGEgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEsCiAgICAgICAgICAgIEhlYWRlcnMgPSBudWxsCiAgICAgICAgfSk7CiAgICB9CgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBEYXRhID0gY29udGV4dC5Cb2R5LAogICAgICAgICAgICBIZWFkZXJzID0gbnVsbAogICAgICAgIH0pOwogICAgfQp9" - } - }, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "push-mfa-success", - "target": "token-generation", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push MFA Success" - }, - { - "language": "tr-TR", - "label": "Push MFA Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/MfaSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBNZmFTdWNjZXNzUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEubWZhLnN1Y2Nlc3MgPT0gdHJ1ZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "push-mfa-failed", - "target": "authentication-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push MFA Failed" - }, - { - "language": "tr-TR", - "label": "Push MFA Başarısız" - } - ], - "schema": null, - "rule": { - "location": "./src/MfaFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBNZmFGYWlsZWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnRleHQuSW5zdGFuY2UuRGF0YS5tZmEuc3VjY2VzcyA9PSBmYWxzZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "otp-mfa", - "stateType": 4, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP Multi-Factor Authentication" - }, - { - "language": "tr-TR", - "label": "OTP Çok Faktörlü Kimlik Doğrulama" - } - ], - "view": null, - "subFlow": { - "type": "S", - "process": { - "key": "otp-mfa-subflow", - "domain": "core", - "version": "1.0.0", - "flow": "sys-flows" - }, - "mapping": { - "location": "./src/OtpMfaSubflowMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBPdHBNZmFTdWJmbG93TWFwcGluZyA6IElTdWJGbG93TWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgRGF0YSA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YSwKICAgICAgICAgICAgSGVhZGVycyA9IG51bGwKICAgICAgICB9KTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICB7CiAgICAgICAgICAgIERhdGEgPSBjb250ZXh0LkJvZHksCiAgICAgICAgICAgIEhlYWRlcnMgPSBudWxsCiAgICAgICAgfSk7CiAgICB9Cn0=" - } - }, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "otp-mfa-success", - "target": "device-registration", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP MFA Success - Register Device" - }, - { - "language": "tr-TR", - "label": "OTP MFA Başarılı - Cihaz Kaydet" - } - ], - "schema": null, - "rule": { - "location": "./src/MfaSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBNZmFTdWNjZXNzUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEubWZhLnN1Y2Nlc3MgPT0gdHJ1ZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "otp-mfa-failed", - "target": "authentication-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP MFA Failed" - }, - { - "language": "tr-TR", - "label": "OTP MFA Başarısız" - } - ], - "schema": null, - "rule": { - "location": "./src/MfaFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBNZmFGYWlsZWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnRleHQuSW5zdGFuY2UuRGF0YS5tZmEuc3VjY2VzcyA9PSBmYWxzZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "device-registration", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Device Registration" - }, - { - "language": "tr-TR", - "label": "Cihaz Kaydı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "register-device", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/RegisterDeviceMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIFJlZ2lzdGVyRGV2aWNlTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgIHZhciBkZXZpY2VEYXRhID0gbmV3CiAgICAgICAgewogICAgICAgICAgICB1c2VySWQgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGE/LmF1dGhlbnRpY2F0aW9uPy51c2VySWQsCiAgICAgICAgICAgIGRldmljZUlkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZGV2aWNlSWQsCiAgICAgICAgICAgIGRldmljZU5hbWUgPSBjb250ZXh0LkJvZHk/LmRldmljZU5hbWUgPz8gIlVua25vd24gRGV2aWNlIiwKICAgICAgICAgICAgZGV2aWNlVHlwZSA9IGNvbnRleHQuQm9keT8uZGV2aWNlVHlwZSA/PyAibW9iaWxlIiwKICAgICAgICAgICAgc3VwcG9ydHNQdXNoID0gdHJ1ZQogICAgICAgIH07CiAgICAgICAgaHR0cFRhc2suU2V0Qm9keShkZXZpY2VEYXRhKTsKICAgICAgICB2YXIgaGVhZGVycyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICB7CiAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIKICAgICAgICB9OwogICAgICAgIGh0dHBUYXNrLlNldEhlYWRlcnMoaGVhZGVycyk7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICB7CiAgICAgICAgICAgIERhdGEgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEsCiAgICAgICAgICAgIEhlYWRlcnMgPSBudWxsCiAgICAgICAgfSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciByZXNwb25zZSA9IG5ldyBTY3JpcHRSZXNwb25zZSgpOwogICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5LnN0YXR1c0NvZGUgPz8gNTAwOwoKICAgICAgICBpZiAoc3RhdHVzQ29kZSA9PSAyMDAgfHwgc3RhdHVzQ29kZSA9PSAyMDEpCiAgICAgICAgewogICAgICAgICAgICByZXNwb25zZS5EYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRldmljZVJlZ2lzdHJhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgIGRldmljZUlkID0gY29udGV4dC5Cb2R5LmRhdGE/LmRldmljZUlkLAogICAgICAgICAgICAgICAgICAgIGlzUmVnaXN0ZXJlZCA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgc3VwcG9ydHNQdXNoID0gdHJ1ZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICByZXNwb25zZS5EYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRldmljZVJlZ2lzdHJhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJEZXZpY2UgcmVnaXN0cmF0aW9uIGZhaWxlZCIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXNwb25zZTsKICAgIH0KfQ==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "device-registered", - "target": "token-generation", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Device Registered Successfully" - }, - { - "language": "tr-TR", - "label": "Cihaz Başarıyla Kaydedildi" - } - ], - "schema": null, - "rule": { - "location": "./src/DeviceRegisteredRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBEZXZpY2VSZWdpc3RlcmVkUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEuZGV2aWNlUmVnaXN0cmF0aW9uLnN1Y2Nlc3MgPT0gdHJ1ZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "token-generation", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Token Generation" - }, - { - "language": "tr-TR", - "label": "Token Oluşturma" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "generate-tokens", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/GenerateTokensMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gR2VuZXJhdGUgVG9rZW5zIE1hcHBpbmcgLSBPQXV0aDIgdG9rZW4gZ2VuZXJhdGlvbiBtYXBwaW5nCi8vIFRoaXMgbWFwcGluZyBpcyB1c2VkIHRvIGdlbmVyYXRlIGFjY2VzcyBhbmQgcmVmcmVzaCB0b2tlbnMgYWZ0ZXIgdGhlIGF1dGhlbnRpY2F0aW9uIHByb2Nlc3MgaXMgY29tcGxldGUuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBHZW5lcmF0ZVRva2Vuc01hcHBpbmcgOiBJTWFwcGluZwp7CiAgICAvLy8gPHN1bW1hcnk+CiAgICAvLy8gUHJlcGFyaW5nIGlucHV0IGZvciB0b2tlbiBjcmVhdGlvbiByZXF1ZXN0CiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2sgZm9yIHRva2VuIGdlbmVyYXRpb24iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gR2F0aGVyIGFsbCBpbmZvcm1hdGlvbiBmcm9tIHRoZSB3b3JrZmxvdyBjb250ZXh0CiAgICAgICAgICAgIHZhciBjbGllbnREYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uY2xpZW50VmFsaWRhdGlvbjsKICAgICAgICAgICAgdmFyIGF1dGhEYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uYXV0aGVudGljYXRpb247CiAgICAgICAgICAgIHZhciBtZmFEYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ubWZhOwogICAgICAgICAgICB2YXIgZGV2aWNlRGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmRldmljZVJlZ2lzdHJhdGlvbjsKCiAgICAgICAgICAgIC8vIFRva2VuIGdlbmVyYXRpb24gcmVxdWVzdCBib2R5CiAgICAgICAgICAgIHZhciByZXF1ZXN0Qm9keSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBDbGllbnQgaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgIGNsaWVudF9pZCA9IGNsaWVudERhdGE/LmNsaWVudElkLAogICAgICAgICAgICAgICAgY2xpZW50X3NlY3JldCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmNsaWVudF9zZWNyZXQsCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vIEdyYW50IHR5cGUgYW5kIHVzZXIgaW5mb3JtYXRpb24KICAgICAgICAgICAgICAgIGdyYW50X3R5cGUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5ncmFudF90eXBlLAogICAgICAgICAgICAgICAgdXNlcl9pZCA9IGF1dGhEYXRhPy51c2VySWQsCiAgICAgICAgICAgICAgICB1c2VybmFtZSA9IGF1dGhEYXRhPy51c2VybmFtZSwKICAgICAgICAgICAgICAgIGVtYWlsID0gYXV0aERhdGE/LmVtYWlsLAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBTY29wZSB2ZSBwZXJtaXNzaW9ucwogICAgICAgICAgICAgICAgc2NvcGUgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5zY29wZSwKICAgICAgICAgICAgICAgIHVzZXJfcm9sZXMgPSBhdXRoRGF0YT8ucm9sZXMgPz8gbmV3W10geyAicmV0YWlsLXVzZXIiIH0sIAogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBEZXZpY2UgY29udGV4dAogICAgICAgICAgICAgICAgZGV2aWNlX2lkID0gZGV2aWNlRGF0YT8uZGV2aWNlSWQsCiAgICAgICAgICAgICAgICBkZXZpY2VfcmVnaXN0ZXJlZCA9IGRldmljZURhdGE/LmlzUmVnaXN0ZXJlZCwKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgLy8gTUZBIGNvbnRleHQKICAgICAgICAgICAgICAgIG1mYV9jb21wbGV0ZWQgPSBtZmFEYXRhPy5zdWNjZXNzID8/IGZhbHNlLAogICAgICAgICAgICAgICAgbWZhX21ldGhvZCA9IG1mYURhdGE/Lm1ldGhvZCA/PyAibm9uZSIsCiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8vIFNlY3VyaXR5IGNvbnRleHQKICAgICAgICAgICAgICAgIGlwX2FkZHJlc3MgPSBjb250ZXh0LkhlYWRlcnM/WyJ4LWZvcndhcmRlZC1mb3IiXSA/PyBjb250ZXh0LkhlYWRlcnM/WyJ4LXJlYWwtaXAiXSwKICAgICAgICAgICAgICAgIHVzZXJfYWdlbnQgPSBjb250ZXh0LkhlYWRlcnM/WyJ1c2VyLWFnZW50Il0KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGh0dHBUYXNrLlNldEJvZHkocmVxdWVzdEJvZHkpOwoKICAgICAgICAgICAgLy8gU2V0IEhlYWRlcnMKICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIHN0cmluZz8+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFsiWC1SZXF1ZXN0LUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5kZXZpY2VJZCwKICAgICAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgICAgICBbIlgtV29ya2Zsb3ctSW5zdGFuY2UiXSA9IGNvbnRleHQuSW5zdGFuY2U/LklkLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIlgtVXNlci1JZCJdID0gcmVxdWVzdEJvZHkudXNlcl9pZD8uVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIFsiWC1EZXZpY2UtSWQiXSA9IHJlcXVlc3RCb2R5LmRldmljZV9pZCwKICAgICAgICAgICAgICAgIFsiWC1HcmFudC1UeXBlIl0gPSByZXF1ZXN0Qm9keS5ncmFudF90eXBlCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKGhlYWRlcnMpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAidG9rZW4tZ2VuZXJhdGlvbi1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBleC5NZXNzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICB0eXBlID0gZXguR2V0VHlwZSgpLk5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgd29ya2Zsb3dfaW5zdGFuY2UgPSBjb250ZXh0Lkluc3RhbmNlPy5JZAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAib2F1dGgyIiwgInRva2VuLWdlbmVyYXRpb24iLCAiaW5wdXQtZXJyb3IiIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIC8vLyA8c3VtbWFyeT4KICAgLy8vIFByb2Nlc3MgdGhlIHRva2VuIGNyZWF0aW9uIHJlc3VsdCBhbmQgbWVyZ2UgaXQgaW50byB0aGUgd29ya2Zsb3cgaW5zdGFuY2UKICAgIC8vLyA8L3N1bW1hcnk+CiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgc3RhdHVzQ29kZSA9IEdldFN0YXR1c0NvZGVGcm9tUmVzcG9uc2UoY29udGV4dCk7CiAgICAgICAgICAgIHZhciByZXNwb25zZURhdGEgPSBHZXRSZXNwb25zZURhdGFGcm9tQ29udGV4dChjb250ZXh0KTsKCiAgICAgICAgICAgLy8gU3VjY2Vzc2Z1bCB0b2tlbiBnZW5lcmF0aW9uCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDwgMzAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB2YXIgdG9rZW5zID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgZ2VuZXJhdGVkX2F0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIGFjY2Vzc190b2tlbiA9IHJlc3BvbnNlRGF0YT8uYWNjZXNzX3Rva2VuLAogICAgICAgICAgICAgICAgICAgIHJlZnJlc2hfdG9rZW4gPSByZXNwb25zZURhdGE/LnJlZnJlc2hfdG9rZW4sCiAgICAgICAgICAgICAgICAgICAgdG9rZW5fdHlwZSA9IHJlc3BvbnNlRGF0YT8udG9rZW5fdHlwZSA/PyAiQmVhcmVyIiwKICAgICAgICAgICAgICAgICAgICBleHBpcmVzX2luID0gcmVzcG9uc2VEYXRhPy5leHBpcmVzX2luLAogICAgICAgICAgICAgICAgICAgIHNjb3BlID0gcmVzcG9uc2VEYXRhPy5zY29wZQogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gInRva2VuLWdlbmVyYXRpb24tc3VjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW5zID0gdG9rZW5zCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAib2F1dGgyIiwgInRva2VuLWdlbmVyYXRpb24iLCAic3VjY2VzcyIsICJhdXRoZW50aWNhdGlvbi1jb21wbGV0ZWQiLCAidG9rZW5zLWlzc3VlZCIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHZhciBlcnJvckluZm8gPSBFeHRyYWN0RXJyb3JJbmZvcm1hdGlvbihjb250ZXh0LCBzdGF0dXNDb2RlKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIHRva2VucyA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBnZW5lcmF0ZWRfYXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBlcnJvckluZm8ubWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICBlcnJvcl9jb2RlID0gZXJyb3JJbmZvLmNvZGUsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JfZGVzY3JpcHRpb24gPSBlcnJvckluZm8uZGVzY3JpcHRpb24sCiAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgIC8vIE1ldGFkYXRhCiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdF9pZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmRldmljZUlkCiAgICAgICAgICAgICAgICB9OwoKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAidG9rZW4tZ2VuZXJhdGlvbi1mYWlsdXJlIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0b2tlbnMgPSB0b2tlbnMKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJvYXV0aDIiLCAidG9rZW4tZ2VuZXJhdGlvbiIsICJmYWlsdXJlIiwgImVycm9yIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXV0aGVudGljYXRpb24tZmFpbGVkIiwgInRva2Vucy1ub3QtaXNzdWVkIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJ0b2tlbi1nZW5lcmF0aW9uLW91dHB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdG9rZW5zID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkludGVybmFsIHByb2Nlc3NpbmcgZXJyb3IiLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl9jb2RlID0gInByb2Nlc3NpbmdfZXJyb3IiLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl9kZXNjcmlwdGlvbiA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGdlbmVyYXRlZF9hdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAib2F1dGgyIiwgInRva2VuLWdlbmVyYXRpb24iLCAiZXJyb3IiLCAiZXhjZXB0aW9uIiwgInByb2Nlc3NpbmctZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9CgogICAgI3JlZ2lvbiBIZWxwZXIgTWV0aG9kcwoKICAgIHByaXZhdGUgc3RhdGljIGludCBHZXRTdGF0dXNDb2RlRnJvbVJlc3BvbnNlKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICBpZiAoY29udGV4dC5Cb2R5Py5zdGF0dXNDb2RlICE9IG51bGwpCiAgICAgICAgICAgIHJldHVybiAoaW50KWNvbnRleHQuQm9keS5zdGF0dXNDb2RlOwoKICAgICAgICByZXR1cm4gMjAwOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIGR5bmFtaWM/IEdldFJlc3BvbnNlRGF0YUZyb21Db250ZXh0KFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICBpZiAoY29udGV4dC5Cb2R5Py5kYXRhICE9IG51bGwpCiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LkJvZHkuZGF0YTsKCiAgICAgICAgaWYgKGNvbnRleHQuQm9keSAhPSBudWxsICYmIGNvbnRleHQuQm9keS5zdGF0dXNDb2RlID09IG51bGwpCiAgICAgICAgICAgIHJldHVybiBjb250ZXh0LkJvZHk7CgogICAgICAgIHJldHVybiBudWxsOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIChzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGNvZGUsIHN0cmluZyBkZXNjcmlwdGlvbikgRXh0cmFjdEVycm9ySW5mb3JtYXRpb24oU2NyaXB0Q29udGV4dCBjb250ZXh0LCBpbnQgc3RhdHVzQ29kZSkKICAgIHsKICAgICAgICB2YXIgZXJyb3JEYXRhID0gY29udGV4dC5Cb2R5Py5lcnJvciA/PyBjb250ZXh0LkJvZHk/LmRhdGE/LmVycm9yOwogICAgICAgIAogICAgICAgIHN0cmluZyBtZXNzYWdlID0gIlRva2VuIGdlbmVyYXRpb24gZmFpbGVkIjsKICAgICAgICBzdHJpbmcgY29kZSA9ICJ0b2tlbl9nZW5lcmF0aW9uX2Vycm9yIjsKICAgICAgICBzdHJpbmcgZGVzY3JpcHRpb24gPSAiVW5hYmxlIHRvIGdlbmVyYXRlIGFjY2VzcyB0b2tlbnMiOwoKICAgICAgICBpZiAoZXJyb3JEYXRhICE9IG51bGwpCiAgICAgICAgewogICAgICAgICAgICBtZXNzYWdlID0gZXJyb3JEYXRhLm1lc3NhZ2UgPz8gZXJyb3JEYXRhLmVycm9yID8/IG1lc3NhZ2U7CiAgICAgICAgICAgIGNvZGUgPSBlcnJvckRhdGEuY29kZSA/PyBlcnJvckRhdGEuZXJyb3JfY29kZSA/PyBjb2RlOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9IGVycm9yRGF0YS5kZXNjcmlwdGlvbiA/PyBlcnJvckRhdGEuZXJyb3JfZGVzY3JpcHRpb24gPz8gZGVzY3JpcHRpb247CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHN0YXR1c0NvZGUgPT0gNDAwKQogICAgICAgIHsKICAgICAgICAgICAgY29kZSA9ICJpbnZhbGlkX3JlcXVlc3QiOwogICAgICAgICAgICBkZXNjcmlwdGlvbiA9ICJJbnZhbGlkIHRva2VuIGdlbmVyYXRpb24gcmVxdWVzdCI7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHN0YXR1c0NvZGUgPT0gNDAxKQogICAgICAgIHsKICAgICAgICAgICAgY29kZSA9ICJpbnZhbGlkX2NsaWVudCI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIkNsaWVudCBhdXRoZW50aWNhdGlvbiBmYWlsZWQgZHVyaW5nIHRva2VuIGdlbmVyYXRpb24iOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID09IDQwMykKICAgICAgICB7CiAgICAgICAgICAgIGNvZGUgPSAiYWNjZXNzX2RlbmllZCI7CiAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIkFjY2VzcyBkZW5pZWQgZm9yIHRva2VuIGdlbmVyYXRpb24iOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdGF0dXNDb2RlID49IDUwMCkKICAgICAgICB7CiAgICAgICAgICAgIGNvZGUgPSAic2VydmVyX2Vycm9yIjsKICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAiSW50ZXJuYWwgc2VydmVyIGVycm9yIGR1cmluZyB0b2tlbiBnZW5lcmF0aW9uIjsKICAgICAgICB9CgogICAgICAgIHJldHVybiAobWVzc2FnZSwgY29kZSwgZGVzY3JpcHRpb24pOwogICAgfQoKICAgICNlbmRyZWdpb24KfQ==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "tokens-generated", - "target": "authentication-success", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Tokens Generated Successfully" - }, - { - "language": "tr-TR", - "label": "Token'lar Başarıyla Oluşturuldu" - } - ], - "schema": null, - "rule": { - "location": "./src/TokensGeneratedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBUb2tlbnNHZW5lcmF0ZWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnRleHQuSW5zdGFuY2UuRGF0YS50b2tlbnMuc3VjY2VzcyA9PSB0cnVlOwogICAgfQp9" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "token-generation-failed", - "target": "authentication-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Token Generation Failed" - }, - { - "language": "tr-TR", - "label": "Token Oluşturma Başarısız" - } - ], - "schema": null, - "rule": { - "location": "./src/TokenGenerationFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBUb2tlbkdlbmVyYXRpb25GYWlsZWRSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnRleHQuSW5zdGFuY2UuRGF0YS50b2tlbnMuc3VjY2VzcyA9PSBmYWxzZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "authentication-success", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authentication Successful" - }, - { - "language": "tr-TR", - "label": "Kimlik Doğrulama Başarılı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "authentication-failed", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Authentication Failed" - }, - { - "language": "tr-TR", - "label": "Kimlik Doğrulama Başarısız" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/otp-mfa-subflow.json b/core/Workflows/oauth/otp-mfa-subflow.json deleted file mode 100644 index 6271bcc..0000000 --- a/core/Workflows/oauth/otp-mfa-subflow.json +++ /dev/null @@ -1,357 +0,0 @@ -{ - "key": "otp-mfa-subflow", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "oauth2", - "mfa", - "otp", - "subflow", - "two-factor" - ], - "attributes": { - "type": "S", - "timeout": { - "key": "otp-timeout", - "target": "otp-expired", - "versionStrategy": "Minor", - "timer": { - "reset": "OnEntry", - "duration": "PT5M" - } - }, - "labels": [ - { - "language": "en-US", - "label": "OTP Multi-Factor Authentication Subflow" - }, - { - "language": "tr-TR", - "label": "OTP Çok Faktörlü Kimlik Doğrulama Alt Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-otp-mfa", - "target": "send-otp", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start OTP MFA" - }, - { - "language": "tr-TR", - "label": "OTP MFA Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "send-otp", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Send OTP Code" - }, - { - "language": "tr-TR", - "label": "OTP Kodu Gönder" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "send-otp-notification", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/SendOtpNotificationMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIFNlbmRPdHBOb3RpZmljYXRpb25NYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgdmFyIG90cERhdGEgPSBuZXcKICAgICAgICB7CiAgICAgICAgICAgIHVzZXJJZCA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YT8uYXV0aGVudGljYXRpb24/LnVzZXJJZCwKICAgICAgICAgICAgZW1haWwgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGE/LmF1dGhlbnRpY2F0aW9uPy5lbWFpbCwKICAgICAgICAgICAgcGhvbmUgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGE/LmF1dGhlbnRpY2F0aW9uPy5waG9uZSwKICAgICAgICAgICAgbWV0aG9kID0gInNtcyIsIC8vIERlZmF1bHQgdG8gc21zLCBjYW4gYmUgInNtcyIgb3IgImVtYWlsIgogICAgICAgICAgICBkZXZpY2VJZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LmRldmljZUlkLAogICAgICAgICAgICBsYW5ndWFnZSA9IGNvbnRleHQuSGVhZGVyc1siYWNjZXB0LWxhbmd1YWdlIl0gPz8gImVuLVVTIgogICAgICAgIH07CiAgICAgICAgaHR0cFRhc2suU2V0Qm9keShvdHBEYXRhKTsKICAgICAgICB2YXIgaGVhZGVycyA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICB7CiAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgIFsiWC1SZXF1ZXN0LUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy5yZXF1ZXN0SWQsCiAgICAgICAgICAgIFsiWC1Vc2VyLUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlLkRhdGE/LmF1dGhlbnRpY2F0aW9uPy51c2VySWQKICAgICAgICB9OwogICAgICAgIGh0dHBUYXNrLlNldEhlYWRlcnMoaGVhZGVycyk7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciByZXNwb25zZSA9IG5ldyBTY3JpcHRSZXNwb25zZSgpOwogICAgICAgIHZhciBzdGF0dXNDb2RlID0gY29udGV4dC5Cb2R5LnN0YXR1c0NvZGUgPz8gNTAwOwoKICAgICAgICBpZiAoc3RhdHVzQ29kZSA9PSAyMDApCiAgICAgICAgewogICAgICAgICAgICByZXNwb25zZS5EYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG90cCA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNlbnQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgIG90cElkID0gY29udGV4dC5Cb2R5LmRhdGE/Lm90cElkLAogICAgICAgICAgICAgICAgICAgIGV4cGlyZXNBdCA9IGNvbnRleHQuQm9keS5kYXRhPy5leHBpcmVzQXQsCiAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gY29udGV4dC5Cb2R5LmRhdGE/Lm1ldGhvZCwKICAgICAgICAgICAgICAgICAgICBhdHRlbXB0c1JlbWFpbmluZyA9IGNvbnRleHQuQm9keS5kYXRhPy5hdHRlbXB0c1JlbWFpbmluZyA/PyAzCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJlc3BvbnNlLkRhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgb3RwID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2VudCA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIkZhaWxlZCB0byBzZW5kIE9UUCIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gIm90cF9zZW5kX2ZhaWxlZCIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXNwb25zZTsKICAgIH0KfQ==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "otp-sent", - "target": "submit-otp", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP Sent Successfully" - }, - { - "language": "tr-TR", - "label": "OTP Başarıyla Gönderildi" - } - ], - "schema": null, - "rule": { - "location": "./src/OtpSentRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBPdHBTZW50UnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEub3RwLnNlbnQgPT0gdHJ1ZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "otp-send-failed", - "target": "otp-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP Send Failed" - }, - { - "language": "tr-TR", - "label": "OTP Gönderme Başarısız" - } - ], - "schema": null, - "rule": { - "location": "./src/OtpSendFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBPdHBTZW5kRmFpbGVkUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEub3RwLnNlbnQgPT0gZmFsc2U7CiAgICB9Cn0=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "submit-otp", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Submit OTP Code" - }, - { - "language": "tr-TR", - "label": "OTP Kodunu Gönder" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "submit-otp", - "target": "verify-otp", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP Verified Successfully" - }, - { - "language": "tr-TR", - "label": "OTP Başarıyla Doğrulandı" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "verify-otp-code", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/VerifyOtpCodeMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIFZlcmlmeU90cENvZGVNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgdmFyIHZlcmlmeURhdGEgPSBuZXcKICAgICAgICB7CiAgICAgICAgICAgIG90cElkID0gY29udGV4dC5JbnN0YW5jZS5EYXRhPy5vdHA/Lm90cElkLAogICAgICAgICAgICBvdHBDb2RlID0gY29udGV4dC5Cb2R5Lm90cF9jb2RlLAogICAgICAgICAgICB1c2VySWQgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGE/LmF1dGhlbnRpY2F0aW9uPy51c2VySWQsCiAgICAgICAgICAgIGRldmljZUlkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uZGV2aWNlSWQKICAgICAgICB9OwogICAgICAgIGh0dHBUYXNrLlNldEJvZHkodmVyaWZ5RGF0YSk7CiAgICAgICAgdmFyIGhlYWRlcnMgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIHN0cmluZz8+CiAgICAgICAgewogICAgICAgICAgICBbIkNvbnRlbnQtVHlwZSJdID0gImFwcGxpY2F0aW9uL2pzb24iLAogICAgICAgICAgICBbIlgtUmVxdWVzdC1JZCJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucmVxdWVzdElkLAogICAgICAgICAgICBbIlgtVXNlci1JZCJdID0gY29udGV4dC5JbnN0YW5jZS5EYXRhPy5hdXRoZW50aWNhdGlvbj8udXNlcklkCiAgICAgICAgfTsKICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKGhlYWRlcnMpOwogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgcmVzcG9uc2UgPSBuZXcgU2NyaXB0UmVzcG9uc2UoKTsKICAgICAgICB2YXIgc3RhdHVzQ29kZSA9IGNvbnRleHQuQm9keS5zdGF0dXNDb2RlID8/IDUwMDsKCiAgICAgICAgaWYgKHN0YXR1c0NvZGUgPT0gMjAwKQogICAgICAgIHsKICAgICAgICAgICAgcmVzcG9uc2UuRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtZmEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBvdHBWZXJpZmllZCA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIm90cCIsCiAgICAgICAgICAgICAgICAgICAgdmVyaWZpZWRBdCA9IERhdGVUaW1lLlV0Y05vdy5Ub1N0cmluZygibyIpCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHN0YXR1c0NvZGUgPT0gNDAwKQogICAgICAgIHsKICAgICAgICAgICAgcmVzcG9uc2UuRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBtZmEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiSW52YWxpZCBPVFAgY29kZSIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gImludmFsaWRfb3RwIiwKICAgICAgICAgICAgICAgICAgICBhdHRlbXB0c1JlbWFpbmluZyA9IGNvbnRleHQuQm9keS5kYXRhPy5hdHRlbXB0c1JlbWFpbmluZyA/PyAwCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJlc3BvbnNlLkRhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbWZhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIlNlcnZlciBlcnJvciBvY2N1cnJlZCIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gInNlcnZlcl9lcnJvciIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXNwb25zZTsKICAgIH0KfQ==" - } - } - ] - } - ] - }, - { - "key": "verify-otp", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Verify OTP Code" - }, - { - "language": "tr-TR", - "label": "OTP Kodu Doğrula" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "otp-verified", - "target": "otp-success", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP Verified Successfully" - }, - { - "language": "tr-TR", - "label": "OTP Başarıyla Doğrulandı" - } - ], - "schema": null, - "rule": { - "location": "./src/MfaSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBNZmFTdWNjZXNzUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEubWZhLnN1Y2Nlc3MgPT0gdHJ1ZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "otp-invalid-retry", - "target": "submit-otp", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP Invalid - Retry" - }, - { - "language": "tr-TR", - "label": "OTP Geçersiz - Tekrar Dene" - } - ], - "schema": null, - "rule": { - "location": "./src/OtpInvalidRetryRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBPdHBJbnZhbGlkUmV0cnlSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnRleHQuSW5zdGFuY2UuRGF0YS5tZmEuc3VjY2VzcyA9PSBmYWxzZSAmJiAKICAgICAgICAgICAgICAgY29udGV4dC5JbnN0YW5jZS5EYXRhLm1mYS5hdHRlbXB0c1JlbWFpbmluZyA+IDA7CiAgICB9Cn0=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "otp-invalid-max-attempts", - "target": "otp-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP Invalid - Max Attempts Reached" - }, - { - "language": "tr-TR", - "label": "OTP Geçersiz - Maksimum Deneme Sayısına Ulaşıldı" - } - ], - "schema": null, - "rule": { - "location": "./src/OtpInvalidMaxAttemptsRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBPdHBJbnZhbGlkTWF4QXR0ZW1wdHNSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIGNvbnRleHQuSW5zdGFuY2UuRGF0YS5tZmEuc3VjY2VzcyA9PSBmYWxzZSAmJiAKICAgICAgICAgICAgICAgY29udGV4dC5JbnN0YW5jZS5EYXRhLm1mYS5hdHRlbXB0c1JlbWFpbmluZyA8PSAwOwogICAgfQp9" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "otp-success", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP MFA Success" - }, - { - "language": "tr-TR", - "label": "OTP MFA Başarılı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "otp-failed", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP MFA Failed" - }, - { - "language": "tr-TR", - "label": "OTP MFA Başarısız" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "otp-expired", - "stateType": 3, - "subType": 3, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "OTP Expired" - }, - { - "language": "tr-TR", - "label": "OTP Süresi Doldu" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/password-subflow.json b/core/Workflows/oauth/password-subflow.json deleted file mode 100644 index 8ddbef4..0000000 --- a/core/Workflows/oauth/password-subflow.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "key": "password-subflow", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "oauth2", - "password", - "subflow", - "authentication", - "user-credentials" - ], - "attributes": { - "type": "S", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Password Grant Subflow" - }, - { - "language": "tr-TR", - "label": "Password Grant Alt Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-password-flow", - "target": "validate-user-credentials", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Password Flow" - }, - { - "language": "tr-TR", - "label": "Password Akışını Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "validate-user-credentials", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Validate User Credentials" - }, - { - "language": "tr-TR", - "label": "Kullanıcı Kimlik Bilgilerini Doğrula" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "validate-user-credentials", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ValidateUserCredentialsMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gT0F1dGgyIFVzZXIgQ3JlZGVudGlhbHMgVmFsaWRhdGlvbiBNYXBwaW5nIC0gVXNlciBjcmVkZW50aWFsIHZhbGlkYXRpb24gbWFwcGluZwovLyBUaGlzIG1hcHBpbmcgaXMgdXNlZCB0byB2YWxpZGF0ZSB1c2VyIGNyZWRlbnRpYWxzIGluIHRoZSBPQXV0aDIgcGFzc3dvcmQgZ3JhbnQgZmxvdy4KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFZhbGlkYXRlVXNlckNyZWRlbnRpYWxzTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIC8vLyA8c3VtbWFyeT4KICAgIC8vLyBQcmVwYXJlIGlucHV0IGZvciB1c2VyIGNyZWRlbnRpYWwgdmFsaWRhdGlvbiByZXF1ZXN0CiAgICAvLy8gPC9zdW1tYXJ5PgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2sgZm9yIHVzZXIgY3JlZGVudGlhbHMgdmFsaWRhdGlvbiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgcmVxdWVzdEJvZHkgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdXNlcm5hbWUgPSBjb250ZXh0LkJvZHk/LnVzZXJuYW1lID8/IGNvbnRleHQuQm9keT8uZW1haWwsCiAgICAgICAgICAgICAgICBwYXNzd29yZCA9IGNvbnRleHQuQm9keT8ucGFzc3dvcmQKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGh0dHBUYXNrLlNldEJvZHkocmVxdWVzdEJvZHkpOwoKICAgICAgICAgICAgLy8gU2V0IHRoZSBoZWFkZXJzCiAgICAgICAgICAgIHZhciBoZWFkZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbIlgtUmVxdWVzdC1JZCJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucmVxdWVzdElkLAogICAgICAgICAgICAgICAgWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgICAgICB9OwoKICAgICAgICAgICAgaHR0cFRhc2suU2V0SGVhZGVycyhoZWFkZXJzKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgfQoKICAgIC8vLyA8c3VtbWFyeT4KICAgIC8vLyBQcm9jZXNzIHVzZXIgYXV0aGVudGljYXRpb24gcmVzdWx0IGFuZCBtZXJnZSBpdCBpbnRvIHRoZSB3b3JrZmxvdyBpbnN0YW5jZQogICAgLy8vIDwvc3VtbWFyeT4KICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICAgdmFyIHJlc3BvbnNlID0gbmV3IFNjcmlwdFJlc3BvbnNlKCk7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgc3RhdHVzQ29kZSA9IEdldFN0YXR1c0NvZGVGcm9tUmVzcG9uc2UoY29udGV4dCk7CiAgICAgICAgICAgIHZhciByZXNwb25zZURhdGEgPSBHZXRSZXNwb25zZURhdGFGcm9tQ29udGV4dChjb250ZXh0KTsKCiAgICAgICAgICAgIC8vIFN1Y2Nlc3NmdWwgdmFsaWRhdGlvbgogICAgICAgICAgICBpZiAoc3RhdHVzQ29kZSA+PSAyMDAgJiYgc3RhdHVzQ29kZSA8IDMwMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzcG9uc2UuRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGF1dGhlbnRpY2F0aW9uID0gbmV3IAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHVzZXJJZCA9IHJlc3BvbnNlRGF0YT8udXNlcklkLAogICAgICAgICAgICAgICAgICAgICAgICB1c2VybmFtZSA9IHJlc3BvbnNlRGF0YT8udXNlcm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIGVtYWlsID0gcmVzcG9uc2VEYXRhPy5lbWFpbCwKICAgICAgICAgICAgICAgICAgICAgICAgcm9sZXMgPSByZXNwb25zZURhdGE/LnJvbGVzLAogICAgICAgICAgICAgICAgICAgICAgICAvLyBNRkEgY29udGV4dAogICAgICAgICAgICAgICAgICAgICAgICBtZmFSZXF1aXJlZCA9IHJlc3BvbnNlRGF0YT8ubWZhUmVxdWlyZWQgPz8gdHJ1ZQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXNwb25zZS5EYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYXV0aGVudGljYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiSW52YWxpZCB1c2VybmFtZSBvciBwYXNzd29yZCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yQ29kZSA9ICJpbnZhbGlkX2NyZWRlbnRpYWxzIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJlc3BvbnNlLkRhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXV0aGVudGljYXRpb24gPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSAiSW50ZXJuYWwgcHJvY2Vzc2luZyBlcnJvciIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gInByb2Nlc3NpbmdfZXJyb3IiLAogICAgICAgICAgICAgICAgICAgIGVycm9yRGVzY3JpcHRpb24gPSBleC5NZXNzYWdlCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXNwb25zZTsKICAgIH0KCiAgICAjcmVnaW9uIEhlbHBlciBNZXRob2RzCgogICAgcHJpdmF0ZSBzdGF0aWMgaW50IEdldFN0YXR1c0NvZGVGcm9tUmVzcG9uc2UoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIGlmIChjb250ZXh0LkJvZHk/LnN0YXR1c0NvZGUgIT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIChpbnQpY29udGV4dC5Cb2R5LnN0YXR1c0NvZGU7CgogICAgICAgIHJldHVybiAyMDA7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgZHluYW1pYz8gR2V0UmVzcG9uc2VEYXRhRnJvbUNvbnRleHQoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIGlmIChjb250ZXh0LkJvZHk/LmRhdGEgIT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuQm9keS5kYXRhOwoKICAgICAgICBpZiAoY29udGV4dC5Cb2R5ICE9IG51bGwgJiYgY29udGV4dC5Cb2R5LnN0YXR1c0NvZGUgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuQm9keTsKCiAgICAgICAgcmV0dXJuIG51bGw7CiAgICB9CgogICAgI2VuZHJlZ2lvbgp9Cg==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "credentials-valid", - "target": "password-success", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "User Credentials Valid" - }, - { - "language": "tr-TR", - "label": "Kullanıcı Kimlik Bilgileri Geçerli" - } - ], - "schema": null, - "rule": { - "location": "./src/AuthorizationSuccessRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uU3VjY2Vzc1J1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gY29udGV4dC5JbnN0YW5jZS5EYXRhLmF1dGhlbnRpY2F0aW9uLnN1Y2Nlc3MgPT0gdHJ1ZTsKICAgIH0KfQo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "credentials-invalid", - "target": "password-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "User Credentials Invalid" - }, - { - "language": "tr-TR", - "label": "Kullanıcı Kimlik Bilgileri Geçersiz" - } - ], - "schema": null, - "rule": { - "location": "./src/AuthorizationFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBBdXRob3JpemF0aW9uRmFpbGVkUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEuYXV0aGVudGljYXRpb24uc3VjY2VzcyA9PSBmYWxzZTsKICAgIH0KfQo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "password-success", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Password Authentication Success" - }, - { - "language": "tr-TR", - "label": "Password Kimlik Doğrulama Başarılı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "password-failed", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Password Authentication Failed" - }, - { - "language": "tr-TR", - "label": "Password Kimlik Doğrulama Başarısız" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/push-notification-mfa-subflow.json b/core/Workflows/oauth/push-notification-mfa-subflow.json deleted file mode 100644 index 31a346b..0000000 --- a/core/Workflows/oauth/push-notification-mfa-subflow.json +++ /dev/null @@ -1,298 +0,0 @@ -{ - "key": "push-notification-mfa-subflow", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "oauth2", - "mfa", - "push-notification", - "subflow", - "two-factor" - ], - "attributes": { - "type": "S", - "timeout": { - "key": "push-timeout", - "target": "push-expired", - "versionStrategy": "Minor", - "timer": { - "reset": "OnEntry", - "duration": "PT5M" - } - }, - "labels": [ - { - "language": "en-US", - "label": "Push Notification MFA Subflow" - }, - { - "language": "tr-TR", - "label": "Push Bildirimi MFA Alt Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-push-mfa", - "target": "send-push-notification", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Push MFA" - }, - { - "language": "tr-TR", - "label": "Push MFA Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "send-push-notification", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Send Push Notification" - }, - { - "language": "tr-TR", - "label": "Push Bildirimi Gönder" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "send-push-notification", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/SendPushNotificationMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIFNlbmRQdXNoTm90aWZpY2F0aW9uTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgIHZhciBwdXNoRGF0YSA9IG5ldwogICAgICAgIHsKICAgICAgICAgICAgdXNlcklkID0gY29udGV4dC5JbnN0YW5jZS5EYXRhPy5hdXRoZW50aWNhdGlvbj8udXNlcklkLAogICAgICAgICAgICBkZXZpY2VJZCA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YT8uZGV2aWNlUmVnaXN0cmF0aW9uPy5kZXZpY2VJZCwKICAgICAgICAgICAgdGl0bGUgPSAiQXV0aGVudGljYXRpb24gUmVxdWVzdCIsCiAgICAgICAgICAgIG1lc3NhZ2UgPSAiQXBwcm92ZSB0aGlzIGxvZ2luIGF0dGVtcHQgZnJvbSB5b3VyIGRldmljZSIsCiAgICAgICAgICAgIGFjdGlvblR5cGUgPSAibWZhX2F1dGhlbnRpY2F0aW9uIiwKICAgICAgICAgICAgZXhwaXJlc0luID0gMTIwLCAvLyAyIG1pbnV0ZXMKICAgICAgICAgICAgbWV0YWRhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVxdWVzdElkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8ucmVxdWVzdElkLAogICAgICAgICAgICAgICAgY2xpZW50SWQgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGE/LmNsaWVudFZhbGlkYXRpb24/LmNsaWVudElkLAogICAgICAgICAgICAgICAgaXBBZGRyZXNzID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8uaXBBZGRyZXNzLAogICAgICAgICAgICAgICAgdXNlckFnZW50ID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udXNlckFnZW50CiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIGh0dHBUYXNrLlNldEJvZHkocHVzaERhdGEpOwogICAgICAgIHZhciBoZWFkZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgIHsKICAgICAgICAgICAgWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi9qc29uIiwKICAgICAgICAgICAgWyJYLVJlcXVlc3QtSWQiXSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnJlcXVlc3RJZCwKICAgICAgICAgICAgWyJYLVVzZXItSWQiXSA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YT8uYXV0aGVudGljYXRpb24/LnVzZXJJZCwKICAgICAgICAgICAgWyJYLURldmljZS1JZCJdID0gY29udGV4dC5JbnN0YW5jZS5EYXRhPy5kZXZpY2VSZWdpc3RyYXRpb24/LmRldmljZUlkCiAgICAgICAgfTsKICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKGhlYWRlcnMpOwogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgcmVzcG9uc2UgPSBuZXcgU2NyaXB0UmVzcG9uc2UoKTsKICAgICAgICB2YXIgc3RhdHVzQ29kZSA9IGNvbnRleHQuQm9keS5zdGF0dXNDb2RlID8/IDUwMDsKCiAgICAgICAgaWYgKHN0YXR1c0NvZGUgPT0gMjAwKQogICAgICAgIHsKICAgICAgICAgICAgcmVzcG9uc2UuRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwdXNoTm90aWZpY2F0aW9uID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc2VudCA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgbm90aWZpY2F0aW9uSWQgPSBjb250ZXh0LkJvZHkuZGF0YT8ubm90aWZpY2F0aW9uSWQsCiAgICAgICAgICAgICAgICAgICAgZXhwaXJlc0F0ID0gY29udGV4dC5Cb2R5LmRhdGE/LmV4cGlyZXNBdCwKICAgICAgICAgICAgICAgICAgICBkZWxpdmVyeVN0YXR1cyA9IGNvbnRleHQuQm9keS5kYXRhPy5zdGF0dXMgPz8gInBlbmRpbmciCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJlc3BvbnNlLkRhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcHVzaE5vdGlmaWNhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNlbnQgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJGYWlsZWQgdG8gc2VuZCBwdXNoIG5vdGlmaWNhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gInB1c2hfc2VuZF9mYWlsZWQiCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gcmVzcG9uc2U7CiAgICB9Cn0=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "push-sent", - "target": "wait-for-approval", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push Notification Sent" - }, - { - "language": "tr-TR", - "label": "Push Bildirimi Gönderildi" - } - ], - "schema": null, - "rule": { - "location": "./src/PushSentRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBQdXNoU2VudFJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gY29udGV4dC5JbnN0YW5jZS5EYXRhLnB1c2hOb3RpZmljYXRpb24uc2VudCA9PSB0cnVlOwogICAgfQp9" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "push-send-failed", - "target": "push-failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push Send Failed" - }, - { - "language": "tr-TR", - "label": "Push Gönderme Başarısız" - } - ], - "schema": null, - "rule": { - "location": "./src/PushSendFailedRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCnB1YmxpYyBjbGFzcyBQdXNoU2VuZEZhaWxlZFJ1bGUgOiBJQ29uZGl0aW9uTWFwcGluZwp7CiAgICBwdWJsaWMgYXN5bmMgVGFzazxib29sPiBIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gY29udGV4dC5JbnN0YW5jZS5EYXRhLnB1c2hOb3RpZmljYXRpb24uc2VudCA9PSBmYWxzZTsKICAgIH0KfQ==" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "wait-for-approval", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Wait for User Approval" - }, - { - "language": "tr-TR", - "label": "Kullanıcı Onayını Bekle" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "push-approved", - "target": "push-success", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push Notification Approved" - }, - { - "language": "tr-TR", - "label": "Push Bildirimi Onaylandı" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "check-push-response", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/CheckPushResponseMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIENoZWNrUHVzaFJlc3BvbnNlTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgIHZhciBjaGVja0RhdGEgPSBuZXcKICAgICAgICB7CiAgICAgICAgICAgIG5vdGlmaWNhdGlvbklkID0gY29udGV4dC5JbnN0YW5jZS5EYXRhPy5wdXNoTm90aWZpY2F0aW9uPy5ub3RpZmljYXRpb25JZCwKICAgICAgICAgICAgdXNlcklkID0gY29udGV4dC5JbnN0YW5jZS5EYXRhPy5hdXRoZW50aWNhdGlvbj8udXNlcklkLAogICAgICAgICAgICBkZXZpY2VJZCA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YT8uZGV2aWNlUmVnaXN0cmF0aW9uPy5kZXZpY2VJZAogICAgICAgIH07CiAgICAgICAgaHR0cFRhc2suU2V0Qm9keShjaGVja0RhdGEpOwogICAgICAgIHZhciBoZWFkZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgIHsKICAgICAgICAgICAgWyJDb250ZW50LVR5cGUiXSA9ICJhcHBsaWNhdGlvbi9qc29uIiwKICAgICAgICAgICAgWyJYLVJlcXVlc3QtSWQiXSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnJlcXVlc3RJZCwKICAgICAgICAgICAgWyJYLVVzZXItSWQiXSA9IGNvbnRleHQuSW5zdGFuY2UuRGF0YT8uYXV0aGVudGljYXRpb24/LnVzZXJJZAogICAgICAgIH07CiAgICAgICAgaHR0cFRhc2suU2V0SGVhZGVycyhoZWFkZXJzKTsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIHJlc3BvbnNlID0gbmV3IFNjcmlwdFJlc3BvbnNlKCk7CiAgICAgICAgdmFyIHN0YXR1c0NvZGUgPSBjb250ZXh0LkJvZHkuc3RhdHVzQ29kZSA/PyA1MDA7CgogICAgICAgIGlmIChzdGF0dXNDb2RlID09IDIwMCkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXNwb25zZVN0YXR1cyA9IGNvbnRleHQuQm9keS5kYXRhPy5zdGF0dXM7CiAgICAgICAgICAgIGlmIChyZXNwb25zZVN0YXR1cyA9PSAiYXBwcm92ZWQiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXNwb25zZS5EYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbWZhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgcHVzaEFwcHJvdmVkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gInB1c2giLAogICAgICAgICAgICAgICAgICAgICAgICBhcHByb3ZlZEF0ID0gY29udGV4dC5Cb2R5LmRhdGE/LnJlc3BvbmRlZEF0CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChyZXNwb25zZVN0YXR1cyA9PSAiZGVuaWVkIikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzcG9uc2UuRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG1mYSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9ICJBdXRoZW50aWNhdGlvbiByZXF1ZXN0IGRlbmllZCBieSB1c2VyIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gImFjY2Vzc19kZW5pZWQiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIFN0aWxsIHBlbmRpbmcsIGNvbnRpbnVlIHdhaXRpbmcKICAgICAgICAgICAgICAgIHJlc3BvbnNlLkRhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBtZmEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwgLy8gU3RpbGwgcGVuZGluZwogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSAicGVuZGluZyIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHJlc3BvbnNlLkRhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbWZhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgIGVycm9yID0gIlNlcnZlciBlcnJvciBvY2N1cnJlZCIsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JDb2RlID0gInNlcnZlcl9lcnJvciIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXNwb25zZTsKICAgIH0KfQ==" - } - } - ] - }, - { - "key": "push-denied", - "target": "push-failed", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push Notification Denied" - }, - { - "language": "tr-TR", - "label": "Push Bildirimi Reddedildi" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "check-push-denied-response", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/CheckPushDeniedResponseMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKcHVibGljIGNsYXNzIENoZWNrUHVzaERlbmllZFJlc3BvbnNlTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIHJlc3BvbnNlID0gbmV3IFNjcmlwdFJlc3BvbnNlKCk7CiAgICAgICAgcmVzcG9uc2UuRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG1mYSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBwdXNoQXBwcm92ZWQgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gInB1c2giLAogICAgICAgICAgICAgICAgICAgICAgICBhcHByb3ZlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfTsKCiAgICAgICAgcmV0dXJuIHJlc3BvbnNlOwogICAgfQp9" - } - } - ] - } - ] - }, - { - "key": "push-success", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push MFA Success" - }, - { - "language": "tr-TR", - "label": "Push MFA Başarılı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "push-failed", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push MFA Failed" - }, - { - "language": "tr-TR", - "label": "Push MFA Başarısız" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "push-expired", - "stateType": 3, - "subType": 3, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Push Notification Expired" - }, - { - "language": "tr-TR", - "label": "Push Bildirimi Süresi Doldu" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/AuthorizationCodeFlowRule.csx b/core/Workflows/oauth/src/AuthorizationCodeFlowRule.csx deleted file mode 100644 index 7d558b5..0000000 --- a/core/Workflows/oauth/src/AuthorizationCodeFlowRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class AuthorizationCodeFlowRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.grant_type == "authorization_code"; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/AuthorizationCodeSubflowMapping.csx b/core/Workflows/oauth/src/AuthorizationCodeSubflowMapping.csx deleted file mode 100644 index 63b43e0..0000000 --- a/core/Workflows/oauth/src/AuthorizationCodeSubflowMapping.csx +++ /dev/null @@ -1,23 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class AuthorizationCodeSubflowMapping : ISubFlowMapping -{ - public Task InputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse - { - Data = context.Instance.Data, - Headers = null - }); - } - - public Task OutputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse - { - Data = context.Body, - Headers = null - }); - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/AuthorizationFailedRule.csx b/core/Workflows/oauth/src/AuthorizationFailedRule.csx deleted file mode 100644 index 5b91ee8..0000000 --- a/core/Workflows/oauth/src/AuthorizationFailedRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class AuthorizationFailedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.authentication.success == false; - } -} diff --git a/core/Workflows/oauth/src/AuthorizationSuccessRule.csx b/core/Workflows/oauth/src/AuthorizationSuccessRule.csx deleted file mode 100644 index a1cc79a..0000000 --- a/core/Workflows/oauth/src/AuthorizationSuccessRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class AuthorizationSuccessRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.authentication.success == true; - } -} diff --git a/core/Workflows/oauth/src/CheckDeviceRegistrationMapping.csx b/core/Workflows/oauth/src/CheckDeviceRegistrationMapping.csx deleted file mode 100644 index dd7563a..0000000 --- a/core/Workflows/oauth/src/CheckDeviceRegistrationMapping.csx +++ /dev/null @@ -1,196 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Device Registration Check Mapping - Device registration status check mapping -/// This mapping is used to check whether the device is registered during the MFA process. -/// -public class CheckDeviceRegistrationMapping : IMapping -{ - /// - /// Prepare input for device registration check - /// - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask for device registration check"); - } - - // Get information from authentication context - var authData = context.Instance?.Data?.authentication; - var clientData = context.Instance?.Data?.clientValidation; - - // Query parameters to be sent - var queryParams = new Dictionary - { - ["user_id"] = authData?.userId?.ToString(), - ["device_id"] = context.Instance?.Data?.deviceId, - ["client_id"] = clientData?.clientId?.ToString() ?? clientData?.clientId?.ToString() - }; - - // Update URL with query parameters - var baseUrl = httpTask.Url; - var queryString = string.Join("&", queryParams.Where(kvp => !string.IsNullOrEmpty(kvp.Value)) - .Select(kvp => $"{kvp.Key}={Uri.EscapeDataString(kvp.Value!)}")); - - if (!string.IsNullOrEmpty(queryString)) - { - httpTask.Url = $"{baseUrl}?{queryString}"; - } - - // Set headers - var headers = new Dictionary - { - ["X-Device-Id"] = context.Instance?.Data?.deviceId, - ["X-Request-Id"] = context.Instance?.Data?.requestId, - ["X-Workflow-Instance"] = context.Instance?.Id.ToString(), - ["Content-Type"] = "application/json" - }; - - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse()); - } - } - - /// - /// Process device registration check result and merge it into the workflow instance - /// - public async Task OutputHandler(ScriptContext context) - { - try - { - var statusCode = GetStatusCodeFromResponse(context); - var responseData = GetResponseDataFromContext(context); - - // Successful check - if (statusCode >= 200 && statusCode < 300) - { - var deviceRegistration = new - { - checkedAt = DateTime.UtcNow, - isRegistered = responseData?.isRegistered ?? false, - deviceId = responseData?.deviceId, - deviceName = responseData?.deviceName, - deviceType = responseData?.deviceType ?? "mobile", - supportsPush = responseData?.supportsPush ?? false, - registeredAt = responseData?.registeredAt, - lastSeenAt = responseData?.lastSeenAt - }; - - return new ScriptResponse - { - Data = new - { - deviceRegistration = deviceRegistration - } - }; - } - else - { - var errorInfo = ExtractErrorInformation(context, statusCode); - - var deviceRegistration = new - { - checkedAt = DateTime.UtcNow, - isRegistered = false, - error = errorInfo.message, - errorCode = errorInfo.code, - errorDescription = errorInfo.description, - statusCode = statusCode - }; - - return new ScriptResponse - { - Data = new - { - deviceRegistration = deviceRegistration - } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Data = new - { - deviceRegistration = new - { - checkedAt = DateTime.UtcNow, - isRegistered = false, - error = "Internal processing error", - errorCode = "processing_error", - errorDescription = ex.Message - } - } - }; - } - } - - #region Helper Methods - - private static int GetStatusCodeFromResponse(ScriptContext context) - { - if (context.Body?.statusCode != null) - return (int)context.Body.statusCode; - - return 200; - } - - private static dynamic? GetResponseDataFromContext(ScriptContext context) - { - if (context.Body?.data != null) - return context.Body.data; - - if (context.Body != null && context.Body.statusCode == null) - return context.Body; - - return null; - } - - private static (string message, string code, string description) ExtractErrorInformation(ScriptContext context, int statusCode) - { - var errorData = context.Body?.data?.error ?? null; - - string message = "Device validation failed"; - string code = "invalid_device"; - string description = "The device credentials provided are invalid"; - - if (errorData != null) - { - message = errorData.message ?? message; - code = errorData.code ?? code; - description = errorData.description ?? description; - } - else if (statusCode == 401) - { - code = "unauthorized_device"; - description = "Device authentication failed"; - } - else if (statusCode == 403) - { - code = "access_denied"; - description = "Device access denied"; - } - else if (statusCode >= 500) - { - code = "server_error"; - description = "Internal server error during device validation"; - } - - return (message, code, description); - } - - - #endregion -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/CheckPushDeniedResponseMapping.csx b/core/Workflows/oauth/src/CheckPushDeniedResponseMapping.csx deleted file mode 100644 index 772b539..0000000 --- a/core/Workflows/oauth/src/CheckPushDeniedResponseMapping.csx +++ /dev/null @@ -1,28 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -public class CheckPushDeniedResponseMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = new ScriptResponse(); - response.Data = new - { - mfa = new - { - success = false, - pushApproved = false, - method = "push", - approvedAt = DateTime.UtcNow - } - }; - - return response; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/CheckPushResponseMapping.csx b/core/Workflows/oauth/src/CheckPushResponseMapping.csx deleted file mode 100644 index 87c4e8d..0000000 --- a/core/Workflows/oauth/src/CheckPushResponseMapping.csx +++ /dev/null @@ -1,88 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -public class CheckPushResponseMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - var checkData = new - { - notificationId = context.Instance.Data?.pushNotification?.notificationId, - userId = context.Instance.Data?.authentication?.userId, - deviceId = context.Instance.Data?.deviceRegistration?.deviceId - }; - httpTask.SetBody(checkData); - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Request-Id"] = context.Instance?.Data?.requestId, - ["X-User-Id"] = context.Instance.Data?.authentication?.userId - }; - httpTask.SetHeaders(headers); - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = new ScriptResponse(); - var statusCode = context.Body.statusCode ?? 500; - - if (statusCode == 200) - { - var responseStatus = context.Body.data?.status; - if (responseStatus == "approved") - { - response.Data = new - { - mfa = new - { - success = true, - pushApproved = true, - method = "push", - approvedAt = context.Body.data?.respondedAt - } - }; - } - else if (responseStatus == "denied") - { - response.Data = new - { - mfa = new - { - success = false, - error = "Authentication request denied by user", - errorCode = "access_denied" - } - }; - } - else - { - // Still pending, continue waiting - response.Data = new - { - mfa = new - { - success = false, // Still pending - status = "pending" - } - }; - } - } - else - { - response.Data = new - { - mfa = new - { - success = false, - error = "Server error occurred", - errorCode = "server_error" - } - }; - } - - return response; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/ClientCredentialsFlowRule.csx b/core/Workflows/oauth/src/ClientCredentialsFlowRule.csx deleted file mode 100644 index c5adc93..0000000 --- a/core/Workflows/oauth/src/ClientCredentialsFlowRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class ClientCredentialsFlowRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.grant_type == "client_credentials"; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/ClientInvalidRule.csx b/core/Workflows/oauth/src/ClientInvalidRule.csx deleted file mode 100644 index 99d4c2d..0000000 --- a/core/Workflows/oauth/src/ClientInvalidRule.csx +++ /dev/null @@ -1,50 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Client Invalid Rule - Client validation failure condition mapping -/// This rule checks if the client validation was successful. -/// -public class ClientInvalidRule : IConditionMapping -{ - /// - /// Check if the client validation was successful. - /// - public async Task Handler(ScriptContext context) - { - try - { - // Null check - if (context?.Instance?.Data == null) - { - return true; - } - - // Client validation data - var clientValidation = context.Instance.Data.clientValidation; - - if (clientValidation == null) - { - return true; - } - - // Check if the client validation was successful. - return clientValidation.success == false; - } - catch (Exception ex) - { - // Exception durumunda true döndür (invalid) - if (context?.MetaData != null) - { - context.MetaData["client_invalid_rule_error"] = new - { - error = ex.Message, - type = ex.GetType().Name, - timestamp = DateTime.UtcNow - }; - } - - return true; // Hata varsa invalid kabul et - } - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/ClientValidRule.csx b/core/Workflows/oauth/src/ClientValidRule.csx deleted file mode 100644 index 8f41a5c..0000000 --- a/core/Workflows/oauth/src/ClientValidRule.csx +++ /dev/null @@ -1,50 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Client Valid Rule - Client validation success condition mapping -/// This rule checks if the client validation was successful. -/// -public class ClientValidRule : IConditionMapping -{ - /// - /// Check if the client validation was successful. - /// - public async Task Handler(ScriptContext context) - { - try - { - // Null check - if (context?.Instance?.Data == null) - { - return false; - } - - // Client validation data - var clientValidation = context.Instance.Data.clientValidation; - - if (clientValidation == null) - { - return false; - } - - // Check if the client validation was successful. - return clientValidation.success == true; - } - catch (Exception ex) - { - // If an exception occurs, return false and write to audit log - if (context?.MetaData != null) - { - context.MetaData["client_valid_rule_error"] = new - { - error = ex.Message, - type = ex.GetType().Name, - timestamp = DateTime.UtcNow - }; - } - - return false; - } - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/DeviceNotRegisteredOtpRule.csx b/core/Workflows/oauth/src/DeviceNotRegisteredOtpRule.csx deleted file mode 100644 index 35f0a80..0000000 --- a/core/Workflows/oauth/src/DeviceNotRegisteredOtpRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class DeviceNotRegisteredOtpRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.deviceRegistration.isRegistered == false; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/DeviceRegisteredPushRule.csx b/core/Workflows/oauth/src/DeviceRegisteredPushRule.csx deleted file mode 100644 index 5d99da4..0000000 --- a/core/Workflows/oauth/src/DeviceRegisteredPushRule.csx +++ /dev/null @@ -1,97 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Device Registered Push Rule - Device registered and push supported condition mapping -// This rule checks whether the device is registered and supports push notifications. -/// -public class DeviceRegisteredPushRule : IConditionMapping -{ - /// - /// Check if the device is registered and supports push notifications - /// - public async Task Handler(ScriptContext context) - { - try - { - // Null check - if (context?.Instance?.Data == null) - { - return false; - } - - // Get device registration data - var deviceRegistration = context.Instance.Data.deviceRegistration; - - if (deviceRegistration == null) - { - return false; - } - - // Basic registration check - var isRegistered = deviceRegistration.isRegistered; - if (isRegistered != true) - { - return false; - } - - // Push support check - var supportsPush = deviceRegistration.supportsPush; - if (supportsPush != true) - { - return false; - } - - // Additional security checks - // Device ID check - var deviceId = deviceRegistration.deviceId; - if (string.IsNullOrEmpty(deviceId?.ToString())) - { - return false; - } - - // Last seen time check (30 days) - // var lastSeenAt = deviceRegistration.lastSeenAt; - // if (lastSeenAt != null) - // { - // if (DateTime.TryParse(lastSeenAt.ToString(), out DateTime lastSeen)) - // { - // if (DateTime.UtcNow.Subtract(lastSeen).TotalDays > 30) - // { - // return false; - // } - // } - // } - - // // Registration time check (6 months) - // var registeredAt = deviceRegistration.registeredAt; - // if (registeredAt != null) - // { - // if (DateTime.TryParse(registeredAt.ToString(), out DateTime regTime)) - // { - // if (DateTime.UtcNow.Subtract(regTime).TotalDays > 180) - // { - // return false; - // } - // } - // } - - return true; - } - catch (Exception ex) - { - // If an exception occurs, return false and write to audit log - if (context?.MetaData != null) - { - context.MetaData["device_registered_push_rule_error"] = new - { - error = ex.Message, - type = ex.GetType().Name, - timestamp = DateTime.UtcNow - }; - } - - return false; - } - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/DeviceRegisteredRule.csx b/core/Workflows/oauth/src/DeviceRegisteredRule.csx deleted file mode 100644 index f3d4110..0000000 --- a/core/Workflows/oauth/src/DeviceRegisteredRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class DeviceRegisteredRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.deviceRegistration.success == true; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/GenerateTokensMapping.csx b/core/Workflows/oauth/src/GenerateTokensMapping.csx deleted file mode 100644 index 7e62242..0000000 --- a/core/Workflows/oauth/src/GenerateTokensMapping.csx +++ /dev/null @@ -1,240 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// Generate Tokens Mapping - OAuth2 token generation mapping -// This mapping is used to generate access and refresh tokens after the authentication process is complete. -/// -public class GenerateTokensMapping : IMapping -{ - /// - /// Preparing input for token creation request - /// - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask for token generation"); - } - - // Gather all information from the workflow context - var clientData = context.Instance?.Data?.clientValidation; - var authData = context.Instance?.Data?.authentication; - var mfaData = context.Instance?.Data?.mfa; - var deviceData = context.Instance?.Data?.deviceRegistration; - - // Token generation request body - var requestBody = new - { - // Client information - client_id = clientData?.clientId, - client_secret = context.Instance?.Data?.client_secret, - - // Grant type and user information - grant_type = context.Instance?.Data?.grant_type, - user_id = authData?.userId, - username = authData?.username, - email = authData?.email, - - // Scope ve permissions - scope = context.Instance?.Data?.scope, - user_roles = authData?.roles ?? new[] { "retail-user" }, - - // Device context - device_id = deviceData?.deviceId, - device_registered = deviceData?.isRegistered, - - // MFA context - mfa_completed = mfaData?.success ?? false, - mfa_method = mfaData?.method ?? "none", - - // Security context - ip_address = context.Headers?["x-forwarded-for"] ?? context.Headers?["x-real-ip"], - user_agent = context.Headers?["user-agent"] - }; - - httpTask.SetBody(requestBody); - - // Set Headers - var headers = new Dictionary - { - ["X-Request-Id"] = context.Instance?.Data?.deviceId, - ["Content-Type"] = "application/json", - ["X-Workflow-Instance"] = context.Instance?.Id.ToString(), - ["X-User-Id"] = requestBody.user_id?.ToString(), - ["X-Device-Id"] = requestBody.device_id, - ["X-Grant-Type"] = requestBody.grant_type - }; - - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "token-generation-input-error", - Data = new - { - error = new - { - message = ex.Message, - type = ex.GetType().Name, - timestamp = DateTime.UtcNow, - workflow_instance = context.Instance?.Id - } - }, - Tags = new[] { "oauth2", "token-generation", "input-error" } - }); - } - } - - /// - /// Process the token creation result and merge it into the workflow instance - /// - public async Task OutputHandler(ScriptContext context) - { - try - { - var statusCode = GetStatusCodeFromResponse(context); - var responseData = GetResponseDataFromContext(context); - - // Successful token generation - if (statusCode >= 200 && statusCode < 300) - { - var tokens = new - { - success = true, - generated_at = DateTime.UtcNow, - access_token = responseData?.access_token, - refresh_token = responseData?.refresh_token, - token_type = responseData?.token_type ?? "Bearer", - expires_in = responseData?.expires_in, - scope = responseData?.scope - }; - - return new ScriptResponse - { - Key = "token-generation-success", - Data = new - { - tokens = tokens - }, - Tags = new[] { "oauth2", "token-generation", "success", "authentication-completed", "tokens-issued" } - }; - } - else - { - var errorInfo = ExtractErrorInformation(context, statusCode); - - var tokens = new - { - success = false, - generated_at = DateTime.UtcNow, - error = errorInfo.message, - error_code = errorInfo.code, - error_description = errorInfo.description, - status_code = statusCode, - // Metadata - request_id = context.Instance?.Data?.deviceId - }; - - return new ScriptResponse - { - Key = "token-generation-failure", - Data = new - { - tokens = tokens - }, - Tags = new[] { "oauth2", "token-generation", "failure", "error", - "authentication-failed", "tokens-not-issued" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "token-generation-output-error", - Data = new - { - tokens = new - { - success = false, - error = "Internal processing error", - error_code = "processing_error", - error_description = ex.Message, - generated_at = DateTime.UtcNow - } - }, - Tags = new[] { "oauth2", "token-generation", "error", "exception", "processing-error" } - }; - } - } - - #region Helper Methods - - private static int GetStatusCodeFromResponse(ScriptContext context) - { - if (context.Body?.statusCode != null) - return (int)context.Body.statusCode; - - return 200; - } - - private static dynamic? GetResponseDataFromContext(ScriptContext context) - { - if (context.Body?.data != null) - return context.Body.data; - - if (context.Body != null && context.Body.statusCode == null) - return context.Body; - - return null; - } - - private static (string message, string code, string description) ExtractErrorInformation(ScriptContext context, int statusCode) - { - var errorData = context.Body?.error ?? context.Body?.data?.error; - - string message = "Token generation failed"; - string code = "token_generation_error"; - string description = "Unable to generate access tokens"; - - if (errorData != null) - { - message = errorData.message ?? errorData.error ?? message; - code = errorData.code ?? errorData.error_code ?? code; - description = errorData.description ?? errorData.error_description ?? description; - } - else if (statusCode == 400) - { - code = "invalid_request"; - description = "Invalid token generation request"; - } - else if (statusCode == 401) - { - code = "invalid_client"; - description = "Client authentication failed during token generation"; - } - else if (statusCode == 403) - { - code = "access_denied"; - description = "Access denied for token generation"; - } - else if (statusCode >= 500) - { - code = "server_error"; - description = "Internal server error during token generation"; - } - - return (message, code, description); - } - - #endregion -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/HeaderInitialMapping.csx b/core/Workflows/oauth/src/HeaderInitialMapping.csx deleted file mode 100644 index 059a0af..0000000 --- a/core/Workflows/oauth/src/HeaderInitialMapping.csx +++ /dev/null @@ -1,39 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// OAuth2 Client Validation Mapping - Client validation mapping -// This mapping is used to validate OAuth2 client credentials. -/// -public class HeaderInitialMapping : ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - /// - /// Process the client authentication result and merge it into the workflow instance - /// - public async Task OutputHandler(ScriptContext context) - { - LogInformation("Header Initial Mapping"); - return new ScriptResponse - { - Key = "header-initial-mapping", - Data = new - { - status = "initial-header", - headers = new - { - requestId = context.Headers?["x-request-id"], - deviceInfo = context.Headers?["x-device-info"], - deviceId = context.Headers?["x-device-id"], - acceptLanguage = context.Headers?["accept-language"], - forwardedFor = context.Headers?["x-forwarded-for"] - } - } - }; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/MfaFailedRule.csx b/core/Workflows/oauth/src/MfaFailedRule.csx deleted file mode 100644 index 6a5bc61..0000000 --- a/core/Workflows/oauth/src/MfaFailedRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class MfaFailedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.mfa.success == false; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/MfaSuccessRule.csx b/core/Workflows/oauth/src/MfaSuccessRule.csx deleted file mode 100644 index c284dce..0000000 --- a/core/Workflows/oauth/src/MfaSuccessRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class MfaSuccessRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.mfa.success == true; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/OtpInvalidMaxAttemptsRule.csx b/core/Workflows/oauth/src/OtpInvalidMaxAttemptsRule.csx deleted file mode 100644 index 75827d0..0000000 --- a/core/Workflows/oauth/src/OtpInvalidMaxAttemptsRule.csx +++ /dev/null @@ -1,11 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class OtpInvalidMaxAttemptsRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.mfa.success == false && - context.Instance.Data.mfa.attemptsRemaining <= 0; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/OtpInvalidRetryRule.csx b/core/Workflows/oauth/src/OtpInvalidRetryRule.csx deleted file mode 100644 index 4dbe58e..0000000 --- a/core/Workflows/oauth/src/OtpInvalidRetryRule.csx +++ /dev/null @@ -1,11 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class OtpInvalidRetryRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.mfa.success == false && - context.Instance.Data.mfa.attemptsRemaining > 0; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/OtpMfaSubflowMapping.csx b/core/Workflows/oauth/src/OtpMfaSubflowMapping.csx deleted file mode 100644 index 9bdb2e3..0000000 --- a/core/Workflows/oauth/src/OtpMfaSubflowMapping.csx +++ /dev/null @@ -1,23 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class OtpMfaSubflowMapping : ISubFlowMapping -{ - public Task InputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse - { - Data = context.Instance.Data, - Headers = null - }); - } - - public Task OutputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse - { - Data = context.Body, - Headers = null - }); - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/OtpSendFailedRule.csx b/core/Workflows/oauth/src/OtpSendFailedRule.csx deleted file mode 100644 index 27850b2..0000000 --- a/core/Workflows/oauth/src/OtpSendFailedRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class OtpSendFailedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.otp.sent == false; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/OtpSentRule.csx b/core/Workflows/oauth/src/OtpSentRule.csx deleted file mode 100644 index 6100651..0000000 --- a/core/Workflows/oauth/src/OtpSentRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class OtpSentRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.otp.sent == true; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/PasswordFlowRule.csx b/core/Workflows/oauth/src/PasswordFlowRule.csx deleted file mode 100644 index ee4577c..0000000 --- a/core/Workflows/oauth/src/PasswordFlowRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class PasswordFlowRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.grant_type == "password"; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/PasswordSubflowMapping.csx b/core/Workflows/oauth/src/PasswordSubflowMapping.csx deleted file mode 100644 index c0d3184..0000000 --- a/core/Workflows/oauth/src/PasswordSubflowMapping.csx +++ /dev/null @@ -1,28 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class PasswordSubflowMapping : ISubFlowMapping -{ - public Task InputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse - { - Data = context.Instance.Data, - Headers = null - }); - } - - public Task OutputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse - { - Data = context.Body, - Headers = null - }); - } -} - - - - - diff --git a/core/Workflows/oauth/src/PushNotificationMfaSubflowMapping.csx b/core/Workflows/oauth/src/PushNotificationMfaSubflowMapping.csx deleted file mode 100644 index 5e30bf0..0000000 --- a/core/Workflows/oauth/src/PushNotificationMfaSubflowMapping.csx +++ /dev/null @@ -1,23 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class PushNotificationMfaSubflowMapping : ISubFlowMapping -{ - public Task InputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse - { - Data = context.Instance.Data, - Headers = null - }); - } - - public Task OutputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse - { - Data = context.Body, - Headers = null - }); - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/PushSendFailedRule.csx b/core/Workflows/oauth/src/PushSendFailedRule.csx deleted file mode 100644 index d45645d..0000000 --- a/core/Workflows/oauth/src/PushSendFailedRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class PushSendFailedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.pushNotification.sent == false; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/PushSentRule.csx b/core/Workflows/oauth/src/PushSentRule.csx deleted file mode 100644 index 77d4de3..0000000 --- a/core/Workflows/oauth/src/PushSentRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class PushSentRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.pushNotification.sent == true; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/RegisterDeviceMapping.csx b/core/Workflows/oauth/src/RegisterDeviceMapping.csx deleted file mode 100644 index 62ca320..0000000 --- a/core/Workflows/oauth/src/RegisterDeviceMapping.csx +++ /dev/null @@ -1,63 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -public class RegisterDeviceMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - var deviceData = new - { - userId = context.Instance.Data?.authentication?.userId, - deviceId = context.Instance?.Data?.deviceId, - deviceName = context.Body?.deviceName ?? "Unknown Device", - deviceType = context.Body?.deviceType ?? "mobile", - supportsPush = true - }; - httpTask.SetBody(deviceData); - var headers = new Dictionary - { - ["Content-Type"] = "application/json" - }; - httpTask.SetHeaders(headers); - return Task.FromResult(new ScriptResponse - { - Data = context.Instance.Data, - Headers = null - }); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = new ScriptResponse(); - var statusCode = context.Body.statusCode ?? 500; - - if (statusCode == 200 || statusCode == 201) - { - response.Data = new - { - deviceRegistration = new - { - success = true, - deviceId = context.Body.data?.deviceId, - isRegistered = true, - supportsPush = true - } - }; - } - else - { - response.Data = new - { - deviceRegistration = new - { - success = false, - error = "Device registration failed" - } - }; - } - - return response; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/SendOtpNotificationMapping.csx b/core/Workflows/oauth/src/SendOtpNotificationMapping.csx deleted file mode 100644 index 3c1b11b..0000000 --- a/core/Workflows/oauth/src/SendOtpNotificationMapping.csx +++ /dev/null @@ -1,64 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -public class SendOtpNotificationMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - var otpData = new - { - userId = context.Instance.Data?.authentication?.userId, - email = context.Instance.Data?.authentication?.email, - phone = context.Instance.Data?.authentication?.phone, - method = "sms", // Default to sms, can be "sms" or "email" - deviceId = context.Instance?.Data?.deviceId, - language = context.Headers["accept-language"] ?? "en-US" - }; - httpTask.SetBody(otpData); - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Request-Id"] = context.Instance?.Data?.requestId, - ["X-User-Id"] = context.Instance.Data?.authentication?.userId - }; - httpTask.SetHeaders(headers); - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = new ScriptResponse(); - var statusCode = context.Body.statusCode ?? 500; - - if (statusCode == 200) - { - response.Data = new - { - otp = new - { - sent = true, - otpId = context.Body.data?.otpId, - expiresAt = context.Body.data?.expiresAt, - method = context.Body.data?.method, - attemptsRemaining = context.Body.data?.attemptsRemaining ?? 3 - } - }; - } - else - { - response.Data = new - { - otp = new - { - sent = false, - error = "Failed to send OTP", - errorCode = "otp_send_failed" - } - }; - } - - return response; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/SendPushNotificationMapping.csx b/core/Workflows/oauth/src/SendPushNotificationMapping.csx deleted file mode 100644 index ee2979b..0000000 --- a/core/Workflows/oauth/src/SendPushNotificationMapping.csx +++ /dev/null @@ -1,71 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -public class SendPushNotificationMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - var pushData = new - { - userId = context.Instance.Data?.authentication?.userId, - deviceId = context.Instance.Data?.deviceRegistration?.deviceId, - title = "Authentication Request", - message = "Approve this login attempt from your device", - actionType = "mfa_authentication", - expiresIn = 120, // 2 minutes - metadata = new - { - requestId = context.Instance?.Data?.requestId, - clientId = context.Instance.Data?.clientValidation?.clientId, - ipAddress = context.Instance?.Data?.ipAddress, - userAgent = context.Instance?.Data?.userAgent - } - }; - httpTask.SetBody(pushData); - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Request-Id"] = context.Instance?.Data?.requestId, - ["X-User-Id"] = context.Instance.Data?.authentication?.userId, - ["X-Device-Id"] = context.Instance.Data?.deviceRegistration?.deviceId - }; - httpTask.SetHeaders(headers); - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = new ScriptResponse(); - var statusCode = context.Body.statusCode ?? 500; - - if (statusCode == 200) - { - response.Data = new - { - pushNotification = new - { - sent = true, - notificationId = context.Body.data?.notificationId, - expiresAt = context.Body.data?.expiresAt, - deliveryStatus = context.Body.data?.status ?? "pending" - } - }; - } - else - { - response.Data = new - { - pushNotification = new - { - sent = false, - error = "Failed to send push notification", - errorCode = "push_send_failed" - } - }; - } - - return response; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/TokenGenerationFailedRule.csx b/core/Workflows/oauth/src/TokenGenerationFailedRule.csx deleted file mode 100644 index 1b70fcc..0000000 --- a/core/Workflows/oauth/src/TokenGenerationFailedRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class TokenGenerationFailedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.tokens.success == false; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/TokensGeneratedRule.csx b/core/Workflows/oauth/src/TokensGeneratedRule.csx deleted file mode 100644 index 247e49e..0000000 --- a/core/Workflows/oauth/src/TokensGeneratedRule.csx +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -public class TokensGeneratedRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.tokens.success == true; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/ValidateAuthorizationCodeMapping.csx b/core/Workflows/oauth/src/ValidateAuthorizationCodeMapping.csx deleted file mode 100644 index 2e01cc7..0000000 --- a/core/Workflows/oauth/src/ValidateAuthorizationCodeMapping.csx +++ /dev/null @@ -1,78 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -public class ValidateAuthorizationCodeMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - var authCodeData = new - { - code = context.Body.code, - clientId = context.Body.client_id, - clientSecret = context.Body.client_secret, - redirectUri = context.Body.redirect_uri, - codeVerifier = context.Body.code_verifier // PKCE for enhanced security - }; - httpTask.SetBody(authCodeData); - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Request-Id"] = context.Instance?.Data?.requestId, - }; - httpTask.SetHeaders(headers); - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = new ScriptResponse(); - var statusCode = context.Body.statusCode ?? 500; - - if (statusCode == 200) - { - response.Data = new - { - authentication = new - { - success = true, - userId = context.Body.data?.userId, - grantType = "authorization_code", - redirectUri = context.Body.data?.redirectUri, - codeChallenge = context.Body.data?.codeChallenge, - codeChallengeMethod = context.Body.data?.codeChallengeMethod, - isValidationSuccess = context.Body.data?.isValid, - expiresAt = context.Body.data?.expiresAt, - authorizationCode = context.Body.data?.code - } - }; - } - else if (statusCode == 400) - { - response.Data = new - { - authentication = new - { - success = false, - error = "Invalid authorization code", - errorCode = "invalid_grant" - } - }; - } - else - { - response.Data = new - { - authentication = new - { - success = false, - error = "Server error occurred", - errorCode = "server_error" - } - }; - } - - return response; - } -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/ValidateClientMapping.csx b/core/Workflows/oauth/src/ValidateClientMapping.csx deleted file mode 100644 index 5f183fc..0000000 --- a/core/Workflows/oauth/src/ValidateClientMapping.csx +++ /dev/null @@ -1,200 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// OAuth2 Client Validation Mapping - Client validation mapping -// This mapping is used to validate OAuth2 client credentials. -/// -public class ValidateClientMapping : ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - LogInformation("Client Validation Input Handler"); - LogInformation("Status: {status}", args: new object?[] { context.Instance?.Data?.status }); - LogInformation("Request ClientId: {ClientId}", args: new object?[] { GetPropertyValue(context.Body, "client_id") }); - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask for client validation"); - } - - // Prepare the request body - Required parameters for OAuth2 client validation - var requestBody = new - { - client_id = context.Body?.client_id, - client_secret = context.Body?.client_secret, - grant_type = context.Body?.grant_type, - scope = context.Body?.scope, - username = context.Body?.username, - password = context.Body?.password - }; - - httpTask.SetBody(requestBody); - - // Set Headers - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Workflow-Instance"] = context.Instance?.Id.ToString() - }; - - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse ()); - } - catch (Exception ex) - { - throw; - //return Task.FromResult(new ScriptResponse ()); - } - } - - /// - /// Process the client authentication result and merge it into the workflow instance - /// - public async Task OutputHandler(ScriptContext context) - { - try - { - var statusCode = GetStatusCodeFromResponse(context); - var responseData = GetResponseDataFromContext(context); - - // Successful verification - if (statusCode >= 200 && statusCode < 300) - { - var clientValidation = new - { - success = true, - validatedAt = DateTime.UtcNow, - clientId = responseData?.clientId, - grantTypes = responseData?.grantTypes, - redirectUris = responseData?.redirectUris, - scopes = responseData?.scopes, - isActive = responseData?.isActive - }; - - return new ScriptResponse - { - Key = "client-validation-success", - Data = new - { - status = "client-validation-success", - clientValidation = clientValidation, - deviceId = context.Headers?["x-device-id"], - requestId = context.Headers?["x-request-id"], - userAgent = context.Headers?["user-agent"], - ipAddress = context.Headers?["x-forwarded-for"] ?? context.Headers?["x-real-ip"] - }, - Tags = new[] { "oauth2", "client-validation", "success", "authenticated" } - }; - } - // Failed verification - else - { - var errorInfo = ExtractErrorInformation(context, statusCode); - - var clientValidation = new - { - success = false, - validatedAt = DateTime.UtcNow, - error = errorInfo.message, - errorCode = errorInfo.code, - errorDescription = errorInfo.description, - statusCode = statusCode - }; - - return new ScriptResponse - { - Key = "client-validation-failure", - Data = new - { - clientValidation = clientValidation - }, - Tags = new[] { "oauth2", "client-validation", "failure", "error" } - }; - } - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "client-validation-output-error", - Data = new - { - clientValidation = new - { - success = false, - error = "Internal processing error", - errorCode = "processing_error", - errorDescription = ex.Message, - validatedAt = DateTime.UtcNow - } - }, - Tags = new[] { "oauth2", "client-validation", "error", "exception" } - }; - } - } - - #region Helper Methods - - private static int GetStatusCodeFromResponse(ScriptContext context) - { - // Get status code from standard response structure - if (context.Body?.statusCode != null) - return (int)context.Body.statusCode; - - // Accept success by default - return 200; - } - - private static dynamic? GetResponseDataFromContext(ScriptContext context) - { - // Get data from Body - if (context.Body?.data != null) - return context.Body.data; - - // Direct body content - if (context.Body != null && context.Body.statusCode == null) - return context.Body; - - return null; - } - - private static (string message, string code, string description) ExtractErrorInformation(ScriptContext context, int statusCode) - { - var errorData = context.Body?.data?.error ?? null; - - string message = "Client validation failed"; - string code = "invalid_client"; - string description = "The client credentials provided are invalid"; - - if (errorData != null) - { - message = errorData.message ?? message; - code = errorData.code ?? code; - description = errorData.description ?? description; - } - else if (statusCode == 401) - { - code = "unauthorized_client"; - description = "Client authentication failed"; - } - else if (statusCode == 403) - { - code = "access_denied"; - description = "Client access denied"; - } - else if (statusCode >= 500) - { - code = "server_error"; - description = "Internal server error during client validation"; - } - - return (message, code, description); - } - - #endregion -} \ No newline at end of file diff --git a/core/Workflows/oauth/src/ValidateUserCredentialsMapping.csx b/core/Workflows/oauth/src/ValidateUserCredentialsMapping.csx deleted file mode 100644 index df59838..0000000 --- a/core/Workflows/oauth/src/ValidateUserCredentialsMapping.csx +++ /dev/null @@ -1,128 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -/// -/// OAuth2 User Credentials Validation Mapping - User credential validation mapping -// This mapping is used to validate user credentials in the OAuth2 password grant flow. -/// -public class ValidateUserCredentialsMapping : IMapping -{ - /// - /// Prepare input for user credential validation request - /// - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask for user credentials validation"); - } - - var requestBody = new - { - username = context.Body?.username ?? context.Body?.email, - password = context.Body?.password - }; - - httpTask.SetBody(requestBody); - - // Set the headers - var headers = new Dictionary - { - ["X-Request-Id"] = context.Instance?.Data?.requestId, - ["Content-Type"] = "application/json" - }; - - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse()); - } - } - - /// - /// Process user authentication result and merge it into the workflow instance - /// - public async Task OutputHandler(ScriptContext context) - { - var response = new ScriptResponse(); - try - { - var statusCode = GetStatusCodeFromResponse(context); - var responseData = GetResponseDataFromContext(context); - - // Successful validation - if (statusCode >= 200 && statusCode < 300) - { - response.Data = new - { - authentication = new - { - success = true, - userId = responseData?.userId, - username = responseData?.username, - email = responseData?.email, - roles = responseData?.roles, - // MFA context - mfaRequired = responseData?.mfaRequired ?? true - } - }; - } - else - { - response.Data = new - { - authentication = new - { - success = false, - error = "Invalid username or password", - errorCode = "invalid_credentials" - } - }; - } - } - catch (Exception ex) - { - response.Data = new - { - authentication = new - { - success = false, - error = "Internal processing error", - errorCode = "processing_error", - errorDescription = ex.Message - } - }; - } - return response; - } - - #region Helper Methods - - private static int GetStatusCodeFromResponse(ScriptContext context) - { - if (context.Body?.statusCode != null) - return (int)context.Body.statusCode; - - return 200; - } - - private static dynamic? GetResponseDataFromContext(ScriptContext context) - { - if (context.Body?.data != null) - return context.Body.data; - - if (context.Body != null && context.Body.statusCode == null) - return context.Body; - - return null; - } - - #endregion -} diff --git a/core/Workflows/oauth/src/VerifyOtpCodeMapping.csx b/core/Workflows/oauth/src/VerifyOtpCodeMapping.csx deleted file mode 100644 index 3815e9e..0000000 --- a/core/Workflows/oauth/src/VerifyOtpCodeMapping.csx +++ /dev/null @@ -1,74 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; -using BBT.Workflow.Definitions; - -public class VerifyOtpCodeMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - var verifyData = new - { - otpId = context.Instance.Data?.otp?.otpId, - otpCode = context.Body.otp_code, - userId = context.Instance.Data?.authentication?.userId, - deviceId = context.Instance?.Data?.deviceId - }; - httpTask.SetBody(verifyData); - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Request-Id"] = context.Instance?.Data?.requestId, - ["X-User-Id"] = context.Instance.Data?.authentication?.userId - }; - httpTask.SetHeaders(headers); - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = new ScriptResponse(); - var statusCode = context.Body.statusCode ?? 500; - - if (statusCode == 200) - { - response.Data = new - { - mfa = new - { - success = true, - otpVerified = true, - method = "otp", - verifiedAt = DateTime.UtcNow.ToString("o") - } - }; - } - else if (statusCode == 400) - { - response.Data = new - { - mfa = new - { - success = false, - error = "Invalid OTP code", - errorCode = "invalid_otp", - attemptsRemaining = context.Body.data?.attemptsRemaining ?? 0 - } - }; - } - else - { - response.Data = new - { - mfa = new - { - success = false, - error = "Server error occurred", - errorCode = "server_error" - } - }; - } - - return response; - } -} \ No newline at end of file diff --git a/core/Workflows/payments/scheduled-payments-workflow.http b/core/Workflows/payments/scheduled-payments-workflow.http deleted file mode 100644 index 26a23dd..0000000 --- a/core/Workflows/payments/scheduled-payments-workflow.http +++ /dev/null @@ -1,157 +0,0 @@ -############################################################################### -# Scheduled Payments Workflow - HTTP Test File -# -# This file tests the scheduled-payments workflow which handles: -# - Payment schedule configuration -# - Automatic payment execution based on schedule -# - Manual payment trigger (pay now) -# - Payment notifications (SMS, Push) -# - Retry logic for failed payments -# -# Prerequisites: -# 1. vNext Runtime running on localhost:4201 -# 2. Mockoon running on localhost:3001 -############################################################################### - -@baseUrl = http://localhost:4201 -@apiVersion = 1 -@domain = core -@workflow = scheduled-payments -@instanceKey = payment-{{$timestamp}} - -############################################################################### -# Step 1: Start Scheduled Payments Workflow -# Creates a new scheduled payment with configuration -############################################################################### - -### Start Scheduled Payment Instance -# @name startPaymentWorkflow -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start?sync=true -Content-Type: application/json -Accept-Language: tr-TR -X-Request-Id: {{$guid}} -X-Device-Id: {{$guid}} -X-Token-Id: {{$guid}} -X-Device-Info: IOS 16 -X-Forwarded-For: 192.168.2.1 - -{ - "key": "{{instanceKey}}", - "tags": [ - "test", - "payment", - "scheduled" - ], - "attributes": { - "userId": 1, - "amount": 12000, - "currency": "TL", - "frequency": "monthly", - "startDate": "2025-10-01T09:02:38.201Z", - "endDate": "2026-10-01T09:02:38.201Z", - "paymentMethodId": "1", - "description": "Monthly payment test", - "recipientId": "324324", - "isAutoRetry": false, - "maxRetries": 3 - } -} - -############################################################################### -# Step 2: Get Instance Data -# Retrieve current workflow instance data -############################################################################### - -### Get Instance Data -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}} -Content-Type: application/json - -### Get Current State -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -############################################################################### -# Step 3: Manual Pay Now -# Trigger immediate payment execution -############################################################################### - -### Pay Now (Manual Trigger) -# @name manualPayNow -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/manual-pay-now?sync=false -Content-Type: application/json - -############################################################################### -# Step 4: Get Current State (Long Polling) -# Check the current state of the workflow -############################################################################### - -### Get Current State -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -############################################################################### -# Step 5: Get Instance Data (After Payment) -# Retrieve all accumulated data including payment results -############################################################################### - -### Get Instance Data After Payment -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -############################################################################### -# Alternative Flows -############################################################################### - -### Cancel Scheduled Payment -# @name cancelPayment -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/cancel-payment?sync=true -Content-Type: application/json - -{ - "attributes": { - "cancelReason": "User requested cancellation", - "cancelledBy": "user-1", - "cancelledAt": "{{$isoTimestamp}}" - } -} - -### Pause Scheduled Payment -# @name pausePayment -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/pause-payment?sync=true -Content-Type: application/json - -{ - "attributes": { - "pauseReason": "Temporary pause requested", - "pausedBy": "user-1" - } -} - -### Resume Scheduled Payment -# @name resumePayment -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/resume-payment?sync=true -Content-Type: application/json - -{ - "attributes": { - "resumedBy": "user-1" - } -} - -############################################################################### -# Scheduled Payments Flow Summary -############################################################################### -# -# | Step | Transition | Description | -# |------|------------------|-------------------------------------------| -# | 1 | start | Create scheduled payment configuration | -# | 2 | (auto) | Validate and save payment configuration | -# | 3a | manual-pay-now | Trigger immediate payment execution | -# | 3b | (scheduled) | Wait for scheduled payment time | -# | 4 | (auto) | Process payment and send notifications | -# | 5a | (success) | Payment successful - archive or reschedule| -# | 5b | (retry) | Payment failed - retry if configured | -# | 6 | cancel-payment | Cancel the scheduled payment | -# -############################################################################### - diff --git a/core/Workflows/self-loop-repro/self-loop-repro-workflow.json b/core/Workflows/self-loop-repro/self-loop-repro-workflow.json deleted file mode 100644 index 704ea73..0000000 --- a/core/Workflows/self-loop-repro/self-loop-repro-workflow.json +++ /dev/null @@ -1,252 +0,0 @@ -{ - "key": "self-loop-repro-workflow", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "self-loop-repro", - "auto-transition", - "target-self", - "rule-invalidation", - "repro" - ], - "attributes": { - "type": "F", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Self-Loop Rule Invalidation Repro Workflow" - }, - { - "language": "tr-TR", - "label": "Self-Loop Kural Geçersizleştirme Repro Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start", - "target": "entry-state", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start" - }, - { - "language": "tr-TR", - "label": "Başlat" - } - ], - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/StartMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTdGFydCBNYXBwaW5nIC0gTWluaW1hbCBpbml0IGZvciBzZWxmLWxvb3AgcmVwcm8gd29ya2Zsb3cKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFN0YXJ0TWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInN0YXJ0ZWQiLAogICAgICAgICAgICBEYXRhID0gbmV3IHsgCiAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csIAogICAgICAgICAgICAgICAgcmVwcm8gPSAic2VsZi1sb29wLXJ1bGUtaW52YWxpZGF0aW9uIiwKICAgICAgICAgICAgICAgIGNvbmRpdGlvbiA9IDEKICAgICAgICAgICAgfQogICAgICAgIH07CiAgICB9Cn0K" - } - } - ] - }, - "states": [ - { - "key": "entry-state", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Entry State" - }, - { - "language": "tr-TR", - "label": "Giriş Durumu" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "go-to-loop", - "target": "loop-state", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Go to Loop State" - }, - { - "language": "tr-TR", - "label": "Döngü Durumuna Git" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "loop-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Loop State (auto target $self + onExecutionTask -> rule invalidated, no 2nd loop)" - }, - { - "language": "tr-TR", - "label": "Döngü Durumu (auto target $self + onExecutionTask -> kural geçersiz, 2. döngü yok)" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "auto-self-loop", - "target": "$self", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Auto Self-Loop (rule invalidated after onExecutionTask)" - }, - { - "language": "tr-TR", - "label": "Otomatik Self-Loop (onExecutionTask sonrası kural geçersiz)" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkIChyZXBybzogaW52YWxpZGF0ZWQgd2hlbiBvbkV4ZWN1dGlvblRhc2sgdGFyZ2V0IGlzIHNlbGYpCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBjb250ZXh0Lkluc3RhbmNlLkRhdGEuY29uZGl0aW9uID09IDE7CiAgICB9Cn0K" - }, - "timer": null, - "view": null, - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/SelfLoopOnExecutionMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTZWxmLWxvb3AgYXV0byB0cmFuc2l0aW9uIG9uRXhlY3V0aW9uVGFzayAtIHRhcmdldCBpcyBzYW1lIHN0YXRlICgkc2VsZikuCi8vLyBSZXByb2R1Y2VzIGNhc2Ugd2hlcmUgdGhpcyBpbnZhbGlkYXRlcyB0aGUgcnVsZSBzbyB0aGUgc3RhdGUgZG9lcyBub3QgbG9vcCBhIHNlY29uZCB0aW1lLgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgU2VsZkxvb3BPbkV4ZWN1dGlvbk1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICB7CiAgICAgICAgICAgIEtleSA9ICJzZWxmLWxvb3AtdGFzay1kb25lIiwKICAgICAgICAgICAgRGF0YSA9IG5ldyB7IAogICAgICAgICAgICAgICAgZXhlY3V0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywgCiAgICAgICAgICAgICAgICBub3RlID0gIm9uRXhlY3V0aW9uVGFzayB0YXJnZXQgaXMgc2VsZiAtPiBydWxlIGludmFsaWRhdGVkLCBubyAybmQgbG9vcCIsCiAgICAgICAgICAgICAgICBjb25kaXRpb24gPSAwCiAgICAgICAgICAgIH0KICAgICAgICB9OwogICAgfQp9Cg==" - } - } - ] - }, - { - "key": "proceed", - "target": "completed", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Proceed" - }, - { - "language": "tr-TR", - "label": "Devam Et" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "reject", - "target": "cancelled", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Cancel" - }, - { - "language": "tr-TR", - "label": "İptal" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "completed", - "stateType": 3, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Completed" - }, - { - "language": "tr-TR", - "label": "Tamamlandı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "cancelled", - "stateType": 3, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Cancelled" - }, - { - "language": "tr-TR", - "label": "İptal Edildi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/self-loop-repro/self-loop-repro.http b/core/Workflows/self-loop-repro/self-loop-repro.http deleted file mode 100644 index 21b9e84..0000000 --- a/core/Workflows/self-loop-repro/self-loop-repro.http +++ /dev/null @@ -1,54 +0,0 @@ -### Self-Loop Rule Invalidation Repro -### Case: Instance start -> manual transition -> target state has 1 auto (target $self) + 2 manual transitions. -### Auto transition's onExecutionTask also targets self -> rule invalidated -> state does NOT loop 2nd time. - -@baseUrl = http://localhost:4201 -@apiVersion = 1 -@domain = core -@workflow = self-loop-repro-workflow -@instanceKey = self-loop-repro-{{$timestamp}} - -### Step 1: Start workflow instance -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start -Content-Type: application/json - -{ - "key": "{{instanceKey}}", - "tags": ["self-loop-repro", "repro"], - "attributes": {} -} - -### Step 2: Get current state (should be "entry-state") -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -### Step 3: Execute manual transition (entry-state -> loop-state) -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/go-to-loop -Content-Type: application/json - -{} - -### Step 4: Get state after manual transition -### Expected: "loop-state". Auto transition (target $self) runs once; onExecutionTask makes rule invalid -> no 2nd loop. -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -### Step 5: Get instance data (verify self-loop task ran once) -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -### Step 6a: Proceed (manual) -> completed -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/proceed -Content-Type: application/json - -{} - -### Step 6b: Or cancel (manual) -> cancelled -# PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/cancel -# Content-Type: application/json -# -# {} - -### Step 7: Final state -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json diff --git a/core/Workflows/self-loop-repro/src/AlwaysTrueRule.csx b/core/Workflows/self-loop-repro/src/AlwaysTrueRule.csx deleted file mode 100644 index eccc254..0000000 --- a/core/Workflows/self-loop-repro/src/AlwaysTrueRule.csx +++ /dev/null @@ -1,13 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Always True Rule - Used for auto transitions that should always proceed (repro: invalidated when onExecutionTask target is self) -/// -public class AlwaysTrueRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return context.Instance.Data.condition == 1; - } -} diff --git a/core/Workflows/self-loop-repro/src/SelfLoopOnExecutionMapping.csx b/core/Workflows/self-loop-repro/src/SelfLoopOnExecutionMapping.csx deleted file mode 100644 index feff0dc..0000000 --- a/core/Workflows/self-loop-repro/src/SelfLoopOnExecutionMapping.csx +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Self-loop auto transition onExecutionTask - target is same state ($self). -/// Reproduces case where this invalidates the rule so the state does not loop a second time. -/// -public class SelfLoopOnExecutionMapping : ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - return new ScriptResponse - { - Key = "self-loop-task-done", - Data = new { - executedAt = DateTime.UtcNow, - note = "onExecutionTask target is self -> rule invalidated, no 2nd loop", - condition = 0 - } - }; - } -} diff --git a/core/Workflows/self-loop-repro/src/StartMapping.csx b/core/Workflows/self-loop-repro/src/StartMapping.csx deleted file mode 100644 index 67e2b6d..0000000 --- a/core/Workflows/self-loop-repro/src/StartMapping.csx +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Start Mapping - Minimal init for self-loop repro workflow -/// -public class StartMapping : ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - return new ScriptResponse - { - Key = "started", - Data = new { - startedAt = DateTime.UtcNow, - repro = "self-loop-rule-invalidation", - condition = 1 - } - }; - } -} diff --git a/core/Workflows/subflow-test/.meta/subflow-view-test-parent.diagram.json b/core/Workflows/subflow-test/.meta/subflow-view-test-parent.diagram.json index aee3fb7..edd1cd1 100644 --- a/core/Workflows/subflow-test/.meta/subflow-view-test-parent.diagram.json +++ b/core/Workflows/subflow-test/.meta/subflow-view-test-parent.diagram.json @@ -5,16 +5,16 @@ "y": 100 }, "waiting-for-subflow": { - "x": 496, - "y": 100 + "x": 420, + "y": -120 }, "parent-after-subflow": { - "x": 892, - "y": 100 + "x": 780, + "y": 180 }, "parent-completed": { - "x": 1288, - "y": 100 + "x": 1360, + "y": 140 }, "__start__": { "x": -296, diff --git a/core/Workflows/subflow-test/BUSY-STATE-TEST-README.md b/core/Workflows/subflow-test/BUSY-STATE-TEST-README.md deleted file mode 100644 index a637b4f..0000000 --- a/core/Workflows/subflow-test/BUSY-STATE-TEST-README.md +++ /dev/null @@ -1,226 +0,0 @@ -# Busy State Test Implementation - -## Overview - -This document describes the implementation of the Busy state test feature in the grandchild workflow. The test demonstrates the new `subType: 5` (Busy) state functionality. - -## New State subType Values - -- **Busy: 5** - State is busy processing, waiting for external trigger -- **Human: 6** - State is waiting for human interaction - -## Test Objective - -Test the Busy state behavior where: -1. A workflow enters a Busy state (`subType: 5`) -2. The state launches a subprocess that runs independently -3. The workflow waits in Busy state for the subprocess to complete -4. The subprocess triggers a transition on the parent workflow when complete -5. The parent workflow exits Busy state and continues normal flow - -## Expected Behavior - -``` -State enters → Status: BUSY → Waits → SubProcess completes → SubProcess pings parent → Transition occurs → State changes -``` - -## Components Created - -### 1. Tasks - -#### `start-busy-subprocess-task.json` -- **Type**: 11 (SubProcessTask) -- **Purpose**: Launches the busy subprocess workflow -- **Location**: `core/Tasks/subflow-test/start-busy-subprocess-task.json` - -#### `trigger-busy-completion-task.json` -- **Type**: 12 (DirectTriggerTask) -- **Purpose**: Triggers transition on parent workflow from subprocess -- **Location**: `core/Tasks/subflow-test/trigger-busy-completion-task.json` - -### 2. Workflows - -#### `busy-subprocess-workflow.json` -- **Purpose**: Independent subprocess that runs while parent is in Busy state -- **States**: - - `processing` (Initial) - Subprocess starts and processes - - `trigger-parent` (Intermediate) - Triggers parent workflow transition - - `completed` (Final) - Subprocess completes -- **Location**: `core/Workflows/subflow-test/busy-subprocess-workflow.json` - -### 3. Mappings - -#### `StartBusySubprocessMapping.csx` -- **Purpose**: Configures and launches the subprocess -- **Task**: SubProcessTask (Type 11) -- **Actions**: - - Sets subprocess domain, flow, and key - - Passes parent instance ID to subprocess - - Prepares subprocess initialization data - -#### `BusySubprocessStartMapping.csx` -- **Purpose**: Initializes subprocess instance -- **Actions**: - - Stores parent instance information - - Prepares subprocess data - -#### `TriggerParentBusyCompletionMapping.csx` -- **Purpose**: Triggers parent workflow transition from subprocess -- **Task**: DirectTriggerTask (Type 12) -- **Actions**: - - Sets target instance (parent workflow) - - Sets transition name (`complete-busy-state`) - - Prepares transition payload with completion data - -### 4. Workflow States - -#### Modified `subflow-view-test-grandchild.json` - -Added new states: - -**State: `grandchild-busy`** -- **Type**: Intermediate (2) -- **SubType**: Busy (5) ⚠️ NEW FEATURE -- **OnEntry**: Launches subprocess via `start-busy-subprocess-task` -- **Transition**: `complete-busy-state` - Manual transition triggered by subprocess - -**State: `grandchild-after-busy`** -- **Type**: Intermediate (2) -- **SubType**: Normal (0) -- **Purpose**: Continues workflow after busy state completes - -## Workflow Flow - -```mermaid -graph TD - A[grandchild-active] -->|enter-busy-state| B[grandchild-busy
subType: 5 - BUSY] - B -->|onEntry: Launch SubProcess| C[busy-subprocess-workflow] - C -->|processing| D[trigger-parent state] - D -->|DirectTriggerTask| E[Trigger: complete-busy-state] - E -->|Transition| F[grandchild-after-busy] - F -->|complete-grandchild| G[grandchild-completed] -``` - -## Testing Steps - -See `subflow-view-test.http` for complete test sequence. Key steps: - -1. **Step 17**: Trigger `enter-busy-state` transition -2. **Step 18**: Verify state is `grandchild-busy` with `subType: 5` -3. **Step 19**: Check data shows subprocess launched -4. **Step 20**: Wait ~5-10 seconds for subprocess to complete -5. **Step 21**: Verify state automatically changed to `grandchild-after-busy` -6. **Step 22**: Check data shows subprocess completion and trigger info -7. **Step 23**: Complete grandchild workflow normally - -## API Endpoints Used - -### Start Busy State -```http -PATCH http://localhost:4201/api/v1/core/workflows/subflow-view-test-grandchild/instances/{instanceId}/transitions/enter-busy-state -``` - -### Check State (Should show BUSY status) -```http -GET http://localhost:4201/api/v1/core/workflows/subflow-view-test-grandchild/instances/{instanceId}/functions/state -``` - -### Get Instance Data -```http -GET http://localhost:4201/api/v1/core/workflows/subflow-view-test-grandchild/instances/{instanceId}/functions/data -``` - -## Task Types Reference - -### SubProcessTask (Type 11) -- Fire-and-forget subprocess launch -- Subprocess runs independently -- Parent doesn't wait for subprocess completion -- Used in: `start-busy-subprocess-task` - -### DirectTriggerTask (Type 12) -- Triggers specific transition on existing workflow instance -- Requires target instance ID and transition name -- Used in: `trigger-busy-completion-task` - -## Expected Data Flow - -### When Entering Busy State - -```json -{ - "subprocessLaunched": true, - "subprocessInstanceId": "uuid", - "launchedAt": "timestamp", - "status": "BUSY" -} -``` - -### When SubProcess Triggers Parent - -```json -{ - "transitionTriggered": true, - "triggeredAt": "timestamp", - "parentNewState": "grandchild-after-busy", - "status": "PARENT_TRANSITION_SUCCESS", - "result": { - "subprocessCompleted": true, - "busyStateTestPassed": true - } -} -``` - -## Known Issues - -### Schema Validation - -The `subType: 5` value currently fails schema validation because it's a new feature under development: - -``` -Schema validation failed for workflow: -/attributes/states/1/subType: must be equal to one of the allowed values (line 74) ({"allowedValues":[0,1,2,3,4]}) -``` - -**Resolution**: The `@burgan-tech/vnext-schema` package needs to be updated to include: -- `Busy: 5` -- `Human: 6` - -Once the schema is updated, validation will pass. - -## Files Modified/Created - -### Created Files -- `core/Tasks/subflow-test/start-busy-subprocess-task.json` -- `core/Tasks/subflow-test/trigger-busy-completion-task.json` -- `core/Workflows/subflow-test/busy-subprocess-workflow.json` -- `core/Workflows/subflow-test/src/StartBusySubprocessMapping.csx` -- `core/Workflows/subflow-test/src/BusySubprocessStartMapping.csx` -- `core/Workflows/subflow-test/src/TriggerParentBusyCompletionMapping.csx` - -### Modified Files -- `core/Workflows/subflow-test/subflow-view-test-grandchild.json` - Added busy state and transitions -- `core/Workflows/subflow-test/subflow-view-test.http` - Added busy state test steps - -## Architecture Benefits - -1. **State Awareness**: Runtime knows the state is busy (subType: 5) -2. **Status Tracking**: Can monitor busy states across all workflows -3. **Independent Processing**: Subprocess runs without blocking -4. **Automatic Transition**: Subprocess triggers parent when ready -5. **Flexible Pattern**: Can be used for any long-running operation - -## Use Cases - -This pattern is useful for: -- Long-running background processes -- External API calls with callbacks -- Async processing workflows -- Human approval processes (with subType: 6) -- Queue-based processing - -## Related Documentation - -- vNext Runtime Docs: TriggerTask types (SubProcess, DirectTrigger) -- State lifecycle and subTypes -- Transition trigger types diff --git a/core/Workflows/subflow-test/src/ParentInitialGetInstanceDataMapping.csx b/core/Workflows/subflow-test/src/ParentInitialGetInstanceDataMapping.csx new file mode 100644 index 0000000..f8e42f8 --- /dev/null +++ b/core/Workflows/subflow-test/src/ParentInitialGetInstanceDataMapping.csx @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using BBT.Workflow.Scripting; +using BBT.Workflow.Definitions; + +/// +/// Parent Initial - Get Instance Data Mapping +/// Fetches instance data from account-opening workflow on entry of parent-initial state. +/// +public class ParentInitialGetInstanceDataMapping : IMapping +{ + public Task InputHandler(WorkflowTask task, ScriptContext context) + { + var triggerTask = (task as GetInstanceDataTask)!; + + triggerTask.SetInstance("50044086189"); + + return Task.FromResult(new ScriptResponse()); + } + + public Task OutputHandler(ScriptContext context) + { + return Task.FromResult(new ScriptResponse() + { + Data = new + { + accountOpeningSnapshot = context.Body, + fetchedAt = System.DateTime.UtcNow + } + }); + } +} diff --git a/core/Workflows/subflow-test/subflow-view-test-parent.json b/core/Workflows/subflow-test/subflow-view-test-parent.json index 8d4a298..6d8bd2f 100644 --- a/core/Workflows/subflow-test/subflow-view-test-parent.json +++ b/core/Workflows/subflow-test/subflow-view-test-parent.json @@ -148,7 +148,21 @@ ] }, "subFlow": null, - "onEntries": [], + "onEntries": [ + { + "order": 1, + "task": { + "key": "get-data-from-workflow", + "domain": "core", + "version": "1.0.0", + "flow": "sys-tasks" + }, + "mapping": { + "location": "./src/ParentInitialGetInstanceDataMapping.csx", + "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gUGFyZW50IEluaXRpYWwgLSBHZXQgSW5zdGFuY2UgRGF0YSBNYXBwaW5nCi8vLyBGZXRjaGVzIGluc3RhbmNlIGRhdGEgZnJvbSBhY2NvdW50LW9wZW5pbmcgd29ya2Zsb3cgb24gZW50cnkgb2YgcGFyZW50LWluaXRpYWwgc3RhdGUuCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBQYXJlbnRJbml0aWFsR2V0SW5zdGFuY2VEYXRhTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgdHJpZ2dlclRhc2sgPSAodGFzayBhcyBHZXRJbnN0YW5jZURhdGFUYXNrKSE7CgogICAgICAgIHRyaWdnZXJUYXNrLlNldEluc3RhbmNlKCI1MDA0NDA4NjE4OSIpOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKQogICAgICAgIHsKICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhY2NvdW50T3BlbmluZ1NuYXBzaG90ID0gY29udGV4dC5Cb2R5LAogICAgICAgICAgICAgICAgZmV0Y2hlZEF0ID0gU3lzdGVtLkRhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9Cn0K" + } + } + ], "onExits": [], "queryRoles": [ { diff --git a/core/Workflows/subflow-test/subflow-view-test.http b/core/Workflows/subflow-test/subflow-view-test.http deleted file mode 100644 index aa33316..0000000 --- a/core/Workflows/subflow-test/subflow-view-test.http +++ /dev/null @@ -1,433 +0,0 @@ -### SubFlow View & Extension Test - 3 Level Nested SubFlows -### This file tests the longpolling view endpoint with deep nested subflows, views and extensions -### Test Goal: Verify that views and extensions work correctly for parent, child, and grandchild workflows -### -### Hierarchy: Parent (Level 1) > Child (Level 2) > Grandchild (Level 3) - -@baseUrl = http://localhost:4201 -@apiVersion = 1 -@domain = core -@parentWorkflow = subflow-view-test-parent -@childWorkflow = subflow-view-test-child -@grandchildWorkflow = subflow-view-test-grandchild -@instanceKey = subflow-test-{{$timestamp}} - -### ============================================ -### STEP 1: Start Parent Workflow (Level 1) -### This starts the parent workflow in initial state -### ============================================ - -# @name startParent -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/start -Content-Type: application/json - -{ - "key": "{{instanceKey}}", - "tags": ["subflow-test", "view-test", "extension-test", "longpolling-test", "3-level-nested"], - "attributes": { - "testId": "subflow-view-extension-test-001", - "testDescription": "Testing 3-level nested subflows with view and extension", - "createdAt": "{{$datetime iso8601}}" - } -} - -### ============================================ -### STEP 2: Get Parent Workflow State (Long Polling) -### Check current state of parent workflow - should be "parent-initial" -### ============================================ - -# @name getParentState -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -### ============================================ -### STEP 3: Get Parent View with Extensions (Level 1) -### THIS IS THE KEY LONGPOLLING TEST FOR PARENT -### Expected: parent-workflow-view with parent-data-extension data -### ============================================ - -# @name getParentView -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/view -Accept: application/json - -### ============================================ -### STEP 4: Get Parent Data to verify extensions loaded -### ============================================ - -# @name getParentData -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -### ============================================ -### STEP 5: Execute Transition to Start SubFlow (Parent -> Child) -### This triggers the child subflow state - parent will wait for child -### ============================================ - -# @name startChildSubflow -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/transitions/start-subflow -Content-Type: application/json - -{ - "message": "Starting child subflow for 3-level nested test" -} - -### ============================================ -### STEP 6: Get Parent State After SubFlow Started -### The parent should be in "waiting-for-subflow" state now -### ============================================ - -# @name getParentStateAfterSubflow -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -### ============================================ -### STEP 6b: [Issue #425] Parent shared transition (target $self) while in subflow -### Call parent's shared transition on PARENT instance while it is in "waiting-for-subflow". -### Expected: Parent flow handles the transition (shared-transition policy); data merged into parent. -### ============================================ - -# @name parentSharedUpdate -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/transitions/parent-shared-update -Content-Type: application/json - -{ - "message": "Update from client while parent is in subflow (issue #425)", - "value": 42 -} - -### ============================================ -### STEP 7: Get Parent Data to Find Child Instance ID -### Check parent data to find child instance ID (and sharedUpdateFromParent from step 6b) -### ============================================ - -# @name getParentDataForChildId -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -### ============================================ -### STEP 8: Get Child View with Extensions (Level 2) -### THIS IS THE KEY LONGPOLLING TEST FOR CHILD -### Expected: child-workflow-view with child-data-extension data -### Note: Replace {{childInstanceId}} with actual child instance ID from previous step -### ============================================ - -@childInstanceId = REPLACE_WITH_CHILD_INSTANCE_ID - -# @name getChildView -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/view -Accept: application/json - -### ============================================ -### STEP 9: Get Child State -### Child should be in "child-initial" state -### ============================================ - -# @name getChildState -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/state -Accept: application/json - -### ============================================ -### STEP 10: Get Child Data -### ============================================ - -# @name getChildData -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/data -Accept: application/json - -### ============================================ -### STEP 11: Start Grandchild SubFlow (Child -> Grandchild) -### This triggers the grandchild subflow state - child will wait for grandchild -### ============================================ - -# @name startGrandchildSubflow -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/transitions/start-grandchild-subflow -Content-Type: application/json - -{ - "message": "Starting grandchild subflow for deep nested test" -} - -### ============================================ -### STEP 12: Get Child State After Grandchild SubFlow Started -### Child should be in "waiting-for-grandchild" state now -### ============================================ - -# @name getChildStateAfterGrandchild -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/state -Accept: application/json - -### ============================================ -### STEP 12b: [Issue #425] Child shared transition (target $self) while in grandchild subflow -### Call child's shared transition on CHILD instance while it is in "waiting-for-grandchild". -### Expected: Child flow handles the transition; data merged into child. -### ============================================ - -# @name childSharedUpdate -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/transitions/child-shared-update -Content-Type: application/json - -{ - "message": "Update from client while child is in grandchild subflow (issue #425)", - "value": 100 -} - -### ============================================ -### STEP 13: Get Child Data to Find Grandchild Instance ID -### Check child data to find grandchild instance ID (and sharedUpdateFromChild from step 12b) -### ============================================ - -# @name getChildDataForGrandchildId -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/data -Accept: application/json - -### ============================================ -### STEP 14: Get Grandchild View with Extensions (Level 3) -### THIS IS THE KEY LONGPOLLING TEST FOR GRANDCHILD (DEEPEST LEVEL) -### Expected: grandchild-workflow-view with grandchild-data-extension data -### Note: Replace {{grandchildInstanceId}} with actual grandchild instance ID from previous step -### ============================================ - -@grandchildInstanceId = REPLACE_WITH_GRANDCHILD_INSTANCE_ID - -# @name getGrandchildView -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/view -Accept: application/json - -### ============================================ -### STEP 15: Get Grandchild State -### Grandchild should be in "grandchild-active" state -### ============================================ - -# @name getGrandchildState -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/state -Accept: application/json - -### ============================================ -### STEP 16: Get Grandchild Data -### ============================================ - -# @name getGrandchildData -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/data -Accept: application/json - -### ============================================ -### STEP 17: Enter Busy State (Busy State Test - subType: 5) -### This transitions grandchild to busy state and starts a subprocess -### The subprocess will trigger the transition when complete -### ============================================ - -# @name enterBusyState -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/transitions/enter-busy-state -Content-Type: application/json - -{ - "message": "Entering busy state - subprocess will be launched" -} - -### ============================================ -### STEP 18: Check Grandchild State - Should be BUSY (subType: 5) -### The state should be "grandchild-busy" with subType: 5 -### The subprocess should be running in background -### ============================================ - -# @name getGrandchildBusyState -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/state -Accept: application/json - -### ============================================ -### STEP 19: Get Grandchild Data During Busy State -### Should show subprocess launched and busy status -### ============================================ - -# @name getGrandchildDataDuringBusy -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/data -Accept: application/json - -### ============================================ -### STEP 20: Wait for SubProcess to Complete and Trigger Transition -### The subprocess (busy-subprocess-workflow) will: -### 1. Complete its processing -### 2. Use DirectTriggerTask to trigger 'complete-busy-state' transition -### 3. Grandchild will automatically move to 'grandchild-after-busy' state -### -### NOTE: Wait ~5-10 seconds for subprocess to complete -### Then check state again to verify automatic transition occurred -### ============================================ - -### ============================================ -### STEP 21: Verify Grandchild Transitioned Out of Busy State -### The state should now be "grandchild-after-busy" (subType: 0) -### This confirms the subprocess successfully triggered the transition -### ============================================ - -# @name getGrandchildStateAfterBusy -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/state -Accept: application/json - -### ============================================ -### STEP 22: Get Grandchild Data After Busy State -### Should show subprocess completion data and trigger info -### ============================================ - -# @name getGrandchildDataAfterBusy -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/functions/data -Accept: application/json - -### ============================================ -### STEP 23: Complete Grandchild Workflow (Level 3 -> Level 2) -### Now complete the grandchild workflow normally -### This will trigger the grandchild completion and unblock child -### ============================================ - -# @name completeGrandchild -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{grandchildWorkflow}}/instances/{{grandchildInstanceId}}/transitions/complete-grandchild -Content-Type: application/json - -{ - "completionMessage": "Grandchild workflow completed after busy state test" -} - -### ============================================ -### STEP 24: Check Child State After Grandchild Completed -### Child should now be in "child-after-grandchild" state -### ============================================ - -# @name getChildStateAfterGrandchildComplete -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/state -Accept: application/json - -### ============================================ -### STEP 25: Get Child View After Grandchild SubFlow -### Verify view and extensions still work after grandchild subflow completes -### ============================================ - -# @name getChildViewAfterGrandchild -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/functions/view -Accept: application/json - -### ============================================ -### STEP 26: Complete Child Workflow (Level 2 -> Level 1) -### This will trigger the child completion and unblock parent -### ============================================ - -# @name completeChild -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{childWorkflow}}/instances/{{childInstanceId}}/transitions/complete-child -Content-Type: application/json - -{ - "completionMessage": "Child workflow completed for nested test" -} - -### ============================================ -### STEP 27: Check Parent State After Child Completed -### Parent should now be in "parent-after-subflow" state -### ============================================ - -# @name getParentStateAfterChildComplete -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -### ============================================ -### STEP 28: Get Parent View After SubFlow (should show again) -### Verify view and extensions still work after child subflow completes -### ============================================ - -# @name getParentViewAfterSubflow -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/view -Accept: application/json - -### ============================================ -### STEP 29: Complete Parent Workflow (Level 1 Final) -### Final transition to complete the parent workflow -### ============================================ - -# @name completeParent -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/transitions/proceed-after-subflow -Content-Type: application/json - -{ - "finalMessage": "Parent workflow completed successfully with 3-level nested subflows and busy state test" -} - -### ============================================ -### STEP 30: Verify Final State -### Parent should be completed -### ============================================ - -# @name getFinalParentState -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -### ============================================ -### STEP 31: Get Final Data -### Check all test results in the data -### ============================================ - -# @name getFinalData -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{parentWorkflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -### ============================================ -### TEST SUMMARY -### ============================================ -### -### Test Objectives: -### 1. Parent workflow starts with own view and extensions (Level 1) -### 2. Parent view returns with parent-data-extension data -### 3. Parent transitions to child subflow state (blocking) -### 4. Child workflow starts with own view and extensions (Level 2) -### 5. Child view returns with child-data-extension data -### 6. Child transitions to grandchild subflow state (blocking) -### 7. Grandchild workflow has its own view and extensions (Level 3 - Deepest) -### 8. Grandchild view returns with grandchild-data-extension data -### 9. **NEW** Grandchild enters Busy state (subType: 5) -### 10. **NEW** Busy state launches subprocess (SubProcessTask - Type 11) -### 11. **NEW** Grandchild waits in Busy state for subprocess -### 12. **NEW** SubProcess completes and triggers parent transition (DirectTriggerTask - Type 12) -### 13. **NEW** Grandchild automatically exits Busy state via triggered transition -### 14. Grandchild workflow completes via manual transition -### 15. Child unblocks and continues after grandchild completes -### 16. Child view still works after grandchild subflow -### 17. Child workflow completes via manual transition -### 18. Parent unblocks and continues after child completes -### 19. Parent view still works after child subflow -### 20. Parent completes via manual transition -### -### Workflow Hierarchy: -### ================== -### Level 1: subflow-view-test-parent -### | -### +-- Level 2: subflow-view-test-child -### | -### +-- Level 3: subflow-view-test-grandchild -### -### Key Endpoints Tested: -### - /functions/view - Long polling for view with extensions (all 3 levels) -### - /functions/state - Long polling for state (all 3 levels) -### - /functions/data - Instance data retrieval (all 3 levels) -### - /transitions/{key} - Manual transition execution (all 3 levels) -### -### Expected Extension Data in View Response: -### - Parent: parentExtension.data.parentConfig, parentExtension.data.parentMetadata -### - Child: childExtension.data.childConfig, childExtension.data.childMetadata -### - Grandchild: grandchildExtension.data.grandchildConfig, grandchildExtension.data.grandchildMetadata -### -### Busy State Test Details: -### ======================== -### - State subType: 5 (Busy) - New state subType for busy/processing states -### - OnEntry Task: SubProcessTask (Type 11) - Launches independent subprocess -### - SubProcess Workflow: busy-subprocess-workflow -### - SubProcess Actions: -### 1. Starts and enters "processing" state -### 2. Auto-transitions to "trigger-parent" state -### 3. Uses DirectTriggerTask (Type 12) to trigger parent's 'complete-busy-state' transition -### 4. Auto-transitions to "completed" final state -### - Expected Behavior: -### - Grandchild enters busy state → status becomes BUSY -### - SubProcess launches in background (fire-and-forget) -### - Grandchild waits for manual transition (triggered by subprocess) -### - SubProcess completes → triggers grandchild transition -### - Grandchild exits busy state → continues normal flow -### - Demonstrates: State enters → Busy → Waits → SubProcess pings → Transition → State changes -### - diff --git a/core/Workflows/task-test/.meta/error-boundary-test-workflow.diagram.json b/core/Workflows/task-test/.meta/error-boundary-test-workflow.diagram.json deleted file mode 100644 index 98f35d2..0000000 --- a/core/Workflows/task-test/.meta/error-boundary-test-workflow.diagram.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "nodePos": { - "test-task-boundary": { - "x": 100, - "y": 100 - }, - "test-state-boundary": { - "x": 657, - "y": 100 - }, - "test-subflow-boundary": { - "x": 1223, - "y": 100 - }, - "test-retry-policies": { - "x": 1753, - "y": 100 - }, - "test-timeout-policy": { - "x": 2220, - "y": 100 - }, - "test-notify-action": { - "x": 2687, - "y": 100 - }, - "error-recovery": { - "x": 1688.1517994375395, - "y": 492.0221499891834 - }, - "rollback-state": { - "x": 2579, - "y": 500 - }, - "timeout-state": { - "x": 2719, - "y": 700 - }, - "manual-review": { - "x": 2678, - "y": 300 - }, - "success": { - "x": 3145, - "y": 200 - }, - "failed": { - "x": 3005, - "y": 500 - }, - "__start__": { - "x": -296, - "y": 100 - } - } -} \ No newline at end of file diff --git a/core/Workflows/task-test/.meta/task-test-subflow.diagram.json b/core/Workflows/task-test/.meta/task-test-subflow.diagram.json deleted file mode 100644 index bd51d28..0000000 --- a/core/Workflows/task-test/.meta/task-test-subflow.diagram.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "nodePos": { - "subflow-active": { - "x": 100, - "y": 100 - }, - "subflow-completed": { - "x": 526, - "y": 100 - }, - "__start__": { - "x": -296, - "y": 100 - } - } -} \ No newline at end of file diff --git a/core/Workflows/task-test/.meta/task-test-workflow.diagram.json b/core/Workflows/task-test/.meta/task-test-workflow.diagram.json deleted file mode 100644 index 8a1236f..0000000 --- a/core/Workflows/task-test/.meta/task-test-workflow.diagram.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "nodePos": { - "test-get-secret-state": { - "x": 100, - "y": 100 - }, - "test-get-config-state": { - "x": 567, - "y": 100 - }, - "test-dapr-pubsub-state": { - "x": 1034, - "y": 100 - }, - "test-http-items-state": { - "x": 1484, - "y": 100 - }, - "test-http-task-state": { - "x": 1951, - "y": 100 - }, - "test-dapr-service-state": { - "x": 2387, - "y": 100 - }, - "test-notification-state": { - "x": 2863, - "y": 100 - }, - "test-script-state": { - "x": 3348, - "y": 100 - }, - "test-start-workflow-state": { - "x": 3779, - "y": 100 - }, - "test-get-instance-data-state": { - "x": 4300, - "y": 100 - }, - "test-direct-transition-state": { - "x": 4792, - "y": 100 - }, - "test-subprocess-state": { - "x": 5284, - "y": 100 - }, - "all-tests-completed": { - "x": 5727, - "y": 100 - }, - "__start__": { - "x": -296, - "y": 100 - } - } -} \ No newline at end of file diff --git a/core/Workflows/task-test/error-boundary-subflow.json b/core/Workflows/task-test/error-boundary-subflow.json deleted file mode 100644 index d435a2c..0000000 --- a/core/Workflows/task-test/error-boundary-subflow.json +++ /dev/null @@ -1,152 +0,0 @@ -{ - "key": "error-boundary-subflow", - "flow": "sys-flows", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "error-boundary", - "subflow", - "test", - "error-propagation" - ], - "attributes": { - "type": "S", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Error Boundary SubFlow Test" - }, - { - "language": "tr-TR", - "label": "ErrorBoundary SubFlow Testi" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-error-subflow", - "target": "subflow-error-state", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Error SubFlow" - }, - { - "language": "tr-TR", - "label": "Hata SubFlow'unu Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "subflow-error-state", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "SubFlow Error State" - }, - { - "language": "tr-TR", - "label": "SubFlow Hata State'i" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "error-boundary-abort-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/SubFlowErrorMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTdWJGbG93IEVycm9yIE1hcHBpbmcgLSBUZXN0cyBTdWJGbG93IGVycm9yIGhhbmRsaW5nIHdpdGggZXJyb3IgcHJvcGFnYXRpb24KLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFN1YkZsb3dFcnJvck1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgICAgICBpZiAoaHR0cFRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICB2YXIgcmVxdWVzdEJvZHkgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVzdElkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udGVzdElkID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICB0ZXN0VHlwZSA9ICJzdWJmbG93LWVycm9yIiwKICAgICAgICAgICAgICAgIHRpbWVzdGFtcCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSAiVGVzdGluZyBTdWJGbG93IGVycm9yIHByb3BhZ2F0aW9uIHRvIHBhcmVudCB3b3JrZmxvdyIKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGh0dHBUYXNrLlNldEJvZHkocmVxdWVzdEJvZHkpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAic3ViZmxvdy1lcnJvci1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInN1YmZsb3ctZXJyb3ItaGFuZGxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3ViRmxvd0Vycm9yUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSByZXNwb25zZT8uc3RhdHVzQ29kZSA/PyA1MDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yUHJvcGFnYXRlZCA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3RUeXBlID0gIlN1YkZsb3cgRXJyb3IgUHJvcGFnYXRpb24gVGVzdCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJlcnJvci1ib3VuZGFyeS10ZXN0IiwgInN1YmZsb3ctZXJyb3IiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInN1YmZsb3ctZXJyb3ItZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "subflow-completed", - "target": "subflow-success", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "SubFlow Completed" - }, - { - "language": "tr-TR", - "label": "SubFlow Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "subflow-success", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "SubFlow Success" - }, - { - "language": "tr-TR", - "label": "SubFlow Başarılı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - }, - { - "key": "subflow-failed", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "SubFlow Failed" - }, - { - "language": "tr-TR", - "label": "SubFlow Başarısız" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/task-test/error-boundary-test-workflow.http b/core/Workflows/task-test/error-boundary-test-workflow.http deleted file mode 100644 index b1c7b29..0000000 --- a/core/Workflows/task-test/error-boundary-test-workflow.http +++ /dev/null @@ -1,186 +0,0 @@ -### ============================================================== -### ErrorBoundary Test Workflow - HTTP Test File -### ============================================================== -### Bu dosya ErrorBoundary feature'ının tüm senaryolarını test eder. -### Test Senaryoları: -### 1. Task-Level ErrorBoundary (Retry, Abort) -### 2. State-Level ErrorBoundary (Ignore, Rollback) -### 3. SubFlow ErrorBoundary (Error Propagation) -### 4. Retry Policies (Fixed, Exponential Backoff) -### 5. Timeout Policy -### 6. Notify Action -### 7. Global ErrorBoundary -### ============================================================== - -@baseUrl = http://localhost:4201 -@apiVersion = 1 -@domain = core -@workflow = error-boundary-test-workflow -@instanceKey = error-boundary-test-{{$timestamp}} - -### ============================================================== -### STEP 1: Start the ErrorBoundary Test Workflow -### ============================================================== -### Bu adım workflow'u başlatır ve test-task-boundary state'ine geçer. -### Global ErrorBoundary aktiftir ve tüm beklenmeyen hatalar için -### Notify ve Log action'ları tanımlıdır. - -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start -Content-Type: application/json - -{ - "key": "{{instanceKey}}", - "tags": ["error-boundary-test", "test"], - "attributes": { - "testId": "eb-test-{{$timestamp}}", - "testStartedAt": "{{$datetime rfc1123}}", - "testScenarios": [ - "task-boundary-retry", - "task-boundary-abort", - "state-boundary-ignore", - "state-boundary-rollback", - "subflow-error-propagation", - "retry-policies", - "timeout-policy", - "notify-action" - ] - } -} - -### ============================================================== -### STEP 2: Get Current State (Long Polling) -### ============================================================== -### Workflow'un mevcut durumunu kontrol eder. - -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state - -### ============================================================== -### STEP 3: Get Instance Data -### ============================================================== -### Workflow instance verisini alır. - -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data - -### ============================================================== -### SCENARIO: Test Task-Level Retry (503 Error with Exponential Backoff) -### ============================================================== -### test-task-boundary state'inde 503 hatası simüle edilir. -### Task-level ErrorBoundary ile retry policy devreye girer: -### - maxRetries: 3 -### - initialDelay: 1s -### - backoffType: Exponential -### - backoffMultiplier: 2.0 - -### Not: Bu senaryo otomatik olarak çalışır, kullanıcı müdahalesi gerekmez. -### Retry sonuçlarını instance data'da görebilirsiniz. - -### ============================================================== -### SCENARIO: Test State-Level Ignore (400 Error) -### ============================================================== -### test-state-boundary state'inde 400 hatası oluşur. -### State-level ErrorBoundary tanımına göre: -### - action: Ignore (3) -### - errorCodes: [400, 404, 422] -### Hata ignore edilir ve workflow devam eder. - -### ============================================================== -### SCENARIO: Test SubFlow Error Propagation -### ============================================================== -### test-subflow-boundary state'inde SubFlow çağrılır. -### SubFlow içinde hata oluştuğunda: -### - SubFlowErrorPolicy.propagateToParent: true -### - SubFlowErrorPolicy.includeChildErrorDetails: true -### - SubFlowErrorPolicy.parentTransition: "subflow-error-recovery" -### Hata parent workflow'a iletilir. - -### ============================================================== -### SCENARIO: Test Timeout Policy -### ============================================================== -### test-timeout-policy state'inde timeout simüle edilir. -### State-level ErrorBoundary.onTimeout ayarı: -### - action: Abort -### - transition: "timeout-state" -### - defaultRetryPolicy ile önce retry denenir - -### ============================================================== -### ALTERNATIVE FLOW: Manual Review Transition (Review Approved) -### ============================================================== -### Eğer workflow manual-review state'ine geçtiyse: - -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/review-approved -Content-Type: application/json - -{ - "reviewedBy": "admin", - "reviewedAt": "{{$datetime rfc1123}}", - "decision": "approved", - "notes": "Error reviewed and approved for continuation" -} - -### ============================================================== -### ALTERNATIVE FLOW: Manual Review Transition (Review Rejected) -### ============================================================== -### Eğer workflow manual-review state'ine geçtiyse ve red kararı: - -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/transitions/review-rejected -Content-Type: application/json - -{ - "reviewedBy": "admin", - "reviewedAt": "{{$datetime rfc1123}}", - "decision": "rejected", - "notes": "Error reviewed and rejected" -} - -### ============================================================== -### MONITORING: Check Final State -### ============================================================== -### Workflow tamamlandığında final state'i kontrol edin: -### - success: Tüm testler başarılı -### - failed: Rollback veya timeout sonrası - -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state - -### ============================================================== -### MONITORING: Get Full Instance Data with Test Results -### ============================================================== -### Tüm test sonuçlarını içeren instance data: - -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data - -### ============================================================== -### ERROR BOUNDARY TEST SCENARIOS SUMMARY -### ============================================================== -### -### | Level | ErrorAction | Scenario | -### |----------|-------------|---------------------------------------| -### | Task | Retry (1) | HTTP 503 - exponential backoff retry | -### | Task | Abort (0) | HTTP 500 - abort and transition | -### | State | Ignore (3) | HTTP 400 - ignore and continue | -### | State | Rollback(2) | HTTP 500 - rollback to prev state | -### | SubFlow | Propagate | Child error propagates to parent | -### | Global | Notify (4) | All unexpected errors notify | -### | Global | Log (5) | All errors are logged | -### | Timeout | Abort+Trans | Timeout leads to specific state | -### -### ErrorAction Enum Values: -### - 0: Abort -### - 1: Retry -### - 2: Rollback -### - 3: Ignore -### - 4: Notify -### - 5: Log -### -### BackoffType Enum Values: -### - 0: Fixed -### - 1: Exponential -### -### ============================================================== - -### ============================================================== -### CLEANUP: Delete Test Instance (Optional) -### ============================================================== -### Test sonrası instance'ı silmek için: - -# DELETE {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}} - diff --git a/core/Workflows/task-test/error-boundary-test-workflow.json b/core/Workflows/task-test/error-boundary-test-workflow.json deleted file mode 100644 index 70dffb4..0000000 --- a/core/Workflows/task-test/error-boundary-test-workflow.json +++ /dev/null @@ -1,847 +0,0 @@ -{ - "key": "error-boundary-test-workflow", - "flow": "sys-flows", - "domain": "core", - "version": "1.0.0", - "flowVersion": "1.0.0", - "tags": [ - "error-boundary", - "test", - "retry", - "abort", - "ignore", - "rollback", - "notify", - "timeout" - ], - "attributes": { - "type": "F", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Error Boundary Test Workflow" - }, - { - "language": "tr-TR", - "label": "ErrorBoundary Test İş Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "errorBoundary": { - "onError": [ - { - "action": 5, - "priority": 1000, - "logOnly": true - } - ] - }, - "startTransition": { - "key": "start-error-boundary-test", - "target": "test-task-boundary", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Error Boundary Test" - }, - { - "language": "tr-TR", - "label": "ErrorBoundary Testini Başlat" - } - ], - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ErrorBoundaryInitMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBFcnJvckJvdW5kYXJ5IEluaXQgTWFwcGluZyAtIEluaXRpYWxpemVzIHRoZSBlcnJvciBib3VuZGFyeSB0ZXN0IHdvcmtmbG93Ci8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBFcnJvckJvdW5kYXJ5SW5pdE1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBpbnB1dERhdGEgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhOwoKICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBLZXkgPSAiaW5pdC1zdWNjZXNzIiwKICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZXN0SWQgPSBpbnB1dERhdGE/LnRlc3RJZCA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgd29ya2Zsb3dTdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICB0ZXN0Q29uZmlndXJhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRlc3RUYXNrQm91bmRhcnkgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgIHRlc3RTdGF0ZUJvdW5kYXJ5ID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICB0ZXN0U3ViRmxvd0JvdW5kYXJ5ID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICB0ZXN0UmV0cnlQb2xpY2llcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgdGVzdFRpbWVvdXRQb2xpY3kgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgIHRlc3ROb3RpZnlBY3Rpb24gPSB0cnVlCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgZXJyb3JCb3VuZGFyeVRlc3RSZXN1bHRzID0gbmV3IHsgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZXJyb3ItYm91bmRhcnktdGVzdCIsICJpbml0aWFsaXplZCIgfQogICAgICAgIH07CiAgICB9Cn0KCg==" - } - } - ] - }, - "states": [ - { - "key": "test-task-boundary", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Task-Level ErrorBoundary" - }, - { - "language": "tr-TR", - "label": "Task Seviyesi ErrorBoundary Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "error-boundary-ignore-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ErrorBoundaryRetryMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBFcnJvckJvdW5kYXJ5IFJldHJ5IE1hcHBpbmcgLSBUZXN0cyBUYXNrLWxldmVsIHJldHJ5IHdpdGggZXhwb25lbnRpYWwgYmFja29mZgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRXJyb3JCb3VuZGFyeVJldHJ5TWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwogICAgICAgIH0KCiAgICAgICAgdmFyIHJlcXVlc3RCb2R5ID0gbmV3CiAgICAgICAgewogICAgICAgICAgICB0ZXN0SWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50ZXN0SWQgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgdGVzdFR5cGUgPSAidGFzay1ib3VuZGFyeS1yZXRyeSIsCiAgICAgICAgICAgIHRpbWVzdGFtcCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgbWVzc2FnZSA9ICJUZXN0aW5nIFRhc2stbGV2ZWwgRXJyb3JCb3VuZGFyeSB3aXRoIFJldHJ5IGFjdGlvbiIKICAgICAgICB9OwoKICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KQoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwoKICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBLZXkgPSAicmV0cnktc3VjY2VzcyIsCiAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGFza0JvdW5kYXJ5UmV0cnlSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gcmVzcG9uc2U/LmlzU3VjY2VzcyA/PyBmYWxzZSwKICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gcmVzcG9uc2U/LnN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgdGVzdFR5cGUgPSAiVGFzay1MZXZlbCBFcnJvckJvdW5kYXJ5IFJldHJ5IiwKICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZXJyb3ItYm91bmRhcnktdGVzdCIsICJ0YXNrLWJvdW5kYXJ5IiwgInJldHJ5IiB9CiAgICAgICAgfTsKICAgIH0KfQoK" - }, - "errorBoundary": { - "onError": [ - { - "action": 1, - "errorTypes": [], - "errorCodes": [ - "400" - ], - "priority": 100, - "retryPolicy": { - "maxRetries": 3, - "initialDelay": "PT2S", - "backoffType": 1, - "backoffMultiplier": 2, - "maxDelay": "PT6S" - } - }, - { - "action": 5, - "errorTypes": [], - "errorCodes": [ - "Task:400002" - ], - "priority": 99 - } - ] - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "task-boundary-success", - "target": "test-state-boundary", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Task Boundary Test Success" - }, - { - "language": "tr-TR", - "label": "Task Boundary Testi Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-state-boundary", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test State-Level ErrorBoundary" - }, - { - "language": "tr-TR", - "label": "State Seviyesi ErrorBoundary Testi" - } - ], - "view": null, - "subFlow": null, - "errorBoundary": { - "onError": [ - { - "action": 0, - "errorCodes": [ - "400", - "404", - "422" - ], - "priority": 100, - "logOnly": false - }, - { - "action": 2, - "errorCodes": [ - "500", - "502", - "503" - ], - "transition": "recovery-to-rollback", - "priority": 50 - } - ] - }, - "onEntries": [ - { - "order": 1, - "task": { - "key": "error-boundary-ignore-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ErrorBoundaryIgnoreMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBFcnJvckJvdW5kYXJ5IElnbm9yZSBNYXBwaW5nIC0gVGVzdHMgU3RhdGUtbGV2ZWwgaWdub3JlIGFjdGlvbiBmb3Igc3BlY2lmaWMgZXJyb3IgY29kZXMKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEVycm9yQm91bmRhcnlJZ25vcmVNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGFuIEh0dHBUYXNrIik7CiAgICAgICAgfQoKICAgICAgICB2YXIgcmVxdWVzdEJvZHkgPSBuZXcKICAgICAgICB7CiAgICAgICAgICAgIHRlc3RJZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRlc3RJZCA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICB0ZXN0VHlwZSA9ICJzdGF0ZS1ib3VuZGFyeS1pZ25vcmUiLAogICAgICAgICAgICB0aW1lc3RhbXAgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgIG1lc3NhZ2UgPSAiVGVzdGluZyBTdGF0ZS1sZXZlbCBFcnJvckJvdW5kYXJ5IHdpdGggSWdub3JlIGFjdGlvbiBmb3IgNDAwIGVycm9ycyIKICAgICAgICB9OwoKICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KTsKCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gImlnbm9yZS1zdWNjZXNzIiwKICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdGF0ZUJvdW5kYXJ5SWdub3JlUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPz8gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gcmVzcG9uc2U/LnN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgZXJyb3JJZ25vcmVkID0gcmVzcG9uc2U/LnN0YXR1c0NvZGUgPT0gNDAwLAogICAgICAgICAgICAgICAgICAgIHRlc3RUeXBlID0gIlN0YXRlLUxldmVsIEVycm9yQm91bmRhcnkgSWdub3JlIiwKICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZXJyb3ItYm91bmRhcnktdGVzdCIsICJzdGF0ZS1ib3VuZGFyeSIsICJpZ25vcmUiIH0KICAgICAgICB9OwogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "state-boundary-success", - "target": "test-subflow-boundary", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "State Boundary Test Success" - }, - { - "language": "tr-TR", - "label": "State Boundary Testi Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-subflow-boundary", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test SubFlow ErrorBoundary" - }, - { - "language": "tr-TR", - "label": "SubFlow ErrorBoundary Testi" - } - ], - "view": null, - "subFlow": { - "type": "S", - "process": { - "key": "error-boundary-subflow", - "domain": "core", - "version": "1.0.0", - "flow": "sys-flows" - }, - "mapping": { - "location": "./src/ErrorBoundarySubFlowMapping.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEVycm9yQm91bmRhcnkgU3ViRmxvdyBNYXBwaW5nIC0gSGFuZGxlcyBTdWJGbG93IGRhdGEgbWFwcGluZyB3aXRoIGVycm9yIHByb3BhZ2F0aW9uCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBFcnJvckJvdW5kYXJ5U3ViRmxvd01hcHBpbmcgOiBJU3ViRmxvd01hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgLy8gUGFzcyBwYXJlbnQgZGF0YSB0byBTdWJGbG93CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICB7CiAgICAgICAgICAgIERhdGEgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGEsCiAgICAgICAgICAgIEhlYWRlcnMgPSBudWxsCiAgICAgICAgfSk7CiAgICB9CgogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBEYXRhID0gY29udGV4dC5Cb2R5LAogICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZXJyb3ItYm91bmRhcnktdGVzdCIsICJzdWJmbG93IiwgImNvbXBsZXRlZCIgfQogICAgICAgIH0pOwogICAgfQp9Cgo=" - } - }, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "subflow-boundary-success", - "target": "test-retry-policies", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "SubFlow Boundary Test Success" - }, - { - "language": "tr-TR", - "label": "SubFlow Boundary Testi Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "subflow-error-recovery", - "target": "test-retry-policies", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "SubFlow Error Recovery" - }, - { - "language": "tr-TR", - "label": "SubFlow Hata Kurtarma" - } - ], - "schema": null, - "rule": { - "location": "./src/SubFlowErrorRecoveryRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIFN1YkZsb3cgRXJyb3IgUmVjb3ZlcnkgUnVsZSAtIERldGVybWluZXMgaWYgd2Ugc2hvdWxkIHByb2NlZWQgYWZ0ZXIgU3ViRmxvdyBlcnJvcgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgU3ViRmxvd0Vycm9yUmVjb3ZlcnlSdWxlIDogSUNvbmRpdGlvbk1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8Ym9vbD4gSGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUgd2FzIGFuIGVycm9yIGluIHRoZSBTdWJGbG93CiAgICAgICAgdmFyIGRhdGEgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhOwogICAgICAgIAogICAgICAgIC8vIElmIHRoZXJlJ3MgYSBzdWJGbG93IGVycm9yIHJlc3VsdCwgdGhpcyB0cmFuc2l0aW9uIHNob3VsZCBmaXJlCiAgICAgICAgaWYgKGRhdGE/LnN1YkZsb3dFcnJvclJlc3VsdCAhPSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KfQoK" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-retry-policies", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Retry Policies" - }, - { - "language": "tr-TR", - "label": "Retry Policy Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "error-boundary-success-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ErrorBoundarySuccessMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBFcnJvckJvdW5kYXJ5IFN1Y2Nlc3MgTWFwcGluZyAtIFRlc3RzIHN1Y2Nlc3NmdWwgZXhlY3V0aW9uIHBhdGgKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEVycm9yQm91bmRhcnlTdWNjZXNzTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgIGlmIChodHRwVGFzayA9PSBudWxsKQogICAgICAgIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwogICAgICAgIH0KCiAgICAgICAgdmFyIHJlcXVlc3RCb2R5ID0gbmV3CiAgICAgICAgewogICAgICAgICAgICB0ZXN0SWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50ZXN0SWQgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgdGVzdFR5cGUgPSAic3VjY2Vzcy1wYXRoIiwKICAgICAgICAgICAgdGltZXN0YW1wID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICBtZXNzYWdlID0gIlRlc3Rpbmcgc3VjY2Vzc2Z1bCBleGVjdXRpb24gcGF0aCIKICAgICAgICB9OwoKICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KTsKCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInN1Y2Nlc3MtY29tcGxldGVkIiwKICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdWNjZXNzUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPz8gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gcmVzcG9uc2U/LnN0YXR1c0NvZGUgPz8gMjAwLAogICAgICAgICAgICAgICAgICAgIHRlc3RUeXBlID0gIlN1Y2Nlc3MgUGF0aCIsCiAgICAgICAgICAgICAgICAgICAgY29tcGxldGVkQXQgPSBEYXRlVGltZS5VdGNOb3cKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgImVycm9yLWJvdW5kYXJ5LXRlc3QiLCAic3VjY2VzcyIgfQogICAgICAgIH07CiAgICB9Cn0KCg==" - }, - "errorBoundary": { - "onError": [ - { - "action": 1, - "priority": 100, - "retryPolicy": { - "maxRetries": 5, - "initialDelay": "PT5S", - "backoffType": 0, - "backoffMultiplier": 1, - "maxDelay": "PT25S" - } - } - ] - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "retry-policies-success", - "target": "test-timeout-policy", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Retry Policies Test Success" - }, - { - "language": "tr-TR", - "label": "Retry Policy Testi Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-timeout-policy", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Timeout Policy" - }, - { - "language": "tr-TR", - "label": "Timeout Policy Testi" - } - ], - "view": null, - "subFlow": null, - "errorBoundary": { - "onError": [], - "onTimeout": { - "action": 0, - "defaultRetryPolicy": { - "maxRetries": 2, - "initialDelay": "PT5S", - "backoffType": 1, - "backoffMultiplier": 1.5, - "maxDelay": "PT10S" - } - } - }, - "onEntries": [ - { - "order": 1, - "task": { - "key": "error-boundary-success-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ErrorBoundaryTimeoutMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBFcnJvckJvdW5kYXJ5IFRpbWVvdXQgTWFwcGluZyAtIFRlc3RzIHRpbWVvdXQgcG9saWN5IGhhbmRsaW5nCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBFcnJvckJvdW5kYXJ5VGltZW91dE1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICBpZiAoaHR0cFRhc2sgPT0gbnVsbCkKICAgICAgICB7CiAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2siKTsKICAgICAgICB9CgogICAgICAgIHZhciByZXF1ZXN0Qm9keSA9IG5ldwogICAgICAgIHsKICAgICAgICAgICAgdGVzdElkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udGVzdElkID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgIHRlc3RUeXBlID0gInRpbWVvdXQtcG9saWN5IiwKICAgICAgICAgICAgdGltZXN0YW1wID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICBtZXNzYWdlID0gIlRlc3RpbmcgVGltZW91dCBQb2xpY3kgd2l0aCBzdGF0ZS1sZXZlbCBFcnJvckJvdW5kYXJ5IgogICAgICAgIH07CgogICAgICAgIGh0dHBUYXNrLlNldEJvZHkocmVxdWVzdEJvZHkpOwoKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwoKICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgewogICAgICAgICAgICBLZXkgPSAidGltZW91dC1zdWNjZXNzIiwKICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aW1lb3V0UG9saWN5UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPz8gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gcmVzcG9uc2U/LnN0YXR1c0NvZGUgPz8gMjAwLAogICAgICAgICAgICAgICAgICAgIHRlc3RUeXBlID0gIlRpbWVvdXQgUG9saWN5IFRlc3QiLAogICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJlcnJvci1ib3VuZGFyeS10ZXN0IiwgInRpbWVvdXQtcG9saWN5IiB9CiAgICAgICAgfTsKICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "timeout-policy-success", - "target": "test-notify-action", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Timeout Policy Test Success" - }, - { - "language": "tr-TR", - "label": "Timeout Policy Testi Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-notify-action", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Notify Action" - }, - { - "language": "tr-TR", - "label": "Notify Action Testi" - } - ], - "view": null, - "subFlow": null, - "errorBoundary": { - "onError": [ - { - "action": 4, - "priority": 100, - "transition": "review-approved" - } - ] - }, - "onEntries": [ - { - "order": 1, - "task": { - "key": "error-boundary-success-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ErrorBoundaryNotifyMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBFcnJvckJvdW5kYXJ5IE5vdGlmeSBNYXBwaW5nIC0gVGVzdHMgbm90aWZ5IGFjdGlvbiB3aXRoIG5vdGlmaWNhdGlvbiBjb25maWcKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIEVycm9yQm91bmRhcnlOb3RpZnlNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBodHRwVGFzayA9IHRhc2sgYXMgSHR0cFRhc2s7CiAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgewogICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGFuIEh0dHBUYXNrIik7CiAgICAgICAgfQoKICAgICAgICB2YXIgcmVxdWVzdEJvZHkgPSBuZXcKICAgICAgICB7CiAgICAgICAgICAgIHRlc3RJZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRlc3RJZCA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICB0ZXN0VHlwZSA9ICJub3RpZnktYWN0aW9uIiwKICAgICAgICAgICAgdGltZXN0YW1wID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICBtZXNzYWdlID0gIlRlc3RpbmcgTm90aWZ5IGFjdGlvbiB3aXRoIE5vdGlmaWNhdGlvbkNvbmZpZyIKICAgICAgICB9OwoKICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KTsKCiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gIm5vdGlmeS1zdWNjZXNzIiwKICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBub3RpZnlBY3Rpb25SZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gcmVzcG9uc2U/LmlzU3VjY2VzcyA/PyB0cnVlLAogICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSByZXNwb25zZT8uc3RhdHVzQ29kZSA/PyAyMDAsCiAgICAgICAgICAgICAgICAgICAgdGVzdFR5cGUgPSAiTm90aWZ5IEFjdGlvbiBUZXN0IiwKICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZXJyb3ItYm91bmRhcnktdGVzdCIsICJub3RpZnktYWN0aW9uIiB9CiAgICAgICAgfTsKICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "notify-action-success", - "target": "success", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Notify Action Test Success" - }, - { - "language": "tr-TR", - "label": "Notify Action Testi Başarılı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "error-recovery", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Error Recovery State" - }, - { - "language": "tr-TR", - "label": "Hata Kurtarma State'i" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ErrorRecoveryMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBFcnJvciBSZWNvdmVyeSBNYXBwaW5nIC0gSGFuZGxlcyBlcnJvciByZWNvdmVyeSBsb2dpYwovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRXJyb3JSZWNvdmVyeU1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHZhciBkYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKCiAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0gInJlY292ZXJ5LWNvbXBsZXRlZCIsCiAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVjb3ZlcnlSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZWNvdmVyeUF0dGVtcHRlZCA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxFcnJvciA9IGRhdGE/Lmxhc3RFcnJvciwKICAgICAgICAgICAgICAgICAgICByZWNvdmVyeUFjdGlvbiA9ICJyb2xsYmFjayIsCiAgICAgICAgICAgICAgICAgICAgcmVjb3ZlcnlBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZXJyb3ItYm91bmRhcnktdGVzdCIsICJlcnJvci1yZWNvdmVyeSIgfQogICAgICAgIH07CiAgICB9Cn0KCg==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "recovery-to-rollback", - "target": "rollback-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Recovery to Rollback" - }, - { - "language": "tr-TR", - "label": "Kurtarmadan Rollback'e" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "rollback-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Rollback State" - }, - { - "language": "tr-TR", - "label": "Rollback State'i" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/RollbackMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBSb2xsYmFjayBNYXBwaW5nIC0gSGFuZGxlcyByb2xsYmFjayBhY3Rpb24gZm9yIGNyaXRpY2FsIGVycm9ycwovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgUm9sbGJhY2tNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBkYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInJvbGxiYWNrLWNvbXBsZXRlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcm9sbGJhY2tSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJvbGxiYWNrRXhlY3V0ZWQgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbEVycm9yID0gZGF0YT8ubGFzdEVycm9yLAogICAgICAgICAgICAgICAgICAgICAgICByb2xsYmFja0FjdGlvbiA9ICJyZXZlcnQtY2hhbmdlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIHJvbGxiYWNrQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgIG5vdGUgPSAiUm9sbGJhY2sgYWN0aW9uIGV4ZWN1dGVkIGR1ZSB0byBFcnJvckJvdW5kYXJ5IGNvbmZpZ3VyYXRpb24iCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJlcnJvci1ib3VuZGFyeS10ZXN0IiwgInJvbGxiYWNrIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJyb2xsYmFjay1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "rollback-to-failed", - "target": "failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Rollback to Failed" - }, - { - "language": "tr-TR", - "label": "Rollback'ten Failed'a" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "timeout-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Timeout State" - }, - { - "language": "tr-TR", - "label": "Timeout State'i" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/TimeoutHandlerMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBUaW1lb3V0IEhhbmRsZXIgTWFwcGluZyAtIEhhbmRsZXMgdGltZW91dCBzY2VuYXJpb3MKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFRpbWVvdXRIYW5kbGVyTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgZGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJ0aW1lb3V0LWhhbmRsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRpbWVvdXRSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVvdXRIYW5kbGVkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxUaW1lb3V0ID0gZGF0YT8udGltZW91dEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXJBY3Rpb24gPSAiYWJvcnQtYW5kLW5vdGlmeSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgbm90ZSA9ICJUaW1lb3V0IHdhcyBjYXVnaHQgYnkgRXJyb3JCb3VuZGFyeS5vblRpbWVvdXQgcG9saWN5IgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAiZXJyb3ItYm91bmRhcnktdGVzdCIsICJ0aW1lb3V0LWhhbmRsZXIiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInRpbWVvdXQtaGFuZGxlci1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "timeout-to-failed", - "target": "failed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Timeout to Failed" - }, - { - "language": "tr-TR", - "label": "Timeout'tan Failed'a" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "manual-review", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Manual Review State" - }, - { - "language": "tr-TR", - "label": "Manuel İnceleme State'i" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ManualReviewMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBNYW51YWwgUmV2aWV3IE1hcHBpbmcgLSBIYW5kbGVzIG1hbnVhbCByZXZpZXcgc3RhdGUgYWZ0ZXIgbm90aWZ5IGFjdGlvbgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgTWFudWFsUmV2aWV3TWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgZGF0YSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJtYW51YWwtcmV2aWV3LXJlYWR5IiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBtYW51YWxSZXZpZXdSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldmlld1JlcXVpcmVkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxFcnJvciA9IGRhdGE/Lmxhc3RFcnJvciwKICAgICAgICAgICAgICAgICAgICAgICAgbm90aWZpY2F0aW9uU2VudCA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHJldmlld1JlcXVlc3RlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICBub3RlID0gIk1hbnVhbCByZXZpZXcgcmVxdWlyZWQgYWZ0ZXIgTm90aWZ5IGFjdGlvbiBmcm9tIEVycm9yQm91bmRhcnkiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJlcnJvci1ib3VuZGFyeS10ZXN0IiwgIm1hbnVhbC1yZXZpZXciIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gIm1hbnVhbC1yZXZpZXctZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "review-approved", - "target": "success", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Review Approved" - }, - { - "language": "tr-TR", - "label": "İnceleme Onaylandı" - } - ], - "schema": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - }, - { - "key": "review-rejected", - "target": "failed", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Review Rejected" - }, - { - "language": "tr-TR", - "label": "İnceleme Reddedildi" - } - ], - "schema": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "success", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Success" - }, - { - "language": "tr-TR", - "label": "Başarılı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [], - "stateSubType": 1 - }, - { - "key": "failed", - "stateType": 3, - "subType": 2, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Failed" - }, - { - "language": "tr-TR", - "label": "Başarısız" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [], - "stateSubType": 2 - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/task-test/src/AlwaysTrueRule.csx b/core/Workflows/task-test/src/AlwaysTrueRule.csx deleted file mode 100644 index 44e727b..0000000 --- a/core/Workflows/task-test/src/AlwaysTrueRule.csx +++ /dev/null @@ -1,14 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// Always True Rule - Used for auto transitions that should always proceed -/// -public class AlwaysTrueRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - return true; - } -} - diff --git a/core/Workflows/task-test/src/DaprPubSubMapping.csx b/core/Workflows/task-test/src/DaprPubSubMapping.csx deleted file mode 100644 index 5080294..0000000 --- a/core/Workflows/task-test/src/DaprPubSubMapping.csx +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// DaprPubSub Task Mapping - Publishes events to message bus -/// Test case: Verify event publishing to Dapr PubSub component -/// -public class DaprPubSubMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var pubsubTask = task as DaprPubSubTask; - if (pubsubTask == null) - { - throw new InvalidOperationException("Task must be a DaprPubSubTask"); - } - - // Configure PubSub component - pubsubTask.SetPubSubName("vnext-execution-pubsub"); - pubsubTask.SetTopic("vnext.test.events"); - - // Create Cloud Events format data - var eventData = new - { - specversion = "1.0", - type = "com.vnext.task-test.TestEvent", - source = "task-test-workflow", - id = Guid.NewGuid().ToString(), - time = DateTime.UtcNow.ToString("O"), - datacontenttype = "application/json", - data = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - workflowId = context.Workflow.Key, - instanceId = context.Instance?.Id, - timestamp = DateTime.UtcNow, - message = "DaprPubSub test event published" - } - }; - - pubsubTask.SetData(eventData); - - // Set metadata - var metadata = new Dictionary - { - ["priority"] = "normal", - ["correlationId"] = context.Instance.Id.ToString(), - ["source"] = "task-test-workflow" - }; - pubsubTask.SetMetadata(metadata); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "dapr-pubsub-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - if (response?.isSuccess == true) - { - return new ScriptResponse - { - Key = "dapr-pubsub-success", - Data = new - { - daprPubSubResult = new - { - success = true, - publishedAt = DateTime.UtcNow, - taskType = "DaprPubSub" - } - }, - Tags = new[] { "task-test", "dapr-pubsub", "success" } - }; - } - - return new ScriptResponse - { - Key = "dapr-pubsub-failed", - Data = new - { - daprPubSubResult = new - { - success = false, - error = response?.errorMessage ?? "Unknown error", - failedAt = DateTime.UtcNow, - taskType = "DaprPubSub" - } - }, - Tags = new[] { "task-test", "dapr-pubsub", "failed" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "dapr-pubsub-exception", - Data = new - { - daprPubSubResult = new - { - success = false, - error = ex.Message, - taskType = "DaprPubSub" - } - } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/DaprServiceTaskMapping.csx b/core/Workflows/task-test/src/DaprServiceTaskMapping.csx deleted file mode 100644 index fd98681..0000000 --- a/core/Workflows/task-test/src/DaprServiceTaskMapping.csx +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// DaprService Task Mapping - Invokes Dapr services -/// Test case: Verify service-to-service invocation via Dapr -/// -public class DaprServiceTaskMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var serviceTask = task as DaprServiceTask; - if (serviceTask == null) - { - throw new InvalidOperationException("Task must be a DaprServiceTask"); - } - - // Configure target service - serviceTask.SetAppId("mockoon"); - serviceTask.SetMethodName("/api/task-test/dapr-endpoint"); - - // Prepare request body - var requestBody = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - workflowId = context.Workflow.Key, - instanceId = context.Instance?.Id, - timestamp = DateTime.UtcNow, - action = "dapr-service-test" - }; - - serviceTask.SetBody(requestBody); - - // Set headers - var headers = new Dictionary - { - ["X-Test-Id"] = context.Instance?.Data?.testId?.ToString(), - ["X-Request-Id"] = Guid.NewGuid().ToString(), - ["X-Correlation-Id"] = context.Instance.Id.ToString() - }; - serviceTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "dapr-service-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - if (response?.isSuccess == true) - { - return new ScriptResponse - { - Key = "dapr-service-success", - Data = new - { - daprServiceResult = new - { - success = true, - data = response?.data, - executionTime = response?.executionDurationMs, - processedAt = DateTime.UtcNow, - taskType = "DaprServiceTask" - } - }, - Tags = new[] { "task-test", "dapr-service", "success" } - }; - } - - return new ScriptResponse - { - Key = "dapr-service-failed", - Data = new - { - daprServiceResult = new - { - success = false, - error = response?.errorMessage ?? "Dapr service invocation failed", - failedAt = DateTime.UtcNow, - taskType = "DaprServiceTask" - } - }, - Tags = new[] { "task-test", "dapr-service", "failed" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "dapr-service-exception", - Data = new - { - daprServiceResult = new - { - success = false, - error = ex.Message, - taskType = "DaprServiceTask" - } - } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/DirectTransitionMapping.csx b/core/Workflows/task-test/src/DirectTransitionMapping.csx deleted file mode 100644 index 695c96d..0000000 --- a/core/Workflows/task-test/src/DirectTransitionMapping.csx +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// DirectTransition Task Mapping - Triggers transition on existing workflow instance -/// Test case: Verify workflow-to-workflow transition triggering -/// -public class DirectTransitionMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var directTriggerTask = task as DirectTriggerTask; - if (directTriggerTask == null) - { - throw new InvalidOperationException("Task must be a DirectTriggerTask"); - } - - // Configure target workflow - directTriggerTask.SetDomain("core"); - directTriggerTask.SetFlow("task-test-subflow"); - directTriggerTask.SetTransitionName("complete-subflow"); - directTriggerTask.SetTags(new[] { "task-test", "direct-transition", "success" }); - directTriggerTask.SetSync(true); - - // Get instance ID from workflow data - var targetInstanceId = context.Instance?.Data?.subflowInstanceId?.ToString(); - if (!string.IsNullOrEmpty(targetInstanceId)) - { - directTriggerTask.SetInstance(targetInstanceId); - } - directTriggerTask.SetKey(context.Instance?.Key ?? Guid.NewGuid().ToString()); - - // Prepare transition body - var transitionBody = new - { - completedBy = "task-test-workflow", - completedAt = DateTime.UtcNow, - parentInstanceId = context.Instance?.Id, - message = "DirectTransition test executed" - }; - directTriggerTask.SetBody(transitionBody); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "direct-transition-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - if (response?.isSuccess == true) - { - return new ScriptResponse - { - Key = "direct-transition-success", - Data = new - { - directTransitionResult = new - { - success = true, - instanceId = response?.data?.id, - status = response?.data?.status, - executedAt = DateTime.UtcNow, - taskType = "DirectTransition" - } - }, - Tags = new[] { "task-test", "direct-transition", "success" } - }; - } - - return new ScriptResponse - { - Key = "direct-transition-failed", - Data = new - { - directTransitionResult = new - { - success = false, - error = response?.errorMessage ?? "Direct transition failed", - failedAt = DateTime.UtcNow, - taskType = "DirectTransition" - } - }, - Tags = new[] { "task-test", "direct-transition", "failed" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "direct-transition-exception", - Data = new - { - directTransitionResult = new - { - success = false, - error = ex.Message, - taskType = "DirectTransition" - } - } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/ErrorBoundaryIgnoreMapping.csx b/core/Workflows/task-test/src/ErrorBoundaryIgnoreMapping.csx deleted file mode 100644 index 48cabad..0000000 --- a/core/Workflows/task-test/src/ErrorBoundaryIgnoreMapping.csx +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// ErrorBoundary Ignore Mapping - Tests State-level ignore action for specific error codes -/// -public class ErrorBoundaryIgnoreMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var requestBody = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - testType = "state-boundary-ignore", - timestamp = DateTime.UtcNow, - message = "Testing State-level ErrorBoundary with Ignore action for 400 errors" - }; - - httpTask.SetBody(requestBody); - - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = context.Body; - - return new ScriptResponse - { - Key = "ignore-success", - Data = new - { - stateBoundaryIgnoreResult = new - { - success = response?.isSuccess ?? true, - statusCode = response?.statusCode, - errorIgnored = response?.statusCode == 400, - testType = "State-Level ErrorBoundary Ignore", - completedAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "state-boundary", "ignore" } - }; - } -} - diff --git a/core/Workflows/task-test/src/ErrorBoundaryInitMapping.csx b/core/Workflows/task-test/src/ErrorBoundaryInitMapping.csx deleted file mode 100644 index 1ee36c9..0000000 --- a/core/Workflows/task-test/src/ErrorBoundaryInitMapping.csx +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// ErrorBoundary Init Mapping - Initializes the error boundary test workflow -/// -public class ErrorBoundaryInitMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var inputData = context.Instance?.Data; - - return new ScriptResponse - { - Key = "init-success", - Data = new - { - testId = inputData?.testId ?? Guid.NewGuid().ToString(), - workflowStartedAt = DateTime.UtcNow, - testConfiguration = new - { - testTaskBoundary = true, - testStateBoundary = true, - testSubFlowBoundary = true, - testRetryPolicies = true, - testTimeoutPolicy = true, - testNotifyAction = true - }, - errorBoundaryTestResults = new { } - }, - Tags = new[] { "error-boundary-test", "initialized" } - }; - } -} - diff --git a/core/Workflows/task-test/src/ErrorBoundaryNotifyMapping.csx b/core/Workflows/task-test/src/ErrorBoundaryNotifyMapping.csx deleted file mode 100644 index 8f1752c..0000000 --- a/core/Workflows/task-test/src/ErrorBoundaryNotifyMapping.csx +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// ErrorBoundary Notify Mapping - Tests notify action with notification config -/// -public class ErrorBoundaryNotifyMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var requestBody = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - testType = "notify-action", - timestamp = DateTime.UtcNow, - message = "Testing Notify action with NotificationConfig" - }; - - httpTask.SetBody(requestBody); - - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = context.Body; - - return new ScriptResponse - { - Key = "notify-success", - Data = new - { - notifyActionResult = new - { - success = response?.isSuccess ?? true, - statusCode = response?.statusCode ?? 200, - testType = "Notify Action Test", - completedAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "notify-action" } - }; - } -} - diff --git a/core/Workflows/task-test/src/ErrorBoundaryRetryMapping.csx b/core/Workflows/task-test/src/ErrorBoundaryRetryMapping.csx deleted file mode 100644 index 95f1f00..0000000 --- a/core/Workflows/task-test/src/ErrorBoundaryRetryMapping.csx +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// ErrorBoundary Retry Mapping - Tests Task-level retry with exponential backoff -/// -public class ErrorBoundaryRetryMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var requestBody = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - testType = "task-boundary-retry", - timestamp = DateTime.UtcNow, - message = "Testing Task-level ErrorBoundary with Retry action" - }; - - httpTask.SetBody(requestBody) - - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = context.Body; - - return new ScriptResponse - { - Key = "retry-success", - Data = new - { - taskBoundaryRetryResult = new - { - success = response?.isSuccess ?? false, - statusCode = response?.statusCode, - testType = "Task-Level ErrorBoundary Retry", - completedAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "task-boundary", "retry" } - }; - } -} - diff --git a/core/Workflows/task-test/src/ErrorBoundarySubFlowMapping.csx b/core/Workflows/task-test/src/ErrorBoundarySubFlowMapping.csx deleted file mode 100644 index 5ec9987..0000000 --- a/core/Workflows/task-test/src/ErrorBoundarySubFlowMapping.csx +++ /dev/null @@ -1,28 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// ErrorBoundary SubFlow Mapping - Handles SubFlow data mapping with error propagation -/// -public class ErrorBoundarySubFlowMapping : ISubFlowMapping -{ - public Task InputHandler(ScriptContext context) - { - // Pass parent data to SubFlow - return Task.FromResult(new ScriptResponse - { - Data = context.Instance.Data, - Headers = null - }); - } - - public Task OutputHandler(ScriptContext context) - { - return Task.FromResult(new ScriptResponse - { - Data = context.Body, - Tags = new[] { "error-boundary-test", "subflow", "completed" } - }); - } -} - diff --git a/core/Workflows/task-test/src/ErrorBoundarySuccessMapping.csx b/core/Workflows/task-test/src/ErrorBoundarySuccessMapping.csx deleted file mode 100644 index fed8e49..0000000 --- a/core/Workflows/task-test/src/ErrorBoundarySuccessMapping.csx +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// ErrorBoundary Success Mapping - Tests successful execution path -/// -public class ErrorBoundarySuccessMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var requestBody = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - testType = "success-path", - timestamp = DateTime.UtcNow, - message = "Testing successful execution path" - }; - - httpTask.SetBody(requestBody); - - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = context.Body; - - return new ScriptResponse - { - Key = "success-completed", - Data = new - { - successResult = new - { - success = response?.isSuccess ?? true, - statusCode = response?.statusCode ?? 200, - testType = "Success Path", - completedAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "success" } - }; - } -} - diff --git a/core/Workflows/task-test/src/ErrorBoundaryTimeoutMapping.csx b/core/Workflows/task-test/src/ErrorBoundaryTimeoutMapping.csx deleted file mode 100644 index da9c21a..0000000 --- a/core/Workflows/task-test/src/ErrorBoundaryTimeoutMapping.csx +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// ErrorBoundary Timeout Mapping - Tests timeout policy handling -/// -public class ErrorBoundaryTimeoutMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var requestBody = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - testType = "timeout-policy", - timestamp = DateTime.UtcNow, - message = "Testing Timeout Policy with state-level ErrorBoundary" - }; - - httpTask.SetBody(requestBody); - - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var response = context.Body; - - return new ScriptResponse - { - Key = "timeout-success", - Data = new - { - timeoutPolicyResult = new - { - success = response?.isSuccess ?? true, - statusCode = response?.statusCode ?? 200, - testType = "Timeout Policy Test", - completedAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "timeout-policy" } - }; - } -} - diff --git a/core/Workflows/task-test/src/ErrorRecoveryMapping.csx b/core/Workflows/task-test/src/ErrorRecoveryMapping.csx deleted file mode 100644 index e03952b..0000000 --- a/core/Workflows/task-test/src/ErrorRecoveryMapping.csx +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Error Recovery Mapping - Handles error recovery logic -/// -public class ErrorRecoveryMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - var data = context.Instance?.Data; - - return new ScriptResponse - { - Key = "recovery-completed", - Data = new - { - recoveryResult = new - { - recoveryAttempted = true, - originalError = data?.lastError, - recoveryAction = "rollback", - recoveryAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "error-recovery" } - }; - } -} - diff --git a/core/Workflows/task-test/src/GetConfigValueMapping.csx b/core/Workflows/task-test/src/GetConfigValueMapping.csx deleted file mode 100644 index a6bbb67..0000000 --- a/core/Workflows/task-test/src/GetConfigValueMapping.csx +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; -using BBT.Workflow.Scripting.Functions; - -/// -/// GetConfigValue Test Mapping - Demonstrates configuration value retrieval -/// Test case: Verify GetConfigValue functionality and logging -/// -public class GetConfigValueMapping : ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - LogInformation("GetConfigValue Test - Starting configuration retrieval test"); - - // Retrieve API base URL from configuration using GetConfigValue - var apiBaseUrl = GetConfigValue("Example:ApiBaseUrl"); - - LogInformation("GetConfigValue Test - Successfully retrieved ApiBaseUrl: {0}", - args: new object?[] { apiBaseUrl ?? "null" }); - - return Task.FromResult(new ScriptResponse - { - Data = new - { - configRetrieved = !string.IsNullOrEmpty(apiBaseUrl), - configKeyName = "ApiBaseUrl", - configValue = apiBaseUrl, - retrievedAt = DateTime.UtcNow - } - }); - } - catch (Exception ex) - { - LogError("GetConfigValue Test - Failed to retrieve config: {0}", - args: new object?[] { ex.Message }); - - return Task.FromResult(new ScriptResponse - { - Key = "get-config-input-error", - Data = new { error = ex.Message } - }); - } - } - - public Task OutputHandler(ScriptContext context) - { - try - { - LogInformation("GetConfigValue Test - Processing output"); - - var inputData = context.Instance?.Data; - - return Task.FromResult(new ScriptResponse - { - Key = "get-config-success", - Data = new - { - getConfigResult = new - { - success = true, - testName = "GetConfigValue", - description = "Retrieved ApiBaseUrl from configuration", - taskType = "ScriptTask" - } - }, - Tags = new[] { "task-test", "get-config-value", "success" } - }); - } - catch (Exception ex) - { - LogError("GetConfigValue Test - Output handler exception: {0}", - args: new object?[] { ex.Message }); - - return Task.FromResult(new ScriptResponse - { - Key = "get-config-exception", - Data = new - { - getConfigResult = new - { - success = false, - error = ex.Message, - taskType = "ScriptTask" - } - } - }); - } - } -} - diff --git a/core/Workflows/task-test/src/GetInstanceDataMapping.csx b/core/Workflows/task-test/src/GetInstanceDataMapping.csx deleted file mode 100644 index 4213717..0000000 --- a/core/Workflows/task-test/src/GetInstanceDataMapping.csx +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; -using System.Text.Json; - -/// -/// GetInstanceData Task Mapping - Retrieves data from another workflow instance -/// Test case: Verify cross-workflow data retrieval -/// -public class GetInstanceDataMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var getDataTask = task as GetInstanceDataTask; - if (getDataTask == null) - { - throw new InvalidOperationException("Task must be a GetInstanceDataTask"); - } - - // Configure target workflow - get data from current workflow instance to test extensions - getDataTask.SetDomain("core"); - getDataTask.SetFlow("task-test-workflow"); - - // Get data from current instance to verify extension data - var currentInstanceId = context.Instance?.Id.ToString(); - if (!string.IsNullOrEmpty(currentInstanceId)) - { - getDataTask.SetInstance(currentInstanceId); - } - - // Request specific extensions - this will trigger the test-http-data-extension - getDataTask.SetExtensions(new[] { "test-http-data-extension" }); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "get-instance-data-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - if (response?.isSuccess == true) - { - return new ScriptResponse - { - Key = "get-instance-data-success", - Data = new - { - getInstanceDataResult = new - { - success = true, - retrievedData = response?.data?.data, - // Extension data will be here - test-http-data-extension response - extensionData = response?.data?.extensions, - retrievedAt = DateTime.UtcNow, - taskType = "GetInstanceData", - note = "Check extensionData field for test-http-data-extension results" - } - }, - Tags = new[] { "task-test", "get-instance-data", "success", "extension-test" } - }; - } - - return new ScriptResponse - { - Key = "get-instance-data-failed", - Data = new - { - getInstanceDataResult = new - { - success = false, - error = response?.errorMessage ?? "Failed to retrieve instance data", - failedAt = DateTime.UtcNow, - taskType = "GetInstanceData" - } - }, - Tags = new[] { "task-test", "get-instance-data", "failed" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "get-instance-data-exception", - Data = new - { - getInstanceDataResult = new - { - success = false, - error = ex.Message, - taskType = "GetInstanceData" - } - } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/GetInstancesMapping.csx b/core/Workflows/task-test/src/GetInstancesMapping.csx deleted file mode 100644 index 06280a5..0000000 --- a/core/Workflows/task-test/src/GetInstancesMapping.csx +++ /dev/null @@ -1,220 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text.Json; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; -using BBT.Workflow.Scripting.Functions; - -/// -/// GetInstances Task Mapping - Retrieves a list of workflow instances with filtering and pagination -/// Test case: Verify GetInstancesTask functionality including filter, pagination, and sorting -/// -/// Filter Format (GraphQL-like JSON structure): -/// ?filter={"attributes":{"fieldName":{"operator":"value"}}} -/// -/// Supported operators: eq, neq, gt, gte, lt, lte, contains, startsWith, endsWith -/// -/// Examples: -/// - Single filter: {"attributes":{"clientId":{"eq":122}}} -/// - Multiple filters: {"attributes":{"clientId":{"eq":122},"testValue":{"gt":2}}} -/// - String filter: {"attributes":{"status":{"eq":"active"}}} -/// -public class GetInstancesMapping : ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - LogInformation("GetInstances Test - Starting GetInstances task configuration"); - - var getInstancesTask = task as GetInstancesTask; - if (getInstancesTask == null) - { - throw new InvalidOperationException("Task must be a GetInstancesTask"); - } - - // Configure target workflow - query instances from task-test-subflow - getInstancesTask.SetDomain("core"); - getInstancesTask.SetFlow("task-test-subflow"); - - // Configure pagination - getInstancesTask.SetPage(1); - getInstancesTask.SetPageSize(10); - - // Configure sorting - newest first - // getInstancesTask.SetSort("-CreatedAt"); - - // Build filter in GraphQL-like JSON format - // Format: {"attributes":{"fieldName":{"operator":"value"}}} - // API call example: GET /api/v1.0/core/workflows/task-test-subflow/instances?filter={"attributes":{"parentInstanceId":{"eq":"abc-123"}}} - - // Get parent instance data to build meaningful filters - var parentInstanceId = context.Instance.Id.ToString(); - var testId = context.Instance.Data?.testId.ToString(); - - // Build attribute filters dictionary - // Each key is a field name, each value is a dictionary of {operator: value} - var attributeFilters = new Dictionary>(); - - // Filter 1: Find instances by parentInstanceId using "eq" operator - if (!string.IsNullOrEmpty(parentInstanceId)) - { - attributeFilters["parentInstanceId"] = new Dictionary - { - { "eq", parentInstanceId } - }; - } - - // Filter 2: Find instances by testId using "eq" operator - if (!string.IsNullOrEmpty(testId)) - { - attributeFilters["testId"] = new Dictionary - { - { "eq", testId } - }; - } - - // Filter 3: Find instances started by task-test-workflow using "eq" operator - attributeFilters["startedBy"] = new Dictionary - { - { "eq", "task-test-workflow" } - }; - - // Build the complete filter JSON object - // Result format: {"attributes":{"parentInstanceId":{"eq":"..."},"testId":{"eq":"..."},"startedBy":{"eq":"task-test-workflow"}}} - if (attributeFilters.Count > 0) - { - var filterObject = new Dictionary - { - { "attributes", attributeFilters } - }; - - // Serialize to JSON string - var filterJson = JsonSerializer.Serialize(filterObject); - - // SetFilter expects a string array - pass the complete filter as single element - getInstancesTask.SetFilter([filterJson]); - - LogInformation("GetInstances Test - Applied JSON filter: {0}", - args: [filterJson]); - } - else - { - LogInformation("GetInstances Test - No filters applied, retrieving all instances"); - } - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - LogError("GetInstances Test - Failed to configure GetInstances task: {0}", - args: [ex.Message]); - - return Task.FromResult(new ScriptResponse - { - Key = "get-instances-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - LogInformation("GetInstances Test - Processing GetInstances response"); - - var response = context.Body; - var isSuccess = response?.isSuccess == true; - var statusCode = response?.statusCode ?? 500; - - if (isSuccess) - { - // Extract response data - var instances = response?.data.items; - - LogInformation("GetInstances Test - Successfully retrieved {0} instance(s)", - args: new object?[] { instances?.Count ?? 0 }); - - // Build instance summary for verification - var instanceSummary = new List(); - if (instances != null) - { - foreach (var instance in instances) - { - instanceSummary.Add(new - { - testId = instance?.data?.testId - }); - } - } - - return new ScriptResponse - { - Key = "get-instances-success", - Data = new - { - getInstancesResult = new - { - success = true, - taskType = "GetInstances", - description = "Retrieved workflow instances with JSON filter, pagination, and sorting", - filter = new - { - applied = true, - format = "GraphQL-like JSON", - targetDomain = "core", - targetFlow = "task-test-subflow" - }, - instances = instanceSummary, - instanceCount = instances?.Count ?? 0, - retrievedAt = DateTime.UtcNow - } - }, - Tags = ["task-test", "get-instances", "filter-test", "json-filter", "success"] - }; - } - - // Handle failure - LogWarning("GetInstances Test - Failed to retrieve instances: {0}", - args: [response?.errorMessage ?? "Unknown error"]); - - return new ScriptResponse - { - Key = "get-instances-failed", - Data = new - { - getInstancesResult = new - { - success = false, - taskType = "GetInstances", - statusCode = statusCode, - error = response?.errorMessage ?? "Failed to retrieve instances", - failedAt = DateTime.UtcNow - } - }, - Tags = ["task-test", "get-instances", "failed"] - }; - } - catch (Exception ex) - { - LogError("GetInstances Test - Output handler exception: {0}", - args: [ex.Message]); - - return new ScriptResponse - { - Key = "get-instances-exception", - Data = new - { - getInstancesResult = new - { - success = false, - taskType = "GetInstances", - error = ex.Message - } - } - }; - } - } -} diff --git a/core/Workflows/task-test/src/GetSecretAsyncMapping.csx b/core/Workflows/task-test/src/GetSecretAsyncMapping.csx deleted file mode 100644 index 16b9588..0000000 --- a/core/Workflows/task-test/src/GetSecretAsyncMapping.csx +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; -using BBT.Workflow.Scripting.Functions; - -/// -/// GetSecretAsync Test Mapping - Demonstrates secret retrieval from Dapr secret store -/// Test case: Verify GetSecretAsync functionality and logging -/// -public class GetSecretAsyncMapping : ScriptBase, IMapping -{ - public async Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - LogInformation("GetSecretAsync Test - Starting secret retrieval test"); - - // Retrieve API secret from Dapr secret store using GetSecretAsync - var apiSecret = await GetSecretAsync("vnext-secret", "workflow-secret", "ApiSecret"); - - LogInformation("GetSecretAsync Test - Successfully retrieved ApiSecret"); - LogDebug("GetSecretAsync Test - Secret value length: {0}", - args: new object?[] { apiSecret?.Length ?? 0 }); - - // Store the result for output handler - return new ScriptResponse - { - Data = new - { - secretRetrieved = !string.IsNullOrEmpty(apiSecret), - secretKeyName = "ApiSecret", - retrievedAt = DateTime.UtcNow - } - }; - } - catch (Exception ex) - { - LogError("GetSecretAsync Test - Failed to retrieve secret: {0}", - args: new object?[] { ex.Message }); - - return new ScriptResponse - { - Key = "get-secret-input-error", - Data = new { error = ex.Message } - }; - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - LogInformation("GetSecretAsync Test - Processing output"); - - return new ScriptResponse - { - Key = "get-secret-success", - Data = new - { - getSecretResult = new - { - success = true, - testName = "GetSecretAsync", - description = "Retrieved ApiSecret from Dapr secret store", - completedAt = DateTime.UtcNow, - taskType = "ScriptTask" - } - }, - Tags = new[] { "task-test", "get-secret-async", "success" } - }; - } - catch (Exception ex) - { - LogError("GetSecretAsync Test - Output handler exception: {0}", - args: new object?[] { ex.Message }); - - return new ScriptResponse - { - Key = "get-secret-exception", - Data = new - { - getSecretResult = new - { - success = false, - error = ex.Message, - taskType = "ScriptTask" - } - } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/HttpTaskItemsMapping.csx b/core/Workflows/task-test/src/HttpTaskItemsMapping.csx deleted file mode 100644 index f435a15..0000000 --- a/core/Workflows/task-test/src/HttpTaskItemsMapping.csx +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// HTTP Task Mapping - Makes external API calls -/// Test case: Verify HTTP requests to external services via Mockoon -/// -public class HttpTaskItemsMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - // Prepare request body - var requestBody = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - workflowId = context.Workflow.Key, - instanceId = context.Instance?.Id, - timestamp = DateTime.UtcNow, - action = "http-task-test" - }; - - httpTask.SetBody(requestBody); - - // Set headers - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Test-Id"] = context.Instance?.Data?.testId?.ToString(), - ["X-Request-Id"] = Guid.NewGuid().ToString(), - ["X-Correlation-Id"] = context.Instance.Id.ToString() - }; - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "http-task-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - var statusCode = response?.statusCode ?? 500; - - if (statusCode >= 200 && statusCode < 300) - { - return new ScriptResponse - { - Key = "http-task-success", - Data = new - { - httpTaskItemsResult = new - { - success = true, - statusCode = statusCode, - data = response?.data, - executionTime = response?.executionDurationMs, - processedAt = DateTime.UtcNow, - taskType = "HttpTask" - } - }, - Tags = new[] { "task-test", "http-task", "success" } - }; - } - - return new ScriptResponse - { - Key = "http-task-failed", - Data = new - { - httpTaskItemsResult = new - { - success = false, - statusCode = statusCode, - error = response?.errorMessage ?? "HTTP request failed", - failedAt = DateTime.UtcNow, - taskType = "HttpTask" - } - }, - Tags = new[] { "task-test", "http-task", "failed" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "http-task-exception", - Data = new - { - httpTaskItemsResult = new - { - success = false, - error = ex.Message, - taskType = "HttpTask" - } - } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/HttpTaskMapping.csx b/core/Workflows/task-test/src/HttpTaskMapping.csx deleted file mode 100644 index ab2072d..0000000 --- a/core/Workflows/task-test/src/HttpTaskMapping.csx +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// HTTP Task Mapping - Makes external API calls -/// Test case: Verify HTTP requests to external services via Mockoon -/// -public class HttpTaskMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - // Prepare request body - var requestBody = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - workflowId = context.Workflow.Key, - instanceId = context.Instance?.Id, - timestamp = DateTime.UtcNow, - action = "http-task-test" - }; - - httpTask.SetBody(requestBody); - - // Set headers - var headers = new Dictionary - { - ["Content-Type"] = "application/json", - ["X-Test-Id"] = context.Instance?.Data?.testId?.ToString(), - ["X-Request-Id"] = Guid.NewGuid().ToString(), - ["X-Correlation-Id"] = context.Instance.Id.ToString() - }; - httpTask.SetHeaders(headers); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "http-task-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - var statusCode = response?.statusCode ?? 500; - - if (statusCode >= 200 && statusCode < 300) - { - return new ScriptResponse - { - Key = "http-task-success", - Data = new - { - httpTaskResult = new - { - success = true, - statusCode = statusCode, - data = response?.data, - executionTime = response?.executionDurationMs, - processedAt = DateTime.UtcNow, - taskType = "HttpTask" - } - }, - Tags = new[] { "task-test", "http-task", "success" } - }; - } - - return new ScriptResponse - { - Key = "http-task-failed", - Data = new - { - httpTaskResult = new - { - success = false, - statusCode = statusCode, - error = response?.errorMessage ?? "HTTP request failed", - failedAt = DateTime.UtcNow, - taskType = "HttpTask" - } - }, - Tags = new[] { "task-test", "http-task", "failed" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "http-task-exception", - Data = new - { - httpTaskResult = new - { - success = false, - error = ex.Message, - taskType = "HttpTask" - } - } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/InitialTransitionMapping.csx b/core/Workflows/task-test/src/InitialTransitionMapping.csx deleted file mode 100644 index cb53fde..0000000 --- a/core/Workflows/task-test/src/InitialTransitionMapping.csx +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting;using BBT.Workflow.Scripting.Functions; - -/// -/// Initial Transition Mapping - Initializes workflow with test data -/// -public class InitialTransitionMapping : ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - LogInformation("InitialTransitionMapping output handler starting..."); - var inputData = context.Instance?.Data; - - return new ScriptResponse - { - Key = "initial-success", - Data = new - { - testId = inputData?.testId ?? Guid.NewGuid().ToString(), - workflowStartedAt = DateTime.UtcNow, - testConfiguration = new - { - testGetSecretAsync = true, - testGetConfigValue = true, - testTaskResponse = true, - testDaprPubSub = true, - testHttpTask = true, - testDaprServiceTask = true, - testNotificationTask = true, - testScriptTask = true, - testGetInstanceData = true, - testGetInstances = true, - testDirectTransition = true, - testStartWorkflow = true, - testSubProcess = true - }, - taskTestResults = new { } - }, - Tags = new[] { "task-test", "initialized" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "initial-error", - Data = new { error = ex.Message } - }; - } - } -} \ No newline at end of file diff --git a/core/Workflows/task-test/src/ManualReviewMapping.csx b/core/Workflows/task-test/src/ManualReviewMapping.csx deleted file mode 100644 index 825d78f..0000000 --- a/core/Workflows/task-test/src/ManualReviewMapping.csx +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Manual Review Mapping - Handles manual review state after notify action -/// -public class ManualReviewMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var data = context.Instance?.Data; - - return new ScriptResponse - { - Key = "manual-review-ready", - Data = new - { - manualReviewResult = new - { - reviewRequired = true, - originalError = data?.lastError, - notificationSent = true, - reviewRequestedAt = DateTime.UtcNow, - note = "Manual review required after Notify action from ErrorBoundary" - } - }, - Tags = new[] { "error-boundary-test", "manual-review" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "manual-review-exception", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/RollbackMapping.csx b/core/Workflows/task-test/src/RollbackMapping.csx deleted file mode 100644 index 93881b4..0000000 --- a/core/Workflows/task-test/src/RollbackMapping.csx +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Rollback Mapping - Handles rollback action for critical errors -/// -public class RollbackMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var data = context.Instance?.Data; - - return new ScriptResponse - { - Key = "rollback-completed", - Data = new - { - rollbackResult = new - { - rollbackExecuted = true, - originalError = data?.lastError, - rollbackAction = "revert-changes", - rollbackAt = DateTime.UtcNow, - note = "Rollback action executed due to ErrorBoundary configuration" - } - }, - Tags = new[] { "error-boundary-test", "rollback" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "rollback-exception", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/ScriptTaskMapping.csx b/core/Workflows/task-test/src/ScriptTaskMapping.csx deleted file mode 100644 index 5ad263d..0000000 --- a/core/Workflows/task-test/src/ScriptTaskMapping.csx +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Script Task Mapping - Executes custom business logic -/// Test case: Verify script execution and data transformation -/// -public class ScriptTaskMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - // Script tasks don't require specific task configuration - // They are used for data transformation and business logic - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "script-task-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - // Perform data transformation - var inputData = context.Instance?.Data; - - // Calculate some values - var calculatedValues = new - { - originalTestId = inputData?.testId, - processedAt = DateTime.UtcNow, - calculatedValue = new Random().Next(1000, 9999), - isProcessed = true, - processingDuration = DateTime.UtcNow.Subtract(DateTime.UtcNow.AddMilliseconds(-100)).TotalMilliseconds - }; - - // Transform and aggregate data - var transformedData = new - { - scriptTaskResult = new - { - success = true, - originalData = new - { - testId = inputData?.testId, - workflowId = context.Workflow.Key, - instanceId = context.Instance?.Id - }, - transformed = calculatedValues, - metadata = new - { - taskType = "ScriptTask", - executedAt = DateTime.UtcNow, - scriptVersion = "1.0.0" - } - } - }; - - return new ScriptResponse - { - Key = "script-task-success", - Data = transformedData, - Tags = new[] { "task-test", "script-task", "success", "data-transformation" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "script-task-exception", - Data = new - { - scriptTaskResult = new - { - success = false, - error = ex.Message, - taskType = "ScriptTask" - } - } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/StartWorkflowMapping.csx b/core/Workflows/task-test/src/StartWorkflowMapping.csx deleted file mode 100644 index 9e227ee..0000000 --- a/core/Workflows/task-test/src/StartWorkflowMapping.csx +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Start Workflow Task Mapping - Starts a new workflow instance -/// Test case: Verify starting new workflow instances -/// -public class StartWorkflowMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var startTask = task as StartTask; - if (startTask == null) - { - throw new InvalidOperationException("Task must be a StartTask"); - } - - // Configure target workflow - startTask.SetDomain("core"); - startTask.SetFlow("task-test-subflow"); - startTask.SetSync(true); - startTask.SetVersion("1.0.0"); - startTask.SetKey(Guid.NewGuid().ToString()); - startTask.SetTags(new[] { "task-test", "start-workflow", "success" }); - - // Prepare initialization body - var initBody = new - { - parentInstanceId = context.Instance?.Id, - parentWorkflowId = context.Workflow?.Key, - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - startedAt = DateTime.UtcNow, - startedBy = "task-test-workflow", - message = "StartTask test - new instance created" - }; - startTask.SetBody(initBody); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "start-workflow-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - if (response?.isSuccess == true) - { - return new ScriptResponse - { - Key = "start-workflow-success", - Data = new - { - startWorkflowResult = new - { - success = true, - newInstanceId = response?.data?.id, - status = response?.data?.status, - startedAt = DateTime.UtcNow, - taskType = "Start" - }, - // Store instance ID for later use - subflowInstanceId = response?.data?.id - }, - Tags = new[] { "task-test", "start-workflow", "success" } - }; - } - - return new ScriptResponse - { - Key = "start-workflow-failed", - Data = new - { - startWorkflowResult = new - { - success = false, - error = response?.errorMessage ?? "Failed to start workflow", - failedAt = DateTime.UtcNow, - taskType = "Start" - } - }, - Tags = new[] { "task-test", "start-workflow", "failed" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "start-workflow-exception", - Data = new - { - startWorkflowResult = new - { - success = false, - error = ex.Message, - taskType = "Start" - } - } - }; - } - } -} \ No newline at end of file diff --git a/core/Workflows/task-test/src/SubFlowErrorMapping.csx b/core/Workflows/task-test/src/SubFlowErrorMapping.csx deleted file mode 100644 index 967d943..0000000 --- a/core/Workflows/task-test/src/SubFlowErrorMapping.csx +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// SubFlow Error Mapping - Tests SubFlow error handling with error propagation -/// -public class SubFlowErrorMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var httpTask = task as HttpTask; - if (httpTask == null) - { - throw new InvalidOperationException("Task must be an HttpTask"); - } - - var requestBody = new - { - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - testType = "subflow-error", - timestamp = DateTime.UtcNow, - message = "Testing SubFlow error propagation to parent workflow" - }; - - httpTask.SetBody(requestBody); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "subflow-error-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - return new ScriptResponse - { - Key = "subflow-error-handled", - Data = new - { - subFlowErrorResult = new - { - success = false, - statusCode = response?.statusCode ?? 500, - errorPropagated = true, - testType = "SubFlow Error Propagation Test", - completedAt = DateTime.UtcNow - } - }, - Tags = new[] { "error-boundary-test", "subflow-error" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "subflow-error-exception", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/SubFlowErrorRecoveryRule.csx b/core/Workflows/task-test/src/SubFlowErrorRecoveryRule.csx deleted file mode 100644 index 83281a7..0000000 --- a/core/Workflows/task-test/src/SubFlowErrorRecoveryRule.csx +++ /dev/null @@ -1,23 +0,0 @@ -using System.Threading.Tasks; -using BBT.Workflow.Scripting; - -/// -/// SubFlow Error Recovery Rule - Determines if we should proceed after SubFlow error -/// -public class SubFlowErrorRecoveryRule : IConditionMapping -{ - public async Task Handler(ScriptContext context) - { - // Check if there was an error in the SubFlow - var data = context.Instance?.Data; - - // If there's a subFlow error result, this transition should fire - if (data?.subFlowErrorResult != null) - { - return true; - } - - return false; - } -} - diff --git a/core/Workflows/task-test/src/SubProcessMapping.csx b/core/Workflows/task-test/src/SubProcessMapping.csx deleted file mode 100644 index ddcd09e..0000000 --- a/core/Workflows/task-test/src/SubProcessMapping.csx +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// SubProcess Task Mapping - Starts a fire-and-forget subprocess -/// Test case: Verify subprocess launching (non-blocking) -/// -public class SubProcessMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - var subProcessTask = task as SubProcessTask; - if (subProcessTask == null) - { - throw new InvalidOperationException("Task must be a SubProcessTask"); - } - - // Configure subprocess - //subProcessTask.SetDomain("core"); - //subProcessTask.SetFlow("task-test-subflow"); - subProcessTask.SetKey(context.Instance?.Key ?? Guid.NewGuid().ToString()); - subProcessTask.SetTags(new[] { "task-test", "subprocess", "success" }); - - // Prepare subprocess data - var subProcessBody = new - { - parentInstanceId = context.Instance?.Id, - parentWorkflowId = context.Workflow.Key, - testId = context.Instance?.Data?.testId ?? Guid.NewGuid().ToString(), - launchedAt = DateTime.UtcNow, - launchedBy = "task-test-workflow", - isFireAndForget = true, - message = "SubProcess test - fire-and-forget instance" - }; - subProcessTask.SetBody(subProcessBody); - - return Task.FromResult(new ScriptResponse()); - } - catch (Exception ex) - { - return Task.FromResult(new ScriptResponse - { - Key = "subprocess-input-error", - Data = new { error = ex.Message } - }); - } - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var response = context.Body; - - if (response?.isSuccess == true) - { - return new ScriptResponse - { - Key = "subprocess-success", - Data = new - { - subProcessResult = new - { - success = true, - subProcessInstanceId = response?.data?.id, - launchedAt = DateTime.UtcNow, - taskType = "SubProcess", - note = "Fire-and-forget: Parent workflow does not wait for subprocess completion" - } - }, - Tags = new[] { "task-test", "subprocess", "success", "fire-and-forget" } - }; - } - - return new ScriptResponse - { - Key = "subprocess-failed", - Data = new - { - subProcessResult = new - { - success = false, - error = response?.errorMessage ?? "Failed to launch subprocess", - failedAt = DateTime.UtcNow, - taskType = "SubProcess" - } - }, - Tags = new[] { "task-test", "subprocess", "failed" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "subprocess-exception", - Data = new - { - subProcessResult = new - { - success = false, - error = ex.Message, - taskType = "SubProcess" - } - } - }; - } - } -} - diff --git a/core/Workflows/task-test/src/TaskResponseUsageMapping.csx b/core/Workflows/task-test/src/TaskResponseUsageMapping.csx deleted file mode 100644 index d358b0c..0000000 --- a/core/Workflows/task-test/src/TaskResponseUsageMapping.csx +++ /dev/null @@ -1,154 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; -using BBT.Workflow.Scripting.Functions; - -/// -/// TaskResponse Usage Test Mapping - Demonstrates accessing previous task responses -/// Test case: Verify TaskResponse dictionary usage in ScriptContext after HTTP tasks -/// Note: TaskResponse keys are the task's "key" value converted to camelCase -/// Example: "test-http-task" becomes "testHttpTask" -/// -public class TaskResponseUsageMapping : ScriptBase, IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - try - { - LogInformation("TaskResponse Usage Test - Starting TaskResponse access test"); - - // Access TaskResponse dictionary from ScriptContext - // This contains results from previously completed tasks in the workflow - var taskResponseDict = context.TaskResponse; - - if (taskResponseDict != null && taskResponseDict.Count > 0) - { - LogInformation("TaskResponse Usage Test - Found {0} task response(s) in context", - args: new object?[] { taskResponseDict.Count }); - - // Log all available task response keys - foreach (var key in taskResponseDict.Keys) - { - LogDebug("TaskResponse Usage Test - Available task response key: {0}", - args: new object?[] { key }); - } - - // Example: Access specific task response if it exists - // TaskResponse key is the task's "key" value converted to camelCase - // e.g., "test-http-task" becomes "testHttpTask" - if (taskResponseDict.ContainsKey("testHttpTask")) - { - var httpTaskResult = taskResponseDict["testHttpTask"]; - LogInformation("TaskResponse Usage Test - HTTP task response found: isSuccess={0}, statusCode={1}", - args: new object?[] { httpTaskResult?.isSuccess, httpTaskResult?.statusCode }); - - // Access response data - var responseData = httpTaskResult?.data; - if (responseData != null) - { - LogDebug("TaskResponse Usage Test - HTTP response data available"); - } - } - } - else - { - LogWarning("TaskResponse Usage Test - No previous task responses found in context"); - } - - return Task.FromResult(new ScriptResponse - { - Data = new - { - taskResponseCount = taskResponseDict?.Count ?? 0, - taskResponseKeys = taskResponseDict != null - ? string.Join(", ", taskResponseDict.Keys) - : "none", - testedAt = DateTime.UtcNow - } - }); - } - catch (Exception ex) - { - LogError("TaskResponse Usage Test - Failed to access TaskResponse: {0}", - args: new object?[] { ex.Message }); - - return Task.FromResult(new ScriptResponse - { - Key = "task-response-input-error", - Data = new { error = ex.Message } - }); - } - } - - public Task OutputHandler(ScriptContext context) - { - try - { - LogInformation("TaskResponse Usage Test - Processing output"); - - // Demonstrate accessing TaskResponse in OutputHandler as well - var taskResponseDict = context.TaskResponse; - - // Build a summary of available task responses - var taskResponseSummary = new System.Collections.Generic.List(); - - if (taskResponseDict != null) - { - foreach (var kvp in taskResponseDict) - { - taskResponseSummary.Add(new - { - taskKey = kvp.Key, - hasData = kvp.Value != null, - isSuccess = kvp.Value?.isSuccess, - statusCode = kvp.Value?.statusCode, - taskType = kvp.Value?.taskType - }); - } - } - - LogInformation("TaskResponse Usage Test - Processed {0} task response(s)", - args: new object?[] { taskResponseSummary.Count }); - - return Task.FromResult(new ScriptResponse - { - Key = "task-response-success", - Data = new - { - taskResponseResult = new - { - success = true, - testName = "TaskResponse Usage", - description = "Demonstrated context.TaskResponse dictionary access", - totalTaskResponses = taskResponseDict?.Count ?? 0, - taskResponseSummary = taskResponseSummary, - completedAt = DateTime.UtcNow, - taskType = "ScriptTask" - } - }, - Tags = new[] { "task-test", "task-response", "context-access", "success" } - }); - } - catch (Exception ex) - { - LogError("TaskResponse Usage Test - Output handler exception: {0}", - args: new object?[] { ex.Message }); - - return Task.FromResult(new ScriptResponse - { - Key = "task-response-exception", - Data = new - { - taskResponseResult = new - { - success = false, - error = ex.Message, - taskType = "ScriptTask" - } - } - }); - } - } -} - diff --git a/core/Workflows/task-test/src/TimeoutHandlerMapping.csx b/core/Workflows/task-test/src/TimeoutHandlerMapping.csx deleted file mode 100644 index b2d6c99..0000000 --- a/core/Workflows/task-test/src/TimeoutHandlerMapping.csx +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Threading.Tasks; -using BBT.Workflow.Definitions; -using BBT.Workflow.Scripting; - -/// -/// Timeout Handler Mapping - Handles timeout scenarios -/// -public class TimeoutHandlerMapping : IMapping -{ - public Task InputHandler(WorkflowTask task, ScriptContext context) - { - return Task.FromResult(new ScriptResponse()); - } - - public async Task OutputHandler(ScriptContext context) - { - try - { - var data = context.Instance?.Data; - - return new ScriptResponse - { - Key = "timeout-handled", - Data = new - { - timeoutResult = new - { - timeoutHandled = true, - originalTimeout = data?.timeoutInfo, - handlerAction = "abort-and-notify", - handledAt = DateTime.UtcNow, - note = "Timeout was caught by ErrorBoundary.onTimeout policy" - } - }, - Tags = new[] { "error-boundary-test", "timeout-handler" } - }; - } - catch (Exception ex) - { - return new ScriptResponse - { - Key = "timeout-handler-exception", - Data = new { error = ex.Message } - }; - } - } -} - diff --git a/core/Workflows/task-test/task-test-subflow.json b/core/Workflows/task-test/task-test-subflow.json deleted file mode 100644 index 5cc3a98..0000000 --- a/core/Workflows/task-test/task-test-subflow.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "key": "task-test-subflow", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "task-test", - "subflow", - "helper-workflow", - "integration-test" - ], - "attributes": { - "type": "S", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Task Test Subflow" - }, - { - "language": "tr-TR", - "label": "Task Testi Alt Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [], - "sharedTransitions": [], - "startTransition": { - "key": "start-subflow", - "target": "subflow-active", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Subflow" - }, - { - "language": "tr-TR", - "label": "Alt Akışı Başlat" - } - ], - "onExecutionTasks": [] - }, - "states": [ - { - "key": "subflow-active", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Subflow Active" - }, - { - "language": "tr-TR", - "label": "Alt Akış Aktif" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [ - { - "key": "complete-subflow", - "target": "subflow-completed", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Complete Subflow" - }, - { - "language": "tr-TR", - "label": "Alt Akışı Tamamla" - } - ], - "schema": null, - "rule": null, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "subflow-completed", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Subflow Completed" - }, - { - "language": "tr-TR", - "label": "Alt Akış Tamamlandı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/core/Workflows/task-test/task-test-workflow.http b/core/Workflows/task-test/task-test-workflow.http deleted file mode 100644 index adb795b..0000000 --- a/core/Workflows/task-test/task-test-workflow.http +++ /dev/null @@ -1,149 +0,0 @@ -############################################################################### -# Task Test Workflow - HTTP Test File -# -# This file tests the task-test-workflow which demonstrates all vNext task types: -# - DaprPubSub (Type 4) -# - HttpTask (Type 6) -# - DaprServiceTask (Type 3) -# - NotificationTask (Type 8) -# - ScriptTask (Type 7) -# - GetInstanceData (Type 13) -# - DirectTransition (Type 12) -# - Start (Type 11) -# - SubProcess (Type 14) -# -# Prerequisites: -# 1. vNext Runtime running on localhost:4201 -# 2. Mockoon running on localhost:3001 -# 3. Dapr sidecar running (for DaprPubSub and DaprServiceTask) -############################################################################### - -@baseUrl = http://localhost:4201 -@apiVersion = 1 -@domain = core -@workflow = task-test-workflow -@subflow = task-test-subflow -@instanceKey = task-test-{{$timestamp}} - -############################################################################### -# Step 1: Start Task Test Workflow -# This initiates the main workflow that will test all task types -############################################################################### - -### Start Main Workflow Instance -# @name startWorkflow -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/start -Content-Type: application/json - -{ - "key": "{{instanceKey}}", - "tags": ["task-test", "all-task-types", "integration-test"], - "attributes": { - "testId": "test-{{$timestamp}}", - "testName": "All Task Types Test", - "testDescription": "Testing all vNext task types in a single workflow", - "startedBy": "http-test-file", - "environment": "development" - } -} - -############################################################################### -# Step 2: Check Workflow State (Long Polling) -# The workflow should automatically progress through all states -############################################################################### - -### Get Current State - Use Long Polling -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/state -Accept: application/json - -############################################################################### -# Step 3: Get Instance Data -# Retrieve all accumulated data from the workflow instance -############################################################################### - -### Get Instance Data -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{workflow}}/instances/{{instanceKey}}/functions/data -Accept: application/json - -############################################################################### -# Subflow Operations - For Start, GetInstanceData, DirectTransition tests -############################################################################### - -### Start Subflow Instance Manually (for testing Start task type) -# @name startSubflow -POST {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{subflow}}/instances/start -Content-Type: application/json - -{ - "key": "subflow-{{$timestamp}}", - "tags": ["task-test", "subflow", "helper"], - "attributes": { - "parentTestId": "test-{{$timestamp}}", - "purpose": "Testing Start, GetInstanceData, DirectTransition tasks", - "createdAt": "{{$isoTimestamp}}" - } -} - -### Get Subflow State -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{subflow}}/instances/subflow-{{$timestamp}}/functions/state -Accept: application/json - -### Get Subflow Data -GET {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{subflow}}/instances/subflow-{{$timestamp}}/functions/data -Accept: application/json - -### Complete Subflow (DirectTransition test target) -PATCH {{baseUrl}}/api/v{{apiVersion}}/{{domain}}/workflows/{{subflow}}/instances/subflow-{{$timestamp}}/transitions/complete-subflow -Content-Type: application/json - -{ - "completedBy": "http-test-file", - "completedAt": "{{$isoTimestamp}}", - "message": "Subflow completed via HTTP test" -} - -############################################################################### -# Mockoon Endpoint Tests - Verify Mock Server is Running -############################################################################### - -### Test Mockoon Health Check -GET http://localhost:3001/health -Accept: application/json - -### Test Task Test HTTP Endpoint (Mockoon) -POST http://localhost:3001/api/task-test/http-endpoint -Content-Type: application/json - -{ - "testId": "mockoon-test-{{$timestamp}}", - "action": "http-task-test", - "timestamp": "{{$isoTimestamp}}" -} - -### Test Task Test HTTP Endpoint - Error Scenario -POST http://localhost:3001/api/task-test/http-endpoint -Content-Type: application/json - -{ - "testId": "mockoon-error-test-{{$timestamp}}", - "simulateError": "true" -} - -############################################################################### -# Task Type Summary -############################################################################### -# -# | Task Type | Type Code | Description | -# |------------------|-----------|---------------------------------------| -# | DaprServiceTask | 3 | Dapr service-to-service invocation | -# | DaprPubSubTask | 4 | Dapr publish/subscribe messaging | -# | HttpTask | 6 | External HTTP API calls | -# | ScriptTask | 7 | Custom business logic execution | -# | NotificationTask | 8 | Real-time client notifications | -# | StartTask | 11 | Start new workflow instance | -# | DirectTriggerTask| 12 | Trigger transition on existing inst. | -# | GetInstanceData | 13 | Fetch data from another workflow | -# | SubProcessTask | 14 | Fire-and-forget subprocess launch | -# -############################################################################### - diff --git a/core/Workflows/task-test/task-test-workflow.json b/core/Workflows/task-test/task-test-workflow.json deleted file mode 100644 index 771f861..0000000 --- a/core/Workflows/task-test/task-test-workflow.json +++ /dev/null @@ -1,902 +0,0 @@ -{ - "key": "task-test-workflow", - "flow": "sys-flows", - "flowVersion": "1.0.0", - "domain": "core", - "version": "1.0.0", - "tags": [ - "task-test", - "all-task-types", - "integration-test", - "get-secret-async", - "get-config-value", - "task-response", - "dapr-pubsub", - "http-task", - "dapr-service", - "notification", - "script", - "get-instance-data", - "get-instances", - "direct-transition", - "start", - "subprocess" - ], - "attributes": { - "type": "F", - "timeout": null, - "labels": [ - { - "language": "en-US", - "label": "Task Type Test Workflow" - }, - { - "language": "tr-TR", - "label": "Task Tipi Test İş Akışı" - } - ], - "functions": [], - "features": [], - "extensions": [ - { - "key": "test-http-data-extension", - "domain": "core", - "version": "1.0.0", - "flow": "sys-extensions" - }, - { - "key": "test-http-transform-extension", - "domain": "core", - "version": "1.0.0", - "flow": "sys-extensions" - } - ], - "sharedTransitions": [], - "startTransition": { - "key": "start-task-test", - "target": "test-get-secret-state", - "triggerType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Task Test" - }, - { - "language": "tr-TR", - "label": "Task Testini Başlat" - } - ], - "onExecutionTasks": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/InitialTransitionMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7dXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZy5GdW5jdGlvbnM7CgovLy8gPHN1bW1hcnk+Ci8vLyBJbml0aWFsIFRyYW5zaXRpb24gTWFwcGluZyAtIEluaXRpYWxpemVzIHdvcmtmbG93IHdpdGggdGVzdCBkYXRhCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBJbml0aWFsVHJhbnNpdGlvbk1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkluaXRpYWxUcmFuc2l0aW9uTWFwcGluZyBvdXRwdXQgaGFuZGxlciBzdGFydGluZy4uLiIpOwogICAgICAgICAgICB2YXIgaW5wdXREYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImluaXRpYWwtc3VjY2VzcyIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGVzdElkID0gaW5wdXREYXRhPy50ZXN0SWQgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgICAgICB3b3JrZmxvd1N0YXJ0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICB0ZXN0Q29uZmlndXJhdGlvbiA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdEdldFNlY3JldEFzeW5jID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdEdldENvbmZpZ1ZhbHVlID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdFRhc2tSZXNwb25zZSA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3REYXByUHViU3ViID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdEh0dHBUYXNrID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdERhcHJTZXJ2aWNlVGFzayA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3ROb3RpZmljYXRpb25UYXNrID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdFNjcmlwdFRhc2sgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICB0ZXN0R2V0SW5zdGFuY2VEYXRhID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdEdldEluc3RhbmNlcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3REaXJlY3RUcmFuc2l0aW9uID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGVzdFN0YXJ0V29ya2Zsb3cgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICB0ZXN0U3ViUHJvY2VzcyA9IHRydWUKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgICAgIHRhc2tUZXN0UmVzdWx0cyA9IG5ldyB7IH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgImluaXRpYWxpemVkIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJpbml0aWFsLWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQ==" - } - } - ] - }, - "states": [ - { - "key": "test-get-secret-state", - "stateType": 1, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test GetSecretAsync" - }, - { - "language": "tr-TR", - "label": "GetSecretAsync Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/GetSecretAsyncMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gR2V0U2VjcmV0QXN5bmMgVGVzdCBNYXBwaW5nIC0gRGVtb25zdHJhdGVzIHNlY3JldCByZXRyaWV2YWwgZnJvbSBEYXByIHNlY3JldCBzdG9yZQovLy8gVGVzdCBjYXNlOiBWZXJpZnkgR2V0U2VjcmV0QXN5bmMgZnVuY3Rpb25hbGl0eSBhbmQgbG9nZ2luZwovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgR2V0U2VjcmV0QXN5bmNNYXBwaW5nIDogU2NyaXB0QmFzZSwgSU1hcHBpbmcKewogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkdldFNlY3JldEFzeW5jIFRlc3QgLSBTdGFydGluZyBzZWNyZXQgcmV0cmlldmFsIHRlc3QiKTsKCiAgICAgICAgICAgIC8vIFJldHJpZXZlIEFQSSBzZWNyZXQgZnJvbSBEYXByIHNlY3JldCBzdG9yZSB1c2luZyBHZXRTZWNyZXRBc3luYwogICAgICAgICAgICB2YXIgYXBpU2VjcmV0ID0gYXdhaXQgR2V0U2VjcmV0QXN5bmMoInZuZXh0LXNlY3JldCIsICJ3b3JrZmxvdy1zZWNyZXQiLCAiQXBpU2VjcmV0Iik7CiAgICAgICAgICAgIAogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiR2V0U2VjcmV0QXN5bmMgVGVzdCAtIFN1Y2Nlc3NmdWxseSByZXRyaWV2ZWQgQXBpU2VjcmV0Iik7CiAgICAgICAgICAgIExvZ0RlYnVnKCJHZXRTZWNyZXRBc3luYyBUZXN0IC0gU2VjcmV0IHZhbHVlIGxlbmd0aDogezB9IiwgCiAgICAgICAgICAgICAgICBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgYXBpU2VjcmV0Py5MZW5ndGggPz8gMCB9KTsKCiAgICAgICAgICAgIC8vIFN0b3JlIHRoZSByZXN1bHQgZm9yIG91dHB1dCBoYW5kbGVyCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNlY3JldFJldHJpZXZlZCA9ICFzdHJpbmcuSXNOdWxsT3JFbXB0eShhcGlTZWNyZXQpLAogICAgICAgICAgICAgICAgICAgIHNlY3JldEtleU5hbWUgPSAiQXBpU2VjcmV0IiwKICAgICAgICAgICAgICAgICAgICByZXRyaWV2ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIkdldFNlY3JldEFzeW5jIFRlc3QgLSBGYWlsZWQgdG8gcmV0cmlldmUgc2VjcmV0OiB7MH0iLCAKICAgICAgICAgICAgICAgIGFyZ3M6IG5ldyBvYmplY3Q/W10geyBleC5NZXNzYWdlIH0pOwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZ2V0LXNlY3JldC1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkdldFNlY3JldEFzeW5jIFRlc3QgLSBQcm9jZXNzaW5nIG91dHB1dCIpOwoKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZ2V0LXNlY3JldC1zdWNjZXNzIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBnZXRTZWNyZXRSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICB0ZXN0TmFtZSA9ICJHZXRTZWNyZXRBc3luYyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIlJldHJpZXZlZCBBcGlTZWNyZXQgZnJvbSBEYXByIHNlY3JldCBzdG9yZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJTY3JpcHRUYXNrIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgImdldC1zZWNyZXQtYXN5bmMiLCAic3VjY2VzcyIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIkdldFNlY3JldEFzeW5jIFRlc3QgLSBPdXRwdXQgaGFuZGxlciBleGNlcHRpb246IHswfSIsIAogICAgICAgICAgICAgICAgYXJnczogbmV3IG9iamVjdD9bXSB7IGV4Lk1lc3NhZ2UgfSk7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJnZXQtc2VjcmV0LWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZ2V0U2VjcmV0UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiU2NyaXB0VGFzayIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "get-secret-completed", - "target": "test-get-config-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "GetSecretAsync Completed" - }, - { - "language": "tr-TR", - "label": "GetSecretAsync Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-get-config-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test GetConfigValue" - }, - { - "language": "tr-TR", - "label": "GetConfigValue Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/GetConfigValueMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gR2V0Q29uZmlnVmFsdWUgVGVzdCBNYXBwaW5nIC0gRGVtb25zdHJhdGVzIGNvbmZpZ3VyYXRpb24gdmFsdWUgcmV0cmlldmFsCi8vLyBUZXN0IGNhc2U6IFZlcmlmeSBHZXRDb25maWdWYWx1ZSBmdW5jdGlvbmFsaXR5IGFuZCBsb2dnaW5nCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBHZXRDb25maWdWYWx1ZU1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiR2V0Q29uZmlnVmFsdWUgVGVzdCAtIFN0YXJ0aW5nIGNvbmZpZ3VyYXRpb24gcmV0cmlldmFsIHRlc3QiKTsKCiAgICAgICAgICAgIC8vIFJldHJpZXZlIEFQSSBiYXNlIFVSTCBmcm9tIGNvbmZpZ3VyYXRpb24gdXNpbmcgR2V0Q29uZmlnVmFsdWUKICAgICAgICAgICAgdmFyIGFwaUJhc2VVcmwgPSBHZXRDb25maWdWYWx1ZSgiRXhhbXBsZTpBcGlCYXNlVXJsIik7CiAgICAgICAgICAgIAogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiR2V0Q29uZmlnVmFsdWUgVGVzdCAtIFN1Y2Nlc3NmdWxseSByZXRyaWV2ZWQgQXBpQmFzZVVybDogezB9IiwgCiAgICAgICAgICAgICAgICBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgYXBpQmFzZVVybCA/PyAibnVsbCIgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY29uZmlnUmV0cmlldmVkID0gIXN0cmluZy5Jc051bGxPckVtcHR5KGFwaUJhc2VVcmwpLAogICAgICAgICAgICAgICAgICAgIGNvbmZpZ0tleU5hbWUgPSAiQXBpQmFzZVVybCIsCiAgICAgICAgICAgICAgICAgICAgY29uZmlnVmFsdWUgPSBhcGlCYXNlVXJsLAogICAgICAgICAgICAgICAgICAgIHJldHJpZXZlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIkdldENvbmZpZ1ZhbHVlIFRlc3QgLSBGYWlsZWQgdG8gcmV0cmlldmUgY29uZmlnOiB7MH0iLCAKICAgICAgICAgICAgICAgIGFyZ3M6IG5ldyBvYmplY3Q/W10geyBleC5NZXNzYWdlIH0pOwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdldC1jb25maWctaW5wdXQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiR2V0Q29uZmlnVmFsdWUgVGVzdCAtIFByb2Nlc3Npbmcgb3V0cHV0Iik7CgogICAgICAgICAgICB2YXIgaW5wdXREYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJnZXQtY29uZmlnLXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGdldENvbmZpZ1Jlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3ROYW1lID0gIkdldENvbmZpZ1ZhbHVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAiUmV0cmlldmVkIEFwaUJhc2VVcmwgZnJvbSBjb25maWd1cmF0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiU2NyaXB0VGFzayIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJnZXQtY29uZmlnLXZhbHVlIiwgInN1Y2Nlc3MiIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiR2V0Q29uZmlnVmFsdWUgVGVzdCAtIE91dHB1dCBoYW5kbGVyIGV4Y2VwdGlvbjogezB9IiwgCiAgICAgICAgICAgICAgICBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgZXguTWVzc2FnZSB9KTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJnZXQtY29uZmlnLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZ2V0Q29uZmlnUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiU2NyaXB0VGFzayIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "get-config-completed", - "target": "test-dapr-pubsub-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "GetConfigValue Completed" - }, - { - "language": "tr-TR", - "label": "GetConfigValue Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-dapr-pubsub-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test DaprPubSub" - }, - { - "language": "tr-TR", - "label": "DaprPubSub Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "test-dapr-pubsub", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/DaprPubSubMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBEYXByUHViU3ViIFRhc2sgTWFwcGluZyAtIFB1Ymxpc2hlcyBldmVudHMgdG8gbWVzc2FnZSBidXMKLy8vIFRlc3QgY2FzZTogVmVyaWZ5IGV2ZW50IHB1Ymxpc2hpbmcgdG8gRGFwciBQdWJTdWIgY29tcG9uZW50Ci8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBEYXByUHViU3ViTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBwdWJzdWJUYXNrID0gdGFzayBhcyBEYXByUHViU3ViVGFzazsKICAgICAgICAgICAgaWYgKHB1YnN1YlRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIERhcHJQdWJTdWJUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBQdWJTdWIgY29tcG9uZW50CiAgICAgICAgICAgIHB1YnN1YlRhc2suU2V0UHViU3ViTmFtZSgidm5leHQtZXhlY3V0aW9uLXB1YnN1YiIpOwogICAgICAgICAgICBwdWJzdWJUYXNrLlNldFRvcGljKCJ2bmV4dC50ZXN0LmV2ZW50cyIpOwoKICAgICAgICAgICAgLy8gQ3JlYXRlIENsb3VkIEV2ZW50cyBmb3JtYXQgZGF0YQogICAgICAgICAgICB2YXIgZXZlbnREYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNwZWN2ZXJzaW9uID0gIjEuMCIsCiAgICAgICAgICAgICAgICB0eXBlID0gImNvbS52bmV4dC50YXNrLXRlc3QuVGVzdEV2ZW50IiwKICAgICAgICAgICAgICAgIHNvdXJjZSA9ICJ0YXNrLXRlc3Qtd29ya2Zsb3ciLAogICAgICAgICAgICAgICAgaWQgPSBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgdGltZSA9IERhdGVUaW1lLlV0Y05vdy5Ub1N0cmluZygiTyIpLAogICAgICAgICAgICAgICAgZGF0YWNvbnRlbnR0eXBlID0gImFwcGxpY2F0aW9uL2pzb24iLAogICAgICAgICAgICAgICAgZGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRlc3RJZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRlc3RJZCA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgICAgIHdvcmtmbG93SWQgPSBjb250ZXh0LldvcmtmbG93LktleSwKICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSAiRGFwclB1YlN1YiB0ZXN0IGV2ZW50IHB1Ymxpc2hlZCIKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHB1YnN1YlRhc2suU2V0RGF0YShldmVudERhdGEpOwoKICAgICAgICAgICAgLy8gU2V0IG1ldGFkYXRhCiAgICAgICAgICAgIHZhciBtZXRhZGF0YSA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPz4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgWyJwcmlvcml0eSJdID0gIm5vcm1hbCIsCiAgICAgICAgICAgICAgICBbImNvcnJlbGF0aW9uSWQiXSA9IGNvbnRleHQuSW5zdGFuY2UuSWQuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIFsic291cmNlIl0gPSAidGFzay10ZXN0LXdvcmtmbG93IgogICAgICAgICAgICB9OwogICAgICAgICAgICBwdWJzdWJUYXNrLlNldE1ldGFkYXRhKG1ldGFkYXRhKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRhcHItcHVic3ViLWlucHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwoKICAgICAgICAgICAgaWYgKHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPT0gdHJ1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJkYXByLXB1YnN1Yi1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBkYXByUHViU3ViUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHVibGlzaGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJEYXByUHViU3ViIgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgImRhcHItcHVic3ViIiwgInN1Y2Nlc3MiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRhcHItcHVic3ViLWZhaWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGFwclB1YlN1YlJlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IHJlc3BvbnNlPy5lcnJvck1lc3NhZ2UgPz8gIlVua25vd24gZXJyb3IiLAogICAgICAgICAgICAgICAgICAgICAgICBmYWlsZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiRGFwclB1YlN1YiIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJkYXByLXB1YnN1YiIsICJmYWlsZWQiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRhcHItcHVic3ViLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGFwclB1YlN1YlJlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIkRhcHJQdWJTdWIiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "dapr-pubsub-completed", - "target": "test-http-items-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "DaprPubSub Completed" - }, - { - "language": "tr-TR", - "label": "DaprPubSub Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-http-items-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Items HttpTask" - }, - { - "language": "tr-TR", - "label": "HttpTask Items Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "test-http-items", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/HttpTaskItemsMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBIVFRQIFRhc2sgTWFwcGluZyAtIE1ha2VzIGV4dGVybmFsIEFQSSBjYWxscwovLy8gVGVzdCBjYXNlOiBWZXJpZnkgSFRUUCByZXF1ZXN0cyB0byBleHRlcm5hbCBzZXJ2aWNlcyB2aWEgTW9ja29vbgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgSHR0cFRhc2tJdGVtc01hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgaHR0cFRhc2sgPSB0YXNrIGFzIEh0dHBUYXNrOwogICAgICAgICAgICBpZiAoaHR0cFRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhbiBIdHRwVGFzayIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBQcmVwYXJlIHJlcXVlc3QgYm9keQogICAgICAgICAgICB2YXIgcmVxdWVzdEJvZHkgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVzdElkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udGVzdElkID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICB3b3JrZmxvd0lkID0gY29udGV4dC5Xb3JrZmxvdy5LZXksCiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICB0aW1lc3RhbXAgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICBhY3Rpb24gPSAiaHR0cC10YXNrLXRlc3QiCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBodHRwVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KTsKCiAgICAgICAgICAgIC8vIFNldCBoZWFkZXJzCiAgICAgICAgICAgIHZhciBoZWFkZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbIkNvbnRlbnQtVHlwZSJdID0gImFwcGxpY2F0aW9uL2pzb24iLAogICAgICAgICAgICAgICAgWyJYLVRlc3QtSWQiXSA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRlc3RJZD8uVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIFsiWC1SZXF1ZXN0LUlkIl0gPSBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgWyJYLUNvcnJlbGF0aW9uLUlkIl0gPSBjb250ZXh0Lkluc3RhbmNlLklkLlRvU3RyaW5nKCkKICAgICAgICAgICAgfTsKICAgICAgICAgICAgaHR0cFRhc2suU2V0SGVhZGVycyhoZWFkZXJzKTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImh0dHAtdGFzay1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKICAgICAgICAgICAgdmFyIHN0YXR1c0NvZGUgPSByZXNwb25zZT8uc3RhdHVzQ29kZSA/PyA1MDA7CgogICAgICAgICAgICBpZiAoc3RhdHVzQ29kZSA+PSAyMDAgJiYgc3RhdHVzQ29kZSA8IDMwMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJodHRwLXRhc2stc3VjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cFRhc2tJdGVtc1Jlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHJlc3BvbnNlPy5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0aW9uVGltZSA9IHJlc3BvbnNlPy5leGVjdXRpb25EdXJhdGlvbk1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2VkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJIdHRwVGFzayIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJodHRwLXRhc2siLCAic3VjY2VzcyIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiaHR0cC10YXNrLWZhaWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaHR0cFRhc2tJdGVtc1Jlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0gc3RhdHVzQ29kZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSByZXNwb25zZT8uZXJyb3JNZXNzYWdlID8/ICJIVFRQIHJlcXVlc3QgZmFpbGVkIiwKICAgICAgICAgICAgICAgICAgICAgICAgZmFpbGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIkh0dHBUYXNrIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgImh0dHAtdGFzayIsICJmYWlsZWQiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImh0dHAtdGFzay1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGh0dHBUYXNrSXRlbXNSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBleC5NZXNzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJIdHRwVGFzayIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "http-task-completed", - "target": "test-http-task-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "HttpTask Completed" - }, - { - "language": "tr-TR", - "label": "HttpTask Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-http-task-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test HttpTask" - }, - { - "language": "tr-TR", - "label": "HttpTask Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "test-http-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/HttpTaskMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBIVFRQIFRhc2sgTWFwcGluZyAtIE1ha2VzIGV4dGVybmFsIEFQSSBjYWxscwovLy8gVGVzdCBjYXNlOiBWZXJpZnkgSFRUUCByZXF1ZXN0cyB0byBleHRlcm5hbCBzZXJ2aWNlcyB2aWEgTW9ja29vbgovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgSHR0cFRhc2tNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIGh0dHBUYXNrID0gdGFzayBhcyBIdHRwVGFzazsKICAgICAgICAgICAgaWYgKGh0dHBUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYW4gSHR0cFRhc2siKTsKICAgICAgICAgICAgfQogCiAgICAgICAgICAgIC8vIFByZXBhcmUgcmVxdWVzdCBib2R5CiAgICAgICAgICAgIHZhciByZXF1ZXN0Qm9keSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0ZXN0SWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50ZXN0SWQgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIHdvcmtmbG93SWQgPSBjb250ZXh0LldvcmtmbG93LktleSwKICAgICAgICAgICAgICAgIGluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgIHRpbWVzdGFtcCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIGFjdGlvbiA9ICJodHRwLXRhc2stdGVzdCIKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIGh0dHBUYXNrLlNldEJvZHkocmVxdWVzdEJvZHkpOwoKICAgICAgICAgICAgLy8gU2V0IGhlYWRlcnMKICAgICAgICAgICAgdmFyIGhlYWRlcnMgPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIHN0cmluZz8+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFsiQ29udGVudC1UeXBlIl0gPSAiYXBwbGljYXRpb24vanNvbiIsCiAgICAgICAgICAgICAgICBbIlgtVGVzdC1JZCJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udGVzdElkPy5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgWyJYLVJlcXVlc3QtSWQiXSA9IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIlgtQ29ycmVsYXRpb24tSWQiXSA9IGNvbnRleHQuSW5zdGFuY2UuSWQuVG9TdHJpbmcoKQogICAgICAgICAgICB9OwogICAgICAgICAgICBodHRwVGFzay5TZXRIZWFkZXJzKGhlYWRlcnMpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiaHR0cC10YXNrLWlucHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwogICAgICAgICAgICB2YXIgc3RhdHVzQ29kZSA9IHJlc3BvbnNlPy5zdGF0dXNDb2RlID8/IDUwMDsKCiAgICAgICAgICAgIGlmIChzdGF0dXNDb2RlID49IDIwMCAmJiBzdGF0dXNDb2RlIDwgMzAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgS2V5ID0gImh0dHAtdGFzay1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBodHRwVGFza1Jlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHJlc3BvbnNlPy5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0aW9uVGltZSA9IHJlc3BvbnNlPy5leGVjdXRpb25EdXJhdGlvbk1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc2VkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJIdHRwVGFzayIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJodHRwLXRhc2siLCAic3VjY2VzcyIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiaHR0cC10YXNrLWZhaWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaHR0cFRhc2tSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gcmVzcG9uc2U/LmVycm9yTWVzc2FnZSA/PyAiSFRUUCByZXF1ZXN0IGZhaWxlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZhaWxlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJIdHRwVGFzayIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJodHRwLXRhc2siLCAiZmFpbGVkIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJodHRwLXRhc2stZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBodHRwVGFza1Jlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIkh0dHBUYXNrIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - }, - { - "order": 2, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/TaskResponseUsageMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmcuRnVuY3Rpb25zOwoKLy8vIDxzdW1tYXJ5PgovLy8gVGFza1Jlc3BvbnNlIFVzYWdlIFRlc3QgTWFwcGluZyAtIERlbW9uc3RyYXRlcyBhY2Nlc3NpbmcgcHJldmlvdXMgdGFzayByZXNwb25zZXMKLy8vIFRlc3QgY2FzZTogVmVyaWZ5IFRhc2tSZXNwb25zZSBkaWN0aW9uYXJ5IHVzYWdlIGluIFNjcmlwdENvbnRleHQgYWZ0ZXIgSFRUUCB0YXNrcwovLy8gTm90ZTogVGFza1Jlc3BvbnNlIGtleXMgYXJlIHRoZSB0YXNrJ3MgImtleSIgdmFsdWUgY29udmVydGVkIHRvIGNhbWVsQ2FzZQovLy8gRXhhbXBsZTogInRlc3QtaHR0cC10YXNrIiBiZWNvbWVzICJ0ZXN0SHR0cFRhc2siCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBUYXNrUmVzcG9uc2VVc2FnZU1hcHBpbmcgOiBTY3JpcHRCYXNlLCBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiVGFza1Jlc3BvbnNlIFVzYWdlIFRlc3QgLSBTdGFydGluZyBUYXNrUmVzcG9uc2UgYWNjZXNzIHRlc3QiKTsKCiAgICAgICAgICAgIC8vIEFjY2VzcyBUYXNrUmVzcG9uc2UgZGljdGlvbmFyeSBmcm9tIFNjcmlwdENvbnRleHQKICAgICAgICAgICAgLy8gVGhpcyBjb250YWlucyByZXN1bHRzIGZyb20gcHJldmlvdXNseSBjb21wbGV0ZWQgdGFza3MgaW4gdGhlIHdvcmtmbG93CiAgICAgICAgICAgIHZhciB0YXNrUmVzcG9uc2VEaWN0ID0gY29udGV4dC5UYXNrUmVzcG9uc2U7CgogICAgICAgICAgICBpZiAodGFza1Jlc3BvbnNlRGljdCAhPSBudWxsICYmIHRhc2tSZXNwb25zZURpY3QuQ291bnQgPiAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiVGFza1Jlc3BvbnNlIFVzYWdlIFRlc3QgLSBGb3VuZCB7MH0gdGFzayByZXNwb25zZShzKSBpbiBjb250ZXh0IiwgCiAgICAgICAgICAgICAgICAgICAgYXJnczogbmV3IG9iamVjdD9bXSB7IHRhc2tSZXNwb25zZURpY3QuQ291bnQgfSk7CgogICAgICAgICAgICAgICAgLy8gTG9nIGFsbCBhdmFpbGFibGUgdGFzayByZXNwb25zZSBrZXlzCiAgICAgICAgICAgICAgICBmb3JlYWNoICh2YXIga2V5IGluIHRhc2tSZXNwb25zZURpY3QuS2V5cykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBMb2dEZWJ1ZygiVGFza1Jlc3BvbnNlIFVzYWdlIFRlc3QgLSBBdmFpbGFibGUgdGFzayByZXNwb25zZSBrZXk6IHswfSIsIAogICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBuZXcgb2JqZWN0P1tdIHsga2V5IH0pOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIEV4YW1wbGU6IEFjY2VzcyBzcGVjaWZpYyB0YXNrIHJlc3BvbnNlIGlmIGl0IGV4aXN0cwogICAgICAgICAgICAgICAgLy8gVGFza1Jlc3BvbnNlIGtleSBpcyB0aGUgdGFzaydzICJrZXkiIHZhbHVlIGNvbnZlcnRlZCB0byBjYW1lbENhc2UKICAgICAgICAgICAgICAgIC8vIGUuZy4sICJ0ZXN0LWh0dHAtdGFzayIgYmVjb21lcyAidGVzdEh0dHBUYXNrIgogICAgICAgICAgICAgICAgaWYgKHRhc2tSZXNwb25zZURpY3QuQ29udGFpbnNLZXkoInRlc3RIdHRwVGFzayIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHZhciBodHRwVGFza1Jlc3VsdCA9IHRhc2tSZXNwb25zZURpY3RbInRlc3RIdHRwVGFzayJdOwogICAgICAgICAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJUYXNrUmVzcG9uc2UgVXNhZ2UgVGVzdCAtIEhUVFAgdGFzayByZXNwb25zZSBmb3VuZDogaXNTdWNjZXNzPXswfSwgc3RhdHVzQ29kZT17MX0iLCAKICAgICAgICAgICAgICAgICAgICAgICAgYXJnczogbmV3IG9iamVjdD9bXSB7IGh0dHBUYXNrUmVzdWx0Py5pc1N1Y2Nlc3MsIGh0dHBUYXNrUmVzdWx0Py5zdGF0dXNDb2RlIH0pOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIEFjY2VzcyByZXNwb25zZSBkYXRhCiAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3BvbnNlRGF0YSA9IGh0dHBUYXNrUmVzdWx0Py5kYXRhOwogICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZURhdGEgIT0gbnVsbCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIExvZ0RlYnVnKCJUYXNrUmVzcG9uc2UgVXNhZ2UgVGVzdCAtIEhUVFAgcmVzcG9uc2UgZGF0YSBhdmFpbGFibGUiKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMb2dXYXJuaW5nKCJUYXNrUmVzcG9uc2UgVXNhZ2UgVGVzdCAtIE5vIHByZXZpb3VzIHRhc2sgcmVzcG9uc2VzIGZvdW5kIGluIGNvbnRleHQiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRhc2tSZXNwb25zZUNvdW50ID0gdGFza1Jlc3BvbnNlRGljdD8uQ291bnQgPz8gMCwKICAgICAgICAgICAgICAgICAgICB0YXNrUmVzcG9uc2VLZXlzID0gdGFza1Jlc3BvbnNlRGljdCAhPSBudWxsIAogICAgICAgICAgICAgICAgICAgICAgICA/IHN0cmluZy5Kb2luKCIsICIsIHRhc2tSZXNwb25zZURpY3QuS2V5cykgCiAgICAgICAgICAgICAgICAgICAgICAgIDogIm5vbmUiLAogICAgICAgICAgICAgICAgICAgIHRlc3RlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIlRhc2tSZXNwb25zZSBVc2FnZSBUZXN0IC0gRmFpbGVkIHRvIGFjY2VzcyBUYXNrUmVzcG9uc2U6IHswfSIsIAogICAgICAgICAgICAgICAgYXJnczogbmV3IG9iamVjdD9bXSB7IGV4Lk1lc3NhZ2UgfSk7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAidGFzay1yZXNwb25zZS1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJUYXNrUmVzcG9uc2UgVXNhZ2UgVGVzdCAtIFByb2Nlc3Npbmcgb3V0cHV0Iik7CgogICAgICAgICAgICAvLyBEZW1vbnN0cmF0ZSBhY2Nlc3NpbmcgVGFza1Jlc3BvbnNlIGluIE91dHB1dEhhbmRsZXIgYXMgd2VsbAogICAgICAgICAgICB2YXIgdGFza1Jlc3BvbnNlRGljdCA9IGNvbnRleHQuVGFza1Jlc3BvbnNlOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gQnVpbGQgYSBzdW1tYXJ5IG9mIGF2YWlsYWJsZSB0YXNrIHJlc3BvbnNlcwogICAgICAgICAgICB2YXIgdGFza1Jlc3BvbnNlU3VtbWFyeSA9IG5ldyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0PG9iamVjdD4oKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGlmICh0YXNrUmVzcG9uc2VEaWN0ICE9IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGZvcmVhY2ggKHZhciBrdnAgaW4gdGFza1Jlc3BvbnNlRGljdCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0YXNrUmVzcG9uc2VTdW1tYXJ5LkFkZChuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tLZXkgPSBrdnAuS2V5LAogICAgICAgICAgICAgICAgICAgICAgICBoYXNEYXRhID0ga3ZwLlZhbHVlICE9IG51bGwsCiAgICAgICAgICAgICAgICAgICAgICAgIGlzU3VjY2VzcyA9IGt2cC5WYWx1ZT8uaXNTdWNjZXNzLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlID0ga3ZwLlZhbHVlPy5zdGF0dXNDb2RlLAogICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9IGt2cC5WYWx1ZT8udGFza1R5cGUKICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIlRhc2tSZXNwb25zZSBVc2FnZSBUZXN0IC0gUHJvY2Vzc2VkIHswfSB0YXNrIHJlc3BvbnNlKHMpIiwgCiAgICAgICAgICAgICAgICBhcmdzOiBuZXcgb2JqZWN0P1tdIHsgdGFza1Jlc3BvbnNlU3VtbWFyeS5Db3VudCB9KTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJ0YXNrLXJlc3BvbnNlLXN1Y2Nlc3MiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRhc2tSZXNwb25zZVJlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3ROYW1lID0gIlRhc2tSZXNwb25zZSBVc2FnZSIsCiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uID0gIkRlbW9uc3RyYXRlZCBjb250ZXh0LlRhc2tSZXNwb25zZSBkaWN0aW9uYXJ5IGFjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsVGFza1Jlc3BvbnNlcyA9IHRhc2tSZXNwb25zZURpY3Q/LkNvdW50ID8/IDAsCiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tSZXNwb25zZVN1bW1hcnkgPSB0YXNrUmVzcG9uc2VTdW1tYXJ5LAogICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiU2NyaXB0VGFzayIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJ0YXNrLXJlc3BvbnNlIiwgImNvbnRleHQtYWNjZXNzIiwgInN1Y2Nlc3MiIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiVGFza1Jlc3BvbnNlIFVzYWdlIFRlc3QgLSBPdXRwdXQgaGFuZGxlciBleGNlcHRpb246IHswfSIsIAogICAgICAgICAgICAgICAgYXJnczogbmV3IG9iamVjdD9bXSB7IGV4Lk1lc3NhZ2UgfSk7CiAgICAgICAgICAgIAogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAidGFzay1yZXNwb25zZS1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRhc2tSZXNwb25zZVJlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIlNjcmlwdFRhc2siCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "http-task-completed", - "target": "test-dapr-service-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "HttpTask Completed" - }, - { - "language": "tr-TR", - "label": "HttpTask Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-dapr-service-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test DaprServiceTask" - }, - { - "language": "tr-TR", - "label": "DaprServiceTask Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "test-dapr-service-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/DaprServiceTaskMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBEYXByU2VydmljZSBUYXNrIE1hcHBpbmcgLSBJbnZva2VzIERhcHIgc2VydmljZXMKLy8vIFRlc3QgY2FzZTogVmVyaWZ5IHNlcnZpY2UtdG8tc2VydmljZSBpbnZvY2F0aW9uIHZpYSBEYXByCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBEYXByU2VydmljZVRhc2tNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHNlcnZpY2VUYXNrID0gdGFzayBhcyBEYXByU2VydmljZVRhc2s7CiAgICAgICAgICAgIGlmIChzZXJ2aWNlVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgRGFwclNlcnZpY2VUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSB0YXJnZXQgc2VydmljZQogICAgICAgICAgICBzZXJ2aWNlVGFzay5TZXRBcHBJZCgibW9ja29vbiIpOwogICAgICAgICAgICBzZXJ2aWNlVGFzay5TZXRNZXRob2ROYW1lKCIvYXBpL3Rhc2stdGVzdC9kYXByLWVuZHBvaW50Iik7CgogICAgICAgICAgICAvLyBQcmVwYXJlIHJlcXVlc3QgYm9keQogICAgICAgICAgICB2YXIgcmVxdWVzdEJvZHkgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGVzdElkID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udGVzdElkID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICB3b3JrZmxvd0lkID0gY29udGV4dC5Xb3JrZmxvdy5LZXksCiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICB0aW1lc3RhbXAgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICBhY3Rpb24gPSAiZGFwci1zZXJ2aWNlLXRlc3QiCiAgICAgICAgICAgIH07CgogICAgICAgICAgICBzZXJ2aWNlVGFzay5TZXRCb2R5KHJlcXVlc3RCb2R5KTsKCiAgICAgICAgICAgIC8vIFNldCBoZWFkZXJzCiAgICAgICAgICAgIHZhciBoZWFkZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc/PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBbIlgtVGVzdC1JZCJdID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YT8udGVzdElkPy5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgWyJYLVJlcXVlc3QtSWQiXSA9IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCksCiAgICAgICAgICAgICAgICBbIlgtQ29ycmVsYXRpb24tSWQiXSA9IGNvbnRleHQuSW5zdGFuY2UuSWQuVG9TdHJpbmcoKQogICAgICAgICAgICB9OwogICAgICAgICAgICBzZXJ2aWNlVGFzay5TZXRIZWFkZXJzKGhlYWRlcnMpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZGFwci1zZXJ2aWNlLWlucHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwoKICAgICAgICAgICAgaWYgKHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPT0gdHJ1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJkYXByLXNlcnZpY2Utc3VjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZGFwclNlcnZpY2VSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gcmVzcG9uc2U/LmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRpb25UaW1lID0gcmVzcG9uc2U/LmV4ZWN1dGlvbkR1cmF0aW9uTXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9jZXNzZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIkRhcHJTZXJ2aWNlVGFzayIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJkYXByLXNlcnZpY2UiLCAic3VjY2VzcyIgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZGFwci1zZXJ2aWNlLWZhaWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGFwclNlcnZpY2VSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSByZXNwb25zZT8uZXJyb3JNZXNzYWdlID8/ICJEYXByIHNlcnZpY2UgaW52b2NhdGlvbiBmYWlsZWQiLAogICAgICAgICAgICAgICAgICAgICAgICBmYWlsZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiRGFwclNlcnZpY2VUYXNrIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgImRhcHItc2VydmljZSIsICJmYWlsZWQiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRhcHItc2VydmljZS1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRhcHJTZXJ2aWNlUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiRGFwclNlcnZpY2VUYXNrIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9Cn0KCg==" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "dapr-service-completed", - "target": "test-notification-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "DaprServiceTask Completed" - }, - { - "language": "tr-TR", - "label": "DaprServiceTask Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-notification-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test NotificationTask" - }, - { - "language": "tr-TR", - "label": "NotificationTask Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "notification-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "type": "G" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "notification-completed", - "target": "test-script-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "NotificationTask Completed" - }, - { - "language": "tr-TR", - "label": "NotificationTask Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-script-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test ScriptTask" - }, - { - "language": "tr-TR", - "label": "ScriptTask Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "script-task", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/ScriptTaskMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTY3JpcHQgVGFzayBNYXBwaW5nIC0gRXhlY3V0ZXMgY3VzdG9tIGJ1c2luZXNzIGxvZ2ljCi8vLyBUZXN0IGNhc2U6IFZlcmlmeSBzY3JpcHQgZXhlY3V0aW9uIGFuZCBkYXRhIHRyYW5zZm9ybWF0aW9uCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBTY3JpcHRUYXNrTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFNjcmlwdCB0YXNrcyBkb24ndCByZXF1aXJlIHNwZWNpZmljIHRhc2sgY29uZmlndXJhdGlvbgogICAgICAgICAgICAvLyBUaGV5IGFyZSB1c2VkIGZvciBkYXRhIHRyYW5zZm9ybWF0aW9uIGFuZCBidXNpbmVzcyBsb2dpYwogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzY3JpcHQtdGFzay1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIC8vIFBlcmZvcm0gZGF0YSB0cmFuc2Zvcm1hdGlvbgogICAgICAgICAgICB2YXIgaW5wdXREYXRhID0gY29udGV4dC5JbnN0YW5jZT8uRGF0YTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBzb21lIHZhbHVlcwogICAgICAgICAgICB2YXIgY2FsY3VsYXRlZFZhbHVlcyA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBvcmlnaW5hbFRlc3RJZCA9IGlucHV0RGF0YT8udGVzdElkLAogICAgICAgICAgICAgICAgcHJvY2Vzc2VkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICBjYWxjdWxhdGVkVmFsdWUgPSBuZXcgUmFuZG9tKCkuTmV4dCgxMDAwLCA5OTk5KSwKICAgICAgICAgICAgICAgIGlzUHJvY2Vzc2VkID0gdHJ1ZSwKICAgICAgICAgICAgICAgIHByb2Nlc3NpbmdEdXJhdGlvbiA9IERhdGVUaW1lLlV0Y05vdy5TdWJ0cmFjdChEYXRlVGltZS5VdGNOb3cuQWRkTWlsbGlzZWNvbmRzKC0xMDApKS5Ub3RhbE1pbGxpc2Vjb25kcwogICAgICAgICAgICB9OwoKICAgICAgICAgICAgLy8gVHJhbnNmb3JtIGFuZCBhZ2dyZWdhdGUgZGF0YQogICAgICAgICAgICB2YXIgdHJhbnNmb3JtZWREYXRhID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNjcmlwdFRhc2tSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbERhdGEgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHRlc3RJZCA9IGlucHV0RGF0YT8udGVzdElkLAogICAgICAgICAgICAgICAgICAgICAgICB3b3JrZmxvd0lkID0gY29udGV4dC5Xb3JrZmxvdy5LZXksCiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtZWQgPSBjYWxjdWxhdGVkVmFsdWVzLAogICAgICAgICAgICAgICAgICAgIG1ldGFkYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJTY3JpcHRUYXNrIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXhlY3V0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgc2NyaXB0VmVyc2lvbiA9ICIxLjAuMCIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzY3JpcHQtdGFzay1zdWNjZXNzIiwKICAgICAgICAgICAgICAgIERhdGEgPSB0cmFuc2Zvcm1lZERhdGEsCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgInNjcmlwdC10YXNrIiwgInN1Y2Nlc3MiLCAiZGF0YS10cmFuc2Zvcm1hdGlvbiIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAic2NyaXB0LXRhc2stZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBzY3JpcHRUYXNrUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gZXguTWVzc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiU2NyaXB0VGFzayIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9Cgo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "script-completed", - "target": "test-start-workflow-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "ScriptTask Completed" - }, - { - "language": "tr-TR", - "label": "ScriptTask Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-start-workflow-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test Start (New Workflow)" - }, - { - "language": "tr-TR", - "label": "Start Testi (Yeni İş Akışı)" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "test-start-workflow", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/StartWorkflowMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTdGFydCBXb3JrZmxvdyBUYXNrIE1hcHBpbmcgLSBTdGFydHMgYSBuZXcgd29ya2Zsb3cgaW5zdGFuY2UKLy8vIFRlc3QgY2FzZTogVmVyaWZ5IHN0YXJ0aW5nIG5ldyB3b3JrZmxvdyBpbnN0YW5jZXMKLy8vIDwvc3VtbWFyeT4KcHVibGljIGNsYXNzIFN0YXJ0V29ya2Zsb3dNYXBwaW5nIDogSU1hcHBpbmcKewogICAgcHVibGljIFRhc2s8U2NyaXB0UmVzcG9uc2U+IElucHV0SGFuZGxlcihXb3JrZmxvd1Rhc2sgdGFzaywgU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHN0YXJ0VGFzayA9IHRhc2sgYXMgU3RhcnRUYXNrOwogICAgICAgICAgICBpZiAoc3RhcnRUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYSBTdGFydFRhc2siKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ29uZmlndXJlIHRhcmdldCB3b3JrZmxvdwogICAgICAgICAgICBzdGFydFRhc2suU2V0RG9tYWluKCJjb3JlIik7CiAgICAgICAgICAgIHN0YXJ0VGFzay5TZXRGbG93KCJ0YXNrLXRlc3Qtc3ViZmxvdyIpOwogICAgICAgICAgICBzdGFydFRhc2suU2V0U3luYyh0cnVlKTsKICAgICAgICAgICAgc3RhcnRUYXNrLlNldFZlcnNpb24oIjEuMC4wIik7CiAgICAgICAgICAgIHN0YXJ0VGFzay5TZXRLZXkoR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSk7CiAgICAgICAgICAgIHN0YXJ0VGFzay5TZXRUYWdzKG5ld1tdIHsgInRhc2stdGVzdCIsICJzdGFydC13b3JrZmxvdyIsICJzdWNjZXNzIiB9KTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFByZXBhcmUgaW5pdGlhbGl6YXRpb24gYm9keQogICAgICAgICAgICB2YXIgaW5pdEJvZHkgPSBuZXcKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcGFyZW50SW5zdGFuY2VJZCA9IGNvbnRleHQuSW5zdGFuY2U/LklkLAogICAgICAgICAgICAgICAgcGFyZW50V29ya2Zsb3dJZCA9IGNvbnRleHQuV29ya2Zsb3c/LktleSwKICAgICAgICAgICAgICAgIHRlc3RJZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnRlc3RJZCA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpLAogICAgICAgICAgICAgICAgc3RhcnRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgc3RhcnRlZEJ5ID0gInRhc2stdGVzdC13b3JrZmxvdyIsCiAgICAgICAgICAgICAgICBtZXNzYWdlID0gIlN0YXJ0VGFzayB0ZXN0IC0gbmV3IGluc3RhbmNlIGNyZWF0ZWQiCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHN0YXJ0VGFzay5TZXRCb2R5KGluaXRCb2R5KTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gInN0YXJ0LXdvcmtmbG93LWlucHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwoKICAgICAgICAgICAgaWYgKHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPT0gdHJ1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJzdGFydC13b3JrZmxvdy1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdGFydFdvcmtmbG93UmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3SW5zdGFuY2VJZCA9IHJlc3BvbnNlPy5kYXRhPy5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IHJlc3BvbnNlPy5kYXRhPy5zdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJTdGFydCIKICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgLy8gU3RvcmUgaW5zdGFuY2UgSUQgZm9yIGxhdGVyIHVzZQogICAgICAgICAgICAgICAgICAgICAgICBzdWJmbG93SW5zdGFuY2VJZCA9IHJlc3BvbnNlPy5kYXRhPy5pZAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJzdGFydC13b3JrZmxvdyIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzdGFydC13b3JrZmxvdy1mYWlsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0YXJ0V29ya2Zsb3dSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSByZXNwb25zZT8uZXJyb3JNZXNzYWdlID8/ICJGYWlsZWQgdG8gc3RhcnQgd29ya2Zsb3ciLAogICAgICAgICAgICAgICAgICAgICAgICBmYWlsZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiU3RhcnQiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBuZXdbXSB7ICJ0YXNrLXRlc3QiLCAic3RhcnQtd29ya2Zsb3ciLCAiZmFpbGVkIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzdGFydC13b3JrZmxvdy1leGNlcHRpb24iLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0YXJ0V29ya2Zsb3dSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBleC5NZXNzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJTdGFydCIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfQp9" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "start-workflow-completed", - "target": "test-get-instance-data-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Start Completed" - }, - { - "language": "tr-TR", - "label": "Start Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-get-instance-data-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test GetInstanceData" - }, - { - "language": "tr-TR", - "label": "GetInstanceData Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "test-get-instance-data", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/GetInstanceDataMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CnVzaW5nIFN5c3RlbS5UZXh0Lkpzb247CgovLy8gPHN1bW1hcnk+Ci8vLyBHZXRJbnN0YW5jZURhdGEgVGFzayBNYXBwaW5nIC0gUmV0cmlldmVzIGRhdGEgZnJvbSBhbm90aGVyIHdvcmtmbG93IGluc3RhbmNlCi8vLyBUZXN0IGNhc2U6IFZlcmlmeSBjcm9zcy13b3JrZmxvdyBkYXRhIHJldHJpZXZhbAovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgR2V0SW5zdGFuY2VEYXRhTWFwcGluZyA6IElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciBnZXREYXRhVGFzayA9IHRhc2sgYXMgR2V0SW5zdGFuY2VEYXRhVGFzazsKICAgICAgICAgICAgaWYgKGdldERhdGFUYXNrID09IG51bGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBJbnZhbGlkT3BlcmF0aW9uRXhjZXB0aW9uKCJUYXNrIG11c3QgYmUgYSBHZXRJbnN0YW5jZURhdGFUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSB0YXJnZXQgd29ya2Zsb3cgLSBnZXQgZGF0YSBmcm9tIGN1cnJlbnQgd29ya2Zsb3cgaW5zdGFuY2UgdG8gdGVzdCBleHRlbnNpb25zCiAgICAgICAgICAgIGdldERhdGFUYXNrLlNldERvbWFpbigiY29yZSIpOwogICAgICAgICAgICBnZXREYXRhVGFzay5TZXRGbG93KCJ0YXNrLXRlc3Qtd29ya2Zsb3ciKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEdldCBkYXRhIGZyb20gY3VycmVudCBpbnN0YW5jZSB0byB2ZXJpZnkgZXh0ZW5zaW9uIGRhdGEKICAgICAgICAgICAgdmFyIGN1cnJlbnRJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQuVG9TdHJpbmcoKTsKICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShjdXJyZW50SW5zdGFuY2VJZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGdldERhdGFUYXNrLlNldEluc3RhbmNlKGN1cnJlbnRJbnN0YW5jZUlkKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gUmVxdWVzdCBzcGVjaWZpYyBleHRlbnNpb25zIC0gdGhpcyB3aWxsIHRyaWdnZXIgdGhlIHRlc3QtaHR0cC1kYXRhLWV4dGVuc2lvbgogICAgICAgICAgICBnZXREYXRhVGFzay5TZXRFeHRlbnNpb25zKG5ld1tdIHsgInRlc3QtaHR0cC1kYXRhLWV4dGVuc2lvbiIgfSk7CgogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZSgpKTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJnZXQtaW5zdGFuY2UtZGF0YS1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgICAgIGlmIChyZXNwb25zZT8uaXNTdWNjZXNzID09IHRydWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAiZ2V0LWluc3RhbmNlLWRhdGEtc3VjY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZ2V0SW5zdGFuY2VEYXRhUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0cmlldmVkRGF0YSA9IHJlc3BvbnNlPy5kYXRhPy5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRXh0ZW5zaW9uIGRhdGEgd2lsbCBiZSBoZXJlIC0gdGVzdC1odHRwLWRhdGEtZXh0ZW5zaW9uIHJlc3BvbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25EYXRhID0gcmVzcG9uc2U/LmRhdGE/LmV4dGVuc2lvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXRyaWV2ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIkdldEluc3RhbmNlRGF0YSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlID0gIkNoZWNrIGV4dGVuc2lvbkRhdGEgZmllbGQgZm9yIHRlc3QtaHR0cC1kYXRhLWV4dGVuc2lvbiByZXN1bHRzIgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgImdldC1pbnN0YW5jZS1kYXRhIiwgInN1Y2Nlc3MiLCAiZXh0ZW5zaW9uLXRlc3QiIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdldC1pbnN0YW5jZS1kYXRhLWZhaWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZ2V0SW5zdGFuY2VEYXRhUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gZmFsc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gcmVzcG9uc2U/LmVycm9yTWVzc2FnZSA/PyAiRmFpbGVkIHRvIHJldHJpZXZlIGluc3RhbmNlIGRhdGEiLAogICAgICAgICAgICAgICAgICAgICAgICBmYWlsZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiR2V0SW5zdGFuY2VEYXRhIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgImdldC1pbnN0YW5jZS1kYXRhIiwgImZhaWxlZCIgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAiZ2V0LWluc3RhbmNlLWRhdGEtZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBnZXRJbnN0YW5jZURhdGFSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBleC5NZXNzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJHZXRJbnN0YW5jZURhdGEiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "get-instance-data-completed", - "target": "test-get-instances-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "GetInstanceData Completed" - }, - { - "language": "tr-TR", - "label": "GetInstanceData Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-get-instances-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test GetInstances" - }, - { - "language": "tr-TR", - "label": "GetInstances Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "test-get-instances", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/GetInstancesMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKdXNpbmcgU3lzdGVtLlRleHQuSnNvbjsKdXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LkRlZmluaXRpb25zOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nOwp1c2luZyBCQlQuV29ya2Zsb3cuU2NyaXB0aW5nLkZ1bmN0aW9uczsKCi8vLyA8c3VtbWFyeT4KLy8vIEdldEluc3RhbmNlcyBUYXNrIE1hcHBpbmcgLSBSZXRyaWV2ZXMgYSBsaXN0IG9mIHdvcmtmbG93IGluc3RhbmNlcyB3aXRoIGZpbHRlcmluZyBhbmQgcGFnaW5hdGlvbgovLy8gVGVzdCBjYXNlOiBWZXJpZnkgR2V0SW5zdGFuY2VzVGFzayBmdW5jdGlvbmFsaXR5IGluY2x1ZGluZyBmaWx0ZXIsIHBhZ2luYXRpb24sIGFuZCBzb3J0aW5nCi8vLyAKLy8vIEZpbHRlciBGb3JtYXQgKEdyYXBoUUwtbGlrZSBKU09OIHN0cnVjdHVyZSk6Ci8vLyA/ZmlsdGVyPXsiYXR0cmlidXRlcyI6eyJmaWVsZE5hbWUiOnsib3BlcmF0b3IiOiJ2YWx1ZSJ9fX0KLy8vIAovLy8gU3VwcG9ydGVkIG9wZXJhdG9yczogZXEsIG5lcSwgZ3QsIGd0ZSwgbHQsIGx0ZSwgY29udGFpbnMsIHN0YXJ0c1dpdGgsIGVuZHNXaXRoCi8vLyAKLy8vIEV4YW1wbGVzOgovLy8gLSBTaW5nbGUgZmlsdGVyOiB7ImF0dHJpYnV0ZXMiOnsiY2xpZW50SWQiOnsiZXEiOjEyMn19fQovLy8gLSBNdWx0aXBsZSBmaWx0ZXJzOiB7ImF0dHJpYnV0ZXMiOnsiY2xpZW50SWQiOnsiZXEiOjEyMn0sInRlc3RWYWx1ZSI6eyJndCI6Mn19fQovLy8gLSBTdHJpbmcgZmlsdGVyOiB7ImF0dHJpYnV0ZXMiOnsic3RhdHVzIjp7ImVxIjoiYWN0aXZlIn19fQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgR2V0SW5zdGFuY2VzTWFwcGluZyA6IFNjcmlwdEJhc2UsIElNYXBwaW5nCnsKICAgIHB1YmxpYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBJbnB1dEhhbmRsZXIoV29ya2Zsb3dUYXNrIHRhc2ssIFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJHZXRJbnN0YW5jZXMgVGVzdCAtIFN0YXJ0aW5nIEdldEluc3RhbmNlcyB0YXNrIGNvbmZpZ3VyYXRpb24iKTsKCiAgICAgICAgICAgIHZhciBnZXRJbnN0YW5jZXNUYXNrID0gdGFzayBhcyBHZXRJbnN0YW5jZXNUYXNrOwogICAgICAgICAgICBpZiAoZ2V0SW5zdGFuY2VzVGFzayA9PSBudWxsKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSW52YWxpZE9wZXJhdGlvbkV4Y2VwdGlvbigiVGFzayBtdXN0IGJlIGEgR2V0SW5zdGFuY2VzVGFzayIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDb25maWd1cmUgdGFyZ2V0IHdvcmtmbG93IC0gcXVlcnkgaW5zdGFuY2VzIGZyb20gdGFzay10ZXN0LXN1YmZsb3cKICAgICAgICAgICAgZ2V0SW5zdGFuY2VzVGFzay5TZXREb21haW4oImNvcmUiKTsKICAgICAgICAgICAgZ2V0SW5zdGFuY2VzVGFzay5TZXRGbG93KCJ0YXNrLXRlc3Qtc3ViZmxvdyIpOwoKICAgICAgICAgICAgLy8gQ29uZmlndXJlIHBhZ2luYXRpb24KICAgICAgICAgICAgZ2V0SW5zdGFuY2VzVGFzay5TZXRQYWdlKDEpOwogICAgICAgICAgICBnZXRJbnN0YW5jZXNUYXNrLlNldFBhZ2VTaXplKDEwKTsKCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBzb3J0aW5nIC0gbmV3ZXN0IGZpcnN0CiAgICAgICAgICAgIC8vIGdldEluc3RhbmNlc1Rhc2suU2V0U29ydCgiLUNyZWF0ZWRBdCIpOwoKICAgICAgICAgICAgLy8gQnVpbGQgZmlsdGVyIGluIEdyYXBoUUwtbGlrZSBKU09OIGZvcm1hdAogICAgICAgICAgICAvLyBGb3JtYXQ6IHsiYXR0cmlidXRlcyI6eyJmaWVsZE5hbWUiOnsib3BlcmF0b3IiOiJ2YWx1ZSJ9fX0KICAgICAgICAgICAgLy8gQVBJIGNhbGwgZXhhbXBsZTogR0VUIC9hcGkvdjEuMC9jb3JlL3dvcmtmbG93cy90YXNrLXRlc3Qtc3ViZmxvdy9pbnN0YW5jZXM/ZmlsdGVyPXsiYXR0cmlidXRlcyI6eyJwYXJlbnRJbnN0YW5jZUlkIjp7ImVxIjoiYWJjLTEyMyJ9fX0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEdldCBwYXJlbnQgaW5zdGFuY2UgZGF0YSB0byBidWlsZCBtZWFuaW5nZnVsIGZpbHRlcnMKICAgICAgICAgICAgdmFyIHBhcmVudEluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlLklkLlRvU3RyaW5nKCk7CiAgICAgICAgICAgIHZhciB0ZXN0SWQgPSBjb250ZXh0Lkluc3RhbmNlLkRhdGE/LnRlc3RJZC5Ub1N0cmluZygpOwoKICAgICAgICAgICAgLy8gQnVpbGQgYXR0cmlidXRlIGZpbHRlcnMgZGljdGlvbmFyeQogICAgICAgICAgICAvLyBFYWNoIGtleSBpcyBhIGZpZWxkIG5hbWUsIGVhY2ggdmFsdWUgaXMgYSBkaWN0aW9uYXJ5IG9mIHtvcGVyYXRvcjogdmFsdWV9CiAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVGaWx0ZXJzID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0Pj4oKTsKCiAgICAgICAgICAgIC8vIEZpbHRlciAxOiBGaW5kIGluc3RhbmNlcyBieSBwYXJlbnRJbnN0YW5jZUlkIHVzaW5nICJlcSIgb3BlcmF0b3IKICAgICAgICAgICAgaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShwYXJlbnRJbnN0YW5jZUlkKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXR0cmlidXRlRmlsdGVyc1sicGFyZW50SW5zdGFuY2VJZCJdID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeyAiZXEiLCBwYXJlbnRJbnN0YW5jZUlkIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEZpbHRlciAyOiBGaW5kIGluc3RhbmNlcyBieSB0ZXN0SWQgdXNpbmcgImVxIiBvcGVyYXRvcgogICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KHRlc3RJZCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZUZpbHRlcnNbInRlc3RJZCJdID0gbmV3IERpY3Rpb25hcnk8c3RyaW5nLCBvYmplY3Q+CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeyAiZXEiLCB0ZXN0SWQgfQogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gRmlsdGVyIDM6IEZpbmQgaW5zdGFuY2VzIHN0YXJ0ZWQgYnkgdGFzay10ZXN0LXdvcmtmbG93IHVzaW5nICJlcSIgb3BlcmF0b3IKICAgICAgICAgICAgYXR0cmlidXRlRmlsdGVyc1sic3RhcnRlZEJ5Il0gPSBuZXcgRGljdGlvbmFyeTxzdHJpbmcsIG9iamVjdD4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgeyAiZXEiLCAidGFzay10ZXN0LXdvcmtmbG93IiB9CiAgICAgICAgICAgIH07CgogICAgICAgICAgICAvLyBCdWlsZCB0aGUgY29tcGxldGUgZmlsdGVyIEpTT04gb2JqZWN0CiAgICAgICAgICAgIC8vIFJlc3VsdCBmb3JtYXQ6IHsiYXR0cmlidXRlcyI6eyJwYXJlbnRJbnN0YW5jZUlkIjp7ImVxIjoiLi4uIn0sInRlc3RJZCI6eyJlcSI6Ii4uLiJ9LCJzdGFydGVkQnkiOnsiZXEiOiJ0YXNrLXRlc3Qtd29ya2Zsb3cifX19CiAgICAgICAgICAgIGlmIChhdHRyaWJ1dGVGaWx0ZXJzLkNvdW50ID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdmFyIGZpbHRlck9iamVjdCA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgb2JqZWN0PgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHsgImF0dHJpYnV0ZXMiLCBhdHRyaWJ1dGVGaWx0ZXJzIH0KICAgICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgICAgLy8gU2VyaWFsaXplIHRvIEpTT04gc3RyaW5nCiAgICAgICAgICAgICAgICB2YXIgZmlsdGVySnNvbiA9IEpzb25TZXJpYWxpemVyLlNlcmlhbGl6ZShmaWx0ZXJPYmplY3QpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBTZXRGaWx0ZXIgZXhwZWN0cyBhIHN0cmluZyBhcnJheSAtIHBhc3MgdGhlIGNvbXBsZXRlIGZpbHRlciBhcyBzaW5nbGUgZWxlbWVudAogICAgICAgICAgICAgICAgZ2V0SW5zdGFuY2VzVGFzay5TZXRGaWx0ZXIoW2ZpbHRlckpzb25dKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgTG9nSW5mb3JtYXRpb24oIkdldEluc3RhbmNlcyBUZXN0IC0gQXBwbGllZCBKU09OIGZpbHRlcjogezB9IiwgCiAgICAgICAgICAgICAgICAgICAgYXJnczogW2ZpbHRlckpzb25dKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJHZXRJbnN0YW5jZXMgVGVzdCAtIE5vIGZpbHRlcnMgYXBwbGllZCwgcmV0cmlldmluZyBhbGwgaW5zdGFuY2VzIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgTG9nRXJyb3IoIkdldEluc3RhbmNlcyBUZXN0IC0gRmFpbGVkIHRvIGNvbmZpZ3VyZSBHZXRJbnN0YW5jZXMgdGFzazogezB9IiwgCiAgICAgICAgICAgICAgICBhcmdzOiBbZXguTWVzc2FnZV0pOwogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdldC1pbnN0YW5jZXMtaW5wdXQtZXJyb3IiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldyB7IGVycm9yID0gZXguTWVzc2FnZSB9CiAgICAgICAgICAgIH0pOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYXN5bmMgVGFzazxTY3JpcHRSZXNwb25zZT4gT3V0cHV0SGFuZGxlcihTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICBMb2dJbmZvcm1hdGlvbigiR2V0SW5zdGFuY2VzIFRlc3QgLSBQcm9jZXNzaW5nIEdldEluc3RhbmNlcyByZXNwb25zZSIpOwoKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwogICAgICAgICAgICB2YXIgaXNTdWNjZXNzID0gcmVzcG9uc2U/LmlzU3VjY2VzcyA9PSB0cnVlOwogICAgICAgICAgICB2YXIgc3RhdHVzQ29kZSA9IHJlc3BvbnNlPy5zdGF0dXNDb2RlID8/IDUwMDsKCiAgICAgICAgICAgIGlmIChpc1N1Y2Nlc3MpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgcmVzcG9uc2UgZGF0YQogICAgICAgICAgICAgICAgdmFyIGluc3RhbmNlcyA9IHJlc3BvbnNlPy5kYXRhLml0ZW1zOwoKICAgICAgICAgICAgICAgIExvZ0luZm9ybWF0aW9uKCJHZXRJbnN0YW5jZXMgVGVzdCAtIFN1Y2Nlc3NmdWxseSByZXRyaWV2ZWQgezB9IGluc3RhbmNlKHMpIiwgCiAgICAgICAgICAgICAgICAgICAgYXJnczogbmV3IG9iamVjdD9bXSB7IGluc3RhbmNlcz8uQ291bnQgPz8gMCB9KTsKCiAgICAgICAgICAgICAgICAvLyBCdWlsZCBpbnN0YW5jZSBzdW1tYXJ5IGZvciB2ZXJpZmljYXRpb24KICAgICAgICAgICAgICAgIHZhciBpbnN0YW5jZVN1bW1hcnkgPSBuZXcgTGlzdDxvYmplY3Q+KCk7CiAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VzICE9IG51bGwpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yZWFjaCAodmFyIGluc3RhbmNlIGluIGluc3RhbmNlcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlU3VtbWFyeS5BZGQobmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlc3RJZCA9IGluc3RhbmNlPy5kYXRhPy50ZXN0SWQKICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAiZ2V0LWluc3RhbmNlcy1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBnZXRJbnN0YW5jZXNSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IHRydWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJHZXRJbnN0YW5jZXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb24gPSAiUmV0cmlldmVkIHdvcmtmbG93IGluc3RhbmNlcyB3aXRoIEpTT04gZmlsdGVyLCBwYWdpbmF0aW9uLCBhbmQgc29ydGluZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIgPSBuZXcKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcHBsaWVkID0gdHJ1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQgPSAiR3JhcGhRTC1saWtlIEpTT04iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldERvbWFpbiA9ICJjb3JlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRGbG93ID0gInRhc2stdGVzdC1zdWJmbG93IgogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlcyA9IGluc3RhbmNlU3VtbWFyeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlQ291bnQgPSBpbnN0YW5jZXM/LkNvdW50ID8/IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXRyaWV2ZWRBdCA9IERhdGVUaW1lLlV0Y05vdwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICAgICBUYWdzID0gWyJ0YXNrLXRlc3QiLCAiZ2V0LWluc3RhbmNlcyIsICJmaWx0ZXItdGVzdCIsICJqc29uLWZpbHRlciIsICJzdWNjZXNzIl0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEhhbmRsZSBmYWlsdXJlCiAgICAgICAgICAgIExvZ1dhcm5pbmcoIkdldEluc3RhbmNlcyBUZXN0IC0gRmFpbGVkIHRvIHJldHJpZXZlIGluc3RhbmNlczogezB9IiwgCiAgICAgICAgICAgICAgICBhcmdzOiBbcmVzcG9uc2U/LmVycm9yTWVzc2FnZSA/PyAiVW5rbm93biBlcnJvciJdKTsKCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdldC1pbnN0YW5jZXMtZmFpbGVkIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBnZXRJbnN0YW5jZXNSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiR2V0SW5zdGFuY2VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yID0gcmVzcG9uc2U/LmVycm9yTWVzc2FnZSA/PyAiRmFpbGVkIHRvIHJldHJpZXZlIGluc3RhbmNlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZhaWxlZEF0ID0gRGF0ZVRpbWUuVXRjTm93CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIFRhZ3MgPSBbInRhc2stdGVzdCIsICJnZXQtaW5zdGFuY2VzIiwgImZhaWxlZCJdCiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICBMb2dFcnJvcigiR2V0SW5zdGFuY2VzIFRlc3QgLSBPdXRwdXQgaGFuZGxlciBleGNlcHRpb246IHswfSIsIAogICAgICAgICAgICAgICAgYXJnczogW2V4Lk1lc3NhZ2VdKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImdldC1pbnN0YW5jZXMtZXhjZXB0aW9uIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBnZXRJbnN0YW5jZXNSZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiR2V0SW5zdGFuY2VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBleC5NZXNzYWdlCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQo=" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "get-instances-completed", - "target": "test-direct-transition-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "GetInstances Completed" - }, - { - "language": "tr-TR", - "label": "GetInstances Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-direct-transition-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test DirectTransition" - }, - { - "language": "tr-TR", - "label": "DirectTransition Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "test-direct-transition", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/DirectTransitionMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBEaXJlY3RUcmFuc2l0aW9uIFRhc2sgTWFwcGluZyAtIFRyaWdnZXJzIHRyYW5zaXRpb24gb24gZXhpc3Rpbmcgd29ya2Zsb3cgaW5zdGFuY2UKLy8vIFRlc3QgY2FzZTogVmVyaWZ5IHdvcmtmbG93LXRvLXdvcmtmbG93IHRyYW5zaXRpb24gdHJpZ2dlcmluZwovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgRGlyZWN0VHJhbnNpdGlvbk1hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgZGlyZWN0VHJpZ2dlclRhc2sgPSB0YXNrIGFzIERpcmVjdFRyaWdnZXJUYXNrOwogICAgICAgICAgICBpZiAoZGlyZWN0VHJpZ2dlclRhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIERpcmVjdFRyaWdnZXJUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSB0YXJnZXQgd29ya2Zsb3cKICAgICAgICAgICAgZGlyZWN0VHJpZ2dlclRhc2suU2V0RG9tYWluKCJjb3JlIik7CiAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldEZsb3coInRhc2stdGVzdC1zdWJmbG93Iik7CiAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldFRyYW5zaXRpb25OYW1lKCJjb21wbGV0ZS1zdWJmbG93Iik7CiAgICAgICAgICAgIGRpcmVjdFRyaWdnZXJUYXNrLlNldFRhZ3MobmV3W10geyAidGFzay10ZXN0IiwgImRpcmVjdC10cmFuc2l0aW9uIiwgInN1Y2Nlc3MiIH0pOwogICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXRTeW5jKHRydWUpOwoKICAgICAgICAgICAgLy8gR2V0IGluc3RhbmNlIElEIGZyb20gd29ya2Zsb3cgZGF0YQogICAgICAgICAgICB2YXIgdGFyZ2V0SW5zdGFuY2VJZCA9IGNvbnRleHQuSW5zdGFuY2U/LkRhdGE/LnN1YmZsb3dJbnN0YW5jZUlkPy5Ub1N0cmluZygpOwogICAgICAgICAgICBpZiAoIXN0cmluZy5Jc051bGxPckVtcHR5KHRhcmdldEluc3RhbmNlSWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXRJbnN0YW5jZSh0YXJnZXRJbnN0YW5jZUlkKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXRLZXkoY29udGV4dC5JbnN0YW5jZT8uS2V5ID8/IEd1aWQuTmV3R3VpZCgpLlRvU3RyaW5nKCkpOwoKICAgICAgICAgICAgLy8gUHJlcGFyZSB0cmFuc2l0aW9uIGJvZHkKICAgICAgICAgICAgdmFyIHRyYW5zaXRpb25Cb2R5ID0gbmV3CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbXBsZXRlZEJ5ID0gInRhc2stdGVzdC13b3JrZmxvdyIsCiAgICAgICAgICAgICAgICBjb21wbGV0ZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgIHBhcmVudEluc3RhbmNlSWQgPSBjb250ZXh0Lkluc3RhbmNlPy5JZCwKICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSAiRGlyZWN0VHJhbnNpdGlvbiB0ZXN0IGV4ZWN1dGVkIgogICAgICAgICAgICB9OwogICAgICAgICAgICBkaXJlY3RUcmlnZ2VyVGFzay5TZXRCb2R5KHRyYW5zaXRpb25Cb2R5KTsKCiAgICAgICAgICAgIHJldHVybiBUYXNrLkZyb21SZXN1bHQobmV3IFNjcmlwdFJlc3BvbnNlKCkpOwogICAgICAgIH0KICAgICAgICBjYXRjaCAoRXhjZXB0aW9uIGV4KQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRpcmVjdC10cmFuc2l0aW9uLWlucHV0LWVycm9yIiwKICAgICAgICAgICAgICAgIERhdGEgPSBuZXcgeyBlcnJvciA9IGV4Lk1lc3NhZ2UgfQogICAgICAgICAgICB9KTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGFzeW5jIFRhc2s8U2NyaXB0UmVzcG9uc2U+IE91dHB1dEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHRyeQogICAgICAgIHsKICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gY29udGV4dC5Cb2R5OwoKICAgICAgICAgICAgaWYgKHJlc3BvbnNlPy5pc1N1Y2Nlc3MgPT0gdHJ1ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSA9ICJkaXJlY3QtdHJhbnNpdGlvbi1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RUcmFuc2l0aW9uUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VJZCA9IHJlc3BvbnNlPy5kYXRhPy5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IHJlc3BvbnNlPy5kYXRhPy5zdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGVjdXRlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiRGlyZWN0VHJhbnNpdGlvbiIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJkaXJlY3QtdHJhbnNpdGlvbiIsICJzdWNjZXNzIiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJkaXJlY3QtdHJhbnNpdGlvbi1mYWlsZWQiLAogICAgICAgICAgICAgICAgRGF0YSA9IG5ldwogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRpcmVjdFRyYW5zaXRpb25SZXN1bHQgPSBuZXcKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSByZXNwb25zZT8uZXJyb3JNZXNzYWdlID8/ICJEaXJlY3QgdHJhbnNpdGlvbiBmYWlsZWQiLAogICAgICAgICAgICAgICAgICAgICAgICBmYWlsZWRBdCA9IERhdGVUaW1lLlV0Y05vdywKICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiRGlyZWN0VHJhbnNpdGlvbiIKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJkaXJlY3QtdHJhbnNpdGlvbiIsICJmYWlsZWQiIH0KICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICAgY2F0Y2ggKEV4Y2VwdGlvbiBleCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0gImRpcmVjdC10cmFuc2l0aW9uLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGlyZWN0VHJhbnNpdGlvblJlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIkRpcmVjdFRyYW5zaXRpb24iCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "direct-transition-completed", - "target": "test-subprocess-state", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "DirectTransition Completed" - }, - { - "language": "tr-TR", - "label": "DirectTransition Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "test-subprocess-state", - "stateType": 2, - "subType": 0, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "Test SubProcess" - }, - { - "language": "tr-TR", - "label": "SubProcess Testi" - } - ], - "view": null, - "subFlow": null, - "onEntries": [ - { - "order": 1, - "task": { - "key": "test-subprocess", - "domain": "core", - "version": "1.0.0", - "flow": "sys-tasks" - }, - "mapping": { - "location": "./src/SubProcessMapping.csx", - "code": "dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nLlRhc2tzOwp1c2luZyBCQlQuV29ya2Zsb3cuRGVmaW5pdGlvbnM7CnVzaW5nIEJCVC5Xb3JrZmxvdy5TY3JpcHRpbmc7CgovLy8gPHN1bW1hcnk+Ci8vLyBTdWJQcm9jZXNzIFRhc2sgTWFwcGluZyAtIFN0YXJ0cyBhIGZpcmUtYW5kLWZvcmdldCBzdWJwcm9jZXNzCi8vLyBUZXN0IGNhc2U6IFZlcmlmeSBzdWJwcm9jZXNzIGxhdW5jaGluZyAobm9uLWJsb2NraW5nKQovLy8gPC9zdW1tYXJ5PgpwdWJsaWMgY2xhc3MgU3ViUHJvY2Vzc01hcHBpbmcgOiBJTWFwcGluZwp7CiAgICBwdWJsaWMgVGFzazxTY3JpcHRSZXNwb25zZT4gSW5wdXRIYW5kbGVyKFdvcmtmbG93VGFzayB0YXNrLCBTY3JpcHRDb250ZXh0IGNvbnRleHQpCiAgICB7CiAgICAgICAgdHJ5CiAgICAgICAgewogICAgICAgICAgICB2YXIgc3ViUHJvY2Vzc1Rhc2sgPSB0YXNrIGFzIFN1YlByb2Nlc3NUYXNrOwogICAgICAgICAgICBpZiAoc3ViUHJvY2Vzc1Rhc2sgPT0gbnVsbCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludmFsaWRPcGVyYXRpb25FeGNlcHRpb24oIlRhc2sgbXVzdCBiZSBhIFN1YlByb2Nlc3NUYXNrIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBzdWJwcm9jZXNzCiAgICAgICAgICAgIC8vc3ViUHJvY2Vzc1Rhc2suU2V0RG9tYWluKCJjb3JlIik7CiAgICAgICAgICAgIC8vc3ViUHJvY2Vzc1Rhc2suU2V0RmxvdygidGFzay10ZXN0LXN1YmZsb3ciKTsKICAgICAgICAgICAgc3ViUHJvY2Vzc1Rhc2suU2V0S2V5KGNvbnRleHQuSW5zdGFuY2U/LktleSA/PyBHdWlkLk5ld0d1aWQoKS5Ub1N0cmluZygpKTsKICAgICAgICAgICAgc3ViUHJvY2Vzc1Rhc2suU2V0VGFncyhuZXdbXSB7ICJ0YXNrLXRlc3QiLCAic3VicHJvY2VzcyIsICJzdWNjZXNzIiB9KTsKCiAgICAgICAgICAgIC8vIFByZXBhcmUgc3VicHJvY2VzcyBkYXRhCiAgICAgICAgICAgIHZhciBzdWJQcm9jZXNzQm9keSA9IG5ldwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwYXJlbnRJbnN0YW5jZUlkID0gY29udGV4dC5JbnN0YW5jZT8uSWQsCiAgICAgICAgICAgICAgICBwYXJlbnRXb3JrZmxvd0lkID0gY29udGV4dC5Xb3JrZmxvdy5LZXksCiAgICAgICAgICAgICAgICB0ZXN0SWQgPSBjb250ZXh0Lkluc3RhbmNlPy5EYXRhPy50ZXN0SWQgPz8gR3VpZC5OZXdHdWlkKCkuVG9TdHJpbmcoKSwKICAgICAgICAgICAgICAgIGxhdW5jaGVkQXQgPSBEYXRlVGltZS5VdGNOb3csCiAgICAgICAgICAgICAgICBsYXVuY2hlZEJ5ID0gInRhc2stdGVzdC13b3JrZmxvdyIsCiAgICAgICAgICAgICAgICBpc0ZpcmVBbmRGb3JnZXQgPSB0cnVlLAogICAgICAgICAgICAgICAgbWVzc2FnZSA9ICJTdWJQcm9jZXNzIHRlc3QgLSBmaXJlLWFuZC1mb3JnZXQgaW5zdGFuY2UiCiAgICAgICAgICAgIH07CiAgICAgICAgICAgIHN1YlByb2Nlc3NUYXNrLlNldEJvZHkoc3ViUHJvY2Vzc0JvZHkpOwoKICAgICAgICAgICAgcmV0dXJuIFRhc2suRnJvbVJlc3VsdChuZXcgU2NyaXB0UmVzcG9uc2UoKSk7CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gVGFzay5Gcm9tUmVzdWx0KG5ldyBTY3JpcHRSZXNwb25zZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPSAic3VicHJvY2Vzcy1pbnB1dC1lcnJvciIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3IHsgZXJyb3IgPSBleC5NZXNzYWdlIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBhc3luYyBUYXNrPFNjcmlwdFJlc3BvbnNlPiBPdXRwdXRIYW5kbGVyKFNjcmlwdENvbnRleHQgY29udGV4dCkKICAgIHsKICAgICAgICB0cnkKICAgICAgICB7CiAgICAgICAgICAgIHZhciByZXNwb25zZSA9IGNvbnRleHQuQm9keTsKCiAgICAgICAgICAgIGlmIChyZXNwb25zZT8uaXNTdWNjZXNzID09IHRydWUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgU2NyaXB0UmVzcG9uc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBLZXkgPSAic3VicHJvY2Vzcy1zdWNjZXNzIiwKICAgICAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBzdWJQcm9jZXNzUmVzdWx0ID0gbmV3CiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViUHJvY2Vzc0luc3RhbmNlSWQgPSByZXNwb25zZT8uZGF0YT8uaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXVuY2hlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFza1R5cGUgPSAiU3ViUHJvY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3RlID0gIkZpcmUtYW5kLWZvcmdldDogUGFyZW50IHdvcmtmbG93IGRvZXMgbm90IHdhaXQgZm9yIHN1YnByb2Nlc3MgY29tcGxldGlvbiIKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgVGFncyA9IG5ld1tdIHsgInRhc2stdGVzdCIsICJzdWJwcm9jZXNzIiwgInN1Y2Nlc3MiLCAiZmlyZS1hbmQtZm9yZ2V0IiB9CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzdWJwcm9jZXNzLWZhaWxlZCIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3ViUHJvY2Vzc1Jlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IHJlc3BvbnNlPy5lcnJvck1lc3NhZ2UgPz8gIkZhaWxlZCB0byBsYXVuY2ggc3VicHJvY2VzcyIsCiAgICAgICAgICAgICAgICAgICAgICAgIGZhaWxlZEF0ID0gRGF0ZVRpbWUuVXRjTm93LAogICAgICAgICAgICAgICAgICAgICAgICB0YXNrVHlwZSA9ICJTdWJQcm9jZXNzIgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBUYWdzID0gbmV3W10geyAidGFzay10ZXN0IiwgInN1YnByb2Nlc3MiLCAiZmFpbGVkIiB9CiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgICAgIGNhdGNoIChFeGNlcHRpb24gZXgpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gbmV3IFNjcmlwdFJlc3BvbnNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9ICJzdWJwcm9jZXNzLWV4Y2VwdGlvbiIsCiAgICAgICAgICAgICAgICBEYXRhID0gbmV3CiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3ViUHJvY2Vzc1Jlc3VsdCA9IG5ldwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzcyA9IGZhbHNlLAogICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IGV4Lk1lc3NhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2tUeXBlID0gIlN1YlByb2Nlc3MiCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KfQoK" - } - } - ], - "onExits": [], - "transitions": [ - { - "key": "subprocess-completed", - "target": "all-tests-completed", - "triggerType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "SubProcess Completed" - }, - { - "language": "tr-TR", - "label": "SubProcess Tamamlandı" - } - ], - "schema": null, - "rule": { - "location": "./src/AlwaysTrueRule.csx", - "code": "dXNpbmcgU3lzdGVtLlRocmVhZGluZy5UYXNrczsKdXNpbmcgQkJULldvcmtmbG93LlNjcmlwdGluZzsKCi8vLyA8c3VtbWFyeT4KLy8vIEFsd2F5cyBUcnVlIFJ1bGUgLSBVc2VkIGZvciBhdXRvIHRyYW5zaXRpb25zIHRoYXQgc2hvdWxkIGFsd2F5cyBwcm9jZWVkCi8vLyA8L3N1bW1hcnk+CnB1YmxpYyBjbGFzcyBBbHdheXNUcnVlUnVsZSA6IElDb25kaXRpb25NYXBwaW5nCnsKICAgIHB1YmxpYyBhc3luYyBUYXNrPGJvb2w+IEhhbmRsZXIoU2NyaXB0Q29udGV4dCBjb250ZXh0KQogICAgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQp9Cgo=" - }, - "timer": null, - "view": null, - "onExecutionTasks": [] - } - ] - }, - { - "key": "all-tests-completed", - "stateType": 3, - "subType": 1, - "versionStrategy": "Minor", - "labels": [ - { - "language": "en-US", - "label": "All Tests Completed" - }, - { - "language": "tr-TR", - "label": "Tüm Testler Tamamlandı" - } - ], - "view": null, - "subFlow": null, - "onEntries": [], - "onExits": [], - "transitions": [] - } - ] - } -} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..bd263a3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,39 @@ +networks: + bbt-development: + external: true + +services: + mocklab: + image: ghcr.io/burgan-tech/mocklab:latest + container_name: mocklab + ports: + - "3001:5000" + environment: + Mocklab__SeedDirectory: /app/seed + volumes: + - ./etc/docker/config/seed:/app/seed + networks: + - bbt-development + + mocklab-dapr: + image: daprio/daprd:latest + container_name: mocklab-dapr + command: + - ./daprd + - --app-id + - mocklab + - --app-port + - "5000" + - --dapr-http-port + - "3500" + - --dapr-grpc-port + - "50001" + - --config + - /etc/dapr/config.yaml + - --log-level + - info + volumes: + - ./etc/dapr:/etc/dapr + network_mode: "service:mocklab" + depends_on: + - mocklab diff --git a/etc/dapr/config.yaml b/etc/dapr/config.yaml new file mode 100644 index 0000000..1d0bf5d --- /dev/null +++ b/etc/dapr/config.yaml @@ -0,0 +1,7 @@ +apiVersion: dapr.io/v1alpha1 +kind: Configuration +metadata: + name: mocklab-config +spec: + mtls: + enabled: false diff --git a/etc/docker/config/seed/.gitkeep b/etc/docker/config/seed/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/etc/docker/config/seed/account-opening-collection.json b/etc/docker/config/seed/account-opening-collection.json new file mode 100644 index 0000000..1d42dbf --- /dev/null +++ b/etc/docker/config/seed/account-opening-collection.json @@ -0,0 +1,74 @@ +{ + "collection": { + "name": "account-opening", + "description": null, + "color": "#6366f1" + }, + "folders": [], + "mocks": [ + { + "httpMethod": "POST", + "route": "api/banking/policies/validate-account-opening", + "queryString": null, + "requestBody": "", + "statusCode": 200, + "responseBody": "{\n \"validationId\": \"{{helpers.guid()}}\",\n \"complianceChecks\": {\n \"kycCompliant\": true,\n \"amlCompliant\": true,\n \"sanctionsCheck\": true,\n \"riskAssessment\": \"low\"\n },\n \"accountLimits\": {\n \"dailyTransactionLimit\": 50000,\n \"monthlyTransactionLimit\": 500000,\n \"minimumBalance\": 0,\n \"maximumBalance\": 1000000\n },\n \"additionalRequirements\": [],\n \"approvedBy\": \"system\",\n \"approvalLevel\": \"automated\",\n \"policyVersion\": \"1.0.0\",\n \"validationScore\": {{ helpers.rand_int(85, 100) }}\n}", + "contentType": "application/json", + "description": "Validates account opening against bank policies", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [ + { + "conditionField": "body.currency", + "conditionOperator": "regex", + "conditionValue": "SLV|GRS", + "statusCode": 403, + "responseBody": "{\n \"validationId\": \"{{helpers.guid()}}\",\n \"error\": {\n \"message\": \"Policy validation failed\",\n \"code\": \"policy_violation\",\n \"description\": \"Account opening request does not meet policy requirements\"\n },\n \"failedChecks\": [\n \"risk_assessment\"\n ],\n \"recommendations\": [\n \"Please review your account information\",\n \"Contact customer support for assistance\"\n ],\n \"canRetry\": true,\n \"retryAfter\": 300\n}", + "contentType": "application/json", + "priority": 0, + "responseHeaders": [] + } + ], + "sequenceItems": [] + }, + { + "httpMethod": "POST", + "route": "api/banking/accounts/create", + "queryString": null, + "requestBody": "", + "statusCode": 200, + "responseBody": "", + "contentType": "application/json", + "description": "Creates a new bank account in core banking system", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [ + { + "conditionField": "body.accountName", + "conditionOperator": "regex", + "conditionValue": ".+", + "statusCode": 201, + "responseBody": "{\n \"accountId\": \"{{helpers.guid()}}\",\n \"accountNumber\": \"{{random_account_number}}\",\n \"iban\": \"TR{{random_number_string 24}}\",\n \"accountType\": \"demand-deposit\",\n \"currency\": \"{{request.json.currency}}\",\n \"branchCode\": \"{{request.body.branchCode}}\",\n \"status\": \"active\",\n \"isActive\": true,\n \"currentBalance\": {{request.body.initialDeposit}},\n \"availableBalance\": {{request.body.initialDeposit}},\n \"limits\": {\n \"dailyTransactionLimit\": 50000,\n \"monthlyTransactionLimit\": 500000,\n \"minimumBalance\": 0,\n \"maximumBalance\": 1000000\n },\n \"debitCardRequested\": false,\n \"onlineBankingEnabled\": true,\n \"mobileBankingEnabled\": true,\n \"creationReference\": \"{{helpers.guid()}}\",\n \"coreBankingId\": \"CB{{random_number_string 10}}\",\n \"services\": [\n \"online-banking\",\n \"mobile-banking\",\n \"sms-banking\"\n ]\n}", + "contentType": "application/json", + "priority": 0, + "responseHeaders": [] + }, + { + "conditionField": "body.accountName", + "conditionOperator": "notExists", + "conditionValue": "", + "statusCode": 400, + "responseBody": "{\n \"error\": {\n \"message\": \"Account creation failed\",\n \"code\": \"validation_error\",\n \"description\": \"Account data validation failed\"\n },\n \"failureReason\": \"invalid_account_name\",\n \"failureCategory\": \"validation_error\",\n \"canRetry\": true,\n \"retryAfter\": 300,\n \"maxRetries\": 3,\n \"recommendations\": [\n \"Please check your account information and try again\",\n \"Account name must be between 1-50 characters\"\n ],\n \"supportReference\": \"{{helpers.guid()}}\"\n}", + "contentType": "application/json", + "priority": 1, + "responseHeaders": [] + } + ], + "sequenceItems": [] + } + ] +} \ No newline at end of file diff --git a/etc/docker/config/seed/payments-collection.json b/etc/docker/config/seed/payments-collection.json new file mode 100644 index 0000000..bb5cefe --- /dev/null +++ b/etc/docker/config/seed/payments-collection.json @@ -0,0 +1,259 @@ +{ + "collection": { + "name": "payments", + "description": null, + "color": "#a855f7" + }, + "folders": [], + "mocks": [ + { + "httpMethod": "POST", + "route": "/api/payments/schedules", + "queryString": null, + "requestBody": null, + "statusCode": 200, + "responseBody": "", + "contentType": "application/json", + "description": "Save Payment Configuration", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [ + { + "conditionField": "body.userId", + "conditionOperator": "exists", + "conditionValue": "", + "statusCode": 201, + "responseBody": "{\n \"success\": true,\n \"scheduleId\": \"{{helpers.guid()}}\",\n \"userId\": \"{{body.userId}}\",\n \"amount\": {{body.amount}},\n \"currency\": \"{{body.currency}}\",\n \"frequency\": \"{{body.frequency}}\",\n \"startDate\": \"{{body.startDate}}\",\n \"endDate\": \"{{body.endDate}}\",\n \"paymentMethodId\": \"{{body.paymentMethodId}}\",\n \"description\": \"{{body.description}}\",\n \"recipientId\": \"{{body.recipientId}}\",\n \"isAutoRetry\": {{body.isAutoRetry}},\n \"maxRetries\": {{body.maxRetries}},\n \"status\": \"inactive\",\n \"nextPaymentDate\": \"{{date_time_add_fmt (now) 1 'days' 'yyyy-MM-dd HH:mm'}}\",\n \"createdAt\": \"{{now}}\",\n \"maxPayments\": 4\n}", + "contentType": "application/json", + "priority": 0, + "responseHeaders": [] + }, + { + "conditionField": "body.userId", + "conditionOperator": "notExists", + "conditionValue": "", + "statusCode": 400, + "responseBody": "{\n \"success\": false,\n \"error\": \"Invalid payment configuration\",\n \"errorCode\": \"invalid_payment_config\",\n \"details\": \"Missing or invalid parameters\"\n}", + "contentType": "application/json", + "priority": 1, + "responseHeaders": [] + } + ], + "sequenceItems": [] + }, + { + "httpMethod": "POST", + "route": "/api/payments/process", + "queryString": null, + "requestBody": null, + "statusCode": 200, + "responseBody": "", + "contentType": "application/json", + "description": "Process Payment ", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [ + { + "conditionField": "body.amount", + "conditionOperator": "greaterThan", + "conditionValue": "0", + "statusCode": 200, + "responseBody": "{\n \"success\": true,\n \"transactionId\": \"txn_{{helpers.guid()}}\",\n \"scheduleId\": \"{{request.body.scheduleId}}\",\n \"amount\": {{request.body.amount}},\n \"currency\": \"{{request.body.currency}}\",\n \"paymentMethod\": \"card\",\n \"processedAt\": \"{{now}}\",\n \"fees\": {\n \"amount\": {{faker 'number.float' 0.5 5.0 2}},\n \"currency\": \"{{request.body.currency}}\"\n },\n \"status\": \"completed\"\n}", + "contentType": "application/json", + "priority": 0, + "responseHeaders": [] + }, + { + "conditionField": "body.amount", + "conditionOperator": "equals", + "conditionValue": "1000", + "statusCode": 402, + "responseBody": "{\n \"success\": false,\n \"error\": \"Insufficient balance\",\n \"errorCode\": \"insufficient_funds\",\n \"amount\": {{request.body.amount}},\n \"availableBalance\": {{faker 'number.float' 0 100 2}}\n}", + "contentType": "application/json", + "priority": 1, + "responseHeaders": [] + } + ], + "sequenceItems": [] + }, + { + "httpMethod": "PATCH", + "route": "/api/payments/schedules/{scheduleId}/activate", + "queryString": null, + "requestBody": null, + "statusCode": 200, + "responseBody": "", + "contentType": "application/json", + "description": "Activate Payment Schedule", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [ + { + "conditionField": "route.scheduleId", + "conditionOperator": "exists", + "conditionValue": "", + "statusCode": 200, + "responseBody": "{\n \"success\": true,\n \"scheduleId\": \"{{request.route.scheduleId}}\",\n \"status\": \"active\",\n \"activatedAt\": \"{{now}}\",\n \"nextPaymentDate\": \"{{date_time_add_fmt (now) 1 'months' 'yyyy-MM-dd HH:mm'}}\",\n \"isActive\": true\n}", + "contentType": "application/json", + "priority": 0, + "responseHeaders": [] + }, + { + "conditionField": "route.scheduleId", + "conditionOperator": "notExists", + "conditionValue": "", + "statusCode": 404, + "responseBody": "{\n \"success\": false,\n \"error\": \"Payment plan not found.\",\n \"errorCode\": \"schedule_not_found\",\n \"scheduleId\": \"{{request.route.scheduleId}}\"\n}", + "contentType": "application/json", + "priority": 1, + "responseHeaders": [] + } + ], + "sequenceItems": [] + }, + { + "httpMethod": "PATCH", + "route": "/api/payments/schedules/{scheduleId}/deactivate", + "queryString": null, + "requestBody": null, + "statusCode": 200, + "responseBody": "{\n \"success\": true,\n \"scheduleId\": \"{{request.route.scheduleId}}\",\n \"status\": \"deactive\",\n \"deactivatedAt\": \"{{now}}\",\n \"reason\": \"{{body 'reason'}}\",\n \"isActive\": false\n}", + "contentType": "application/json", + "description": "Deactivate Payment Schedule", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [], + "sequenceItems": [] + }, + { + "httpMethod": "POST", + "route": "/api/payments/schedules/{scheduleId}/archive", + "queryString": null, + "requestBody": null, + "statusCode": 200, + "responseBody": "{\n \"success\": true,\n \"scheduleId\": \"{{request.route.scheduleId}}\",\n \"status\": \"archived\",\n \"archivedAt\": \"{{now}}\",\n \"completionReason\": \"{{request.body.completionReason}}\",\n \"finalPaymentCount\": {{request.body.finalPaymentCount}}\n}", + "contentType": "application/json", + "description": "Archive Payment Record", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [], + "sequenceItems": [] + }, + { + "httpMethod": "PATCH", + "route": "/api/payments/schedules/{scheduleId}/retry", + "queryString": null, + "requestBody": "", + "statusCode": 200, + "responseBody": "{\n \"success\": true,\n \"scheduleId\": \"{{request.route.scheduleId}}\",\n \"retryCount\": {{request.body.retryCount}},\n \"retryAt\": \"{{request.body.retryAt}}\",\n \"maxRetries\": 3,\n \"retriesRemaining\": {{subtract 3 (body 'retryCount'))}}\n}", + "contentType": "application/json", + "description": "Increment Retry Counter", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [], + "sequenceItems": [] + }, + { + "httpMethod": "POST", + "route": "/api/payments/notify/sms", + "queryString": null, + "requestBody": null, + "statusCode": 200, + "responseBody": "", + "contentType": "application/json", + "description": "Send Payment Notification Sms", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [ + { + "conditionField": "body.userId", + "conditionOperator": "exists", + "conditionValue": "", + "statusCode": 201, + "responseBody": "{\n \"success\": true,\n \"sendedAt\": \"{{now}}\"\n}", + "contentType": "application/json", + "priority": 0, + "responseHeaders": [] + }, + { + "conditionField": "body.userId", + "conditionOperator": "notExists", + "conditionValue": "", + "statusCode": 400, + "responseBody": "{\n \"success\": false,\n \"error\": \"Invalid payment configuration\",\n \"errorCode\": \"invalid_payment_config\",\n \"details\": \"Missing or invalid parameters\"\n}", + "contentType": "application/json", + "priority": 1, + "responseHeaders": [] + } + ], + "sequenceItems": [] + }, + { + "httpMethod": "POST", + "route": "/api/payments/notify/push", + "queryString": null, + "requestBody": null, + "statusCode": 200, + "responseBody": "", + "contentType": "application/json", + "description": "Send Payment Notification Push", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [ + { + "conditionField": "body.userId", + "conditionOperator": "exists", + "conditionValue": "", + "statusCode": 201, + "responseBody": "{\n \"success\": true,\n \"sendedAt\": \"{{now}}\"\n}", + "contentType": "application/json", + "priority": 0, + "responseHeaders": [] + }, + { + "conditionField": "body.userId", + "conditionOperator": "notExists", + "conditionValue": "", + "statusCode": 400, + "responseBody": "{\n \"success\": false,\n \"error\": \"Invalid payment configuration\",\n \"errorCode\": \"invalid_payment_config\",\n \"details\": \"Missing or invalid parameters\"\n}", + "contentType": "application/json", + "priority": 1, + "responseHeaders": [] + } + ], + "sequenceItems": [] + }, + { + "httpMethod": "GET", + "route": "/api/payments/users/{userId}", + "queryString": null, + "requestBody": null, + "statusCode": 200, + "responseBody": "{\n \"name\": \"{{ faker 'person.firstName' }}\",\n \"surname\": \"{{ faker 'person.lastName' }}\",\n \"email\": \"{{ faker 'internet.email' }}\",\n \"phoneNumber\": \"{{ faker 'phone.number' }}\",\n \"registeredDevices\": [\n {\n \"deviceId\": \"{{helpers.guid()}}\",\n \"deviceInfo\": \"Ios 18\",\n \"active\": true\n }\n ],\n \"language\": \"{{random_language_code}}\"\n}", + "contentType": "application/json", + "description": "Get User Info", + "delayMs": null, + "isActive": true, + "isSequential": false, + "folderIndex": null, + "rules": [], + "sequenceItems": [] + } + ] +} \ No newline at end of file diff --git a/mockoon/migration-api.json b/mockoon/migration-api.json deleted file mode 100644 index 73eff30..0000000 --- a/mockoon/migration-api.json +++ /dev/null @@ -1,2279 +0,0 @@ -{ - "uuid": "0814e199-9bdb-48b0-9128-4679e3c257b1", - "lastMigration": 33, - "name": "vNext - Sample Api Mock", - "endpointPrefix": "", - "latency": 0, - "port": 3001, - "hostname": "localhost", - "folders": [ - { - "uuid": "eceef4f3-226b-4d95-b385-451288693d58", - "name": "ouath2", - "children": [ - { - "type": "route", - "uuid": "a2478fee-19cd-4bb9-90bc-ba71d2212aed" - }, - { - "type": "route", - "uuid": "f0613120-c84b-4e6b-9105-e3c4821223b9" - }, - { - "type": "route", - "uuid": "245bc071-8c44-4764-a1fb-ebaecd939dfd" - }, - { - "type": "route", - "uuid": "08f6d62d-e6e0-46a5-a892-4a92bc1fc9db" - }, - { - "type": "route", - "uuid": "a435af01-7c28-4efb-96e5-73057296a5e3" - }, - { - "type": "route", - "uuid": "07100aa8-2f4f-4b2e-8378-c75d3bd8199d" - }, - { - "type": "route", - "uuid": "bbc31e7e-8753-4e84-97c6-2d27ed877a66" - }, - { - "type": "route", - "uuid": "08ade138-cd5e-4e3d-a9eb-19db04a486df" - }, - { - "type": "route", - "uuid": "b35d7102-3adb-474c-858f-32e244b8f837" - }, - { - "type": "route", - "uuid": "403d5665-e412-49a0-92fa-18905719f595" - } - ] - }, - { - "uuid": "01866f78-cc06-4173-b027-0f105cc589e1", - "name": "payment", - "children": [ - { - "type": "route", - "uuid": "02b3b785-c9af-4a4b-aa2c-6cd418b0efe5" - }, - { - "type": "route", - "uuid": "0eb4b63a-2427-4ada-9ac7-af529eed675a" - }, - { - "type": "route", - "uuid": "06982e3f-70d6-47b3-8a2b-4912123ce302" - }, - { - "type": "route", - "uuid": "c5fb9466-1a2c-4344-8e2b-60462c358658" - }, - { - "type": "route", - "uuid": "0df2b206-93a6-449b-bd44-826440e30b79" - }, - { - "type": "route", - "uuid": "35e96b9c-5af3-4b31-97b1-da948cea8142" - }, - { - "type": "route", - "uuid": "28438e54-1302-4aec-8cde-c5b81fcea084" - }, - { - "type": "route", - "uuid": "ebbd66c6-e6dc-4ca5-8ad1-3ad6c379e7d5" - }, - { - "type": "route", - "uuid": "a4a1879f-b2c6-4387-926a-c12a4c677b60" - } - ] - }, - { - "uuid": "b720fd06-ecfd-423b-b9f8-1f043cd03f14", - "name": "account-opening", - "children": [ - { - "type": "route", - "uuid": "f9e7549f-4247-4873-bab2-762068985673" - }, - { - "type": "route", - "uuid": "cf9264ea-b900-4076-a9c4-b35bdc35c942" - } - ] - }, - { - "uuid": "e4aa74c7-15b5-41d5-9c2b-fd4efc30da49", - "name": "contract", - "children": [ - { - "type": "route", - "uuid": "ae0e765d-c39b-45a7-8eb8-4fc992177c18" - }, - { - "type": "route", - "uuid": "a154307e-112d-4ba8-972a-e8d1254d0cda" - } - ] - }, - { - "uuid": "b4988da1-6b57-4783-8a36-79e9fd497ec9", - "name": "task-test", - "children": [ - { - "type": "route", - "uuid": "116204aa-7cfc-4722-bfbf-e47849bf7615" - }, - { - "type": "route", - "uuid": "280c208d-cd51-4843-ac10-9ffe63191140" - }, - { - "type": "route", - "uuid": "a56487a3-7288-4931-a33d-ba518745b642" - }, - { - "type": "route", - "uuid": "d7de7b48-ece3-4d22-be22-03099c742c64" - } - ] - }, - { - "uuid": "898985c3-5c97-46f6-84db-82b651eb070a", - "name": "notification", - "children": [ - { - "type": "route", - "uuid": "7434390e-a030-4a22-bafc-c81e22580100" - } - ] - }, - { - "uuid": "e28601d8-d4e7-42ef-ab04-0abaf99de45e", - "name": "error-boundary", - "children": [ - { - "type": "route", - "uuid": "343bb629-13a2-453a-911e-175e9f497cd7" - }, - { - "type": "route", - "uuid": "1c4fdf32-e7f3-4ac0-adbe-bb22e4f7d894" - }, - { - "type": "route", - "uuid": "315ac914-3203-4286-b47c-127152f17839" - }, - { - "type": "route", - "uuid": "5227d151-33bb-487e-9419-7a2fcdca45cd" - }, - { - "type": "route", - "uuid": "e4975b46-d6e9-4e79-b30c-c91b45ce270e" - } - ] - }, - { - "uuid": "93e1285c-17d1-4cd7-9d46-7b93c8021709", - "name": "discovery", - "children": [ - { - "type": "route", - "uuid": "18f05afb-8eca-488f-b17f-89ccc29b1277" - }, - { - "type": "route", - "uuid": "4f0c29fe-110b-421b-90c2-065a61be8229" - } - ] - } - ], - "routes": [ - { - "uuid": "33dc9cb7-3f22-42d7-8f68-7e718467141f", - "type": "http", - "documentation": "Health check endpoint", - "method": "get", - "endpoint": "health", - "responses": [ - { - "uuid": "10e2c981-8401-4118-9947-9de763647010", - "body": "{\n \"status\": \"ok\",\n \"timestamp\": \"{{now}}\",\n \"service\": \"migration-api\",\n \"version\": \"1.0.0\"\n}", - "latency": 0, - "statusCode": 200, - "label": "Health OK", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "a2478fee-19cd-4bb9-90bc-ba71d2212aed", - "type": "http", - "documentation": "OAuth2 Client validation - İstemci doğrulama", - "method": "post", - "endpoint": "api/oauth2/client/validate", - "responses": [ - { - "uuid": "31c7f619-8b35-4f34-89ae-c9fa1b2456e9", - "body": "{\n \"success\": true,\n \"clientId\": \"{{body 'client_id'}}\",\n \"grantTypes\": [\"client_credentials\", \"password\", \"authorization_code\"],\n \"redirectUris\": [\"http://localhost:3000/callback\"],\n \"scopes\": [\"api\", \"read\", \"write\"],\n \"isActive\": true\n}", - "latency": 100, - "statusCode": 200, - "label": "Client Geçerli", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "client_id", - "value": "", - "invert": true, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "90106171-a97d-4d81-a929-2e1611b5135d", - "body": "{\n \"success\": false,\n \"error\": \"Geçersiz client credentials\",\n \"errorCode\": \"invalid_client\"\n}", - "latency": 50, - "statusCode": 401, - "label": "Client Geçersiz", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "client_id", - "value": "", - "invert": false, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "f0613120-c84b-4e6b-9105-e3c4821223b9", - "type": "http", - "documentation": "OAuth2 User credentials validation - Kullanıcı kimlik bilgileri doğrulama", - "method": "post", - "endpoint": "api/oauth2/user/authenticate", - "responses": [ - { - "uuid": "825c21d1-b62f-4ffa-b3cd-d45279f66cb5", - "body": "{\n \"success\": true,\n \"userId\": \"{{faker 'string.uuid'}}\",\n \"username\": \"{{body 'username'}}\",\n \"email\": \"{{body 'username'}}@example.com\",\n \"roles\": [\"user\"],\n \"mfaRequired\": true\n}", - "latency": 150, - "statusCode": 200, - "label": "Kullanıcı Geçerli", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "username", - "value": "admin", - "invert": false, - "operator": "equals" - }, - { - "target": "body", - "modifier": "password", - "value": "password123", - "invert": false, - "operator": "equals" - } - ], - "rulesOperator": "AND", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "31f408db-7647-494b-999d-8a2431c07839", - "body": "{\n \"success\": false,\n \"error\": \"Geçersiz kullanıcı adı veya şifre\",\n \"errorCode\": \"invalid_credentials\"\n}", - "latency": 100, - "statusCode": 401, - "label": "Kullanıcı Geçersiz", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "a435af01-7c28-4efb-96e5-73057296a5e3", - "type": "http", - "documentation": "OAuth2 Authorization code validation - Authorization code doğrulama", - "method": "post", - "endpoint": "api/oauth2/user/validate-authorization-code", - "responses": [ - { - "uuid": "222b2a8a-5516-41ef-beff-73c896c1df71", - "body": "{\n \"success\": true,\n \"code\": \"{{body 'code'}}\",\n \"clientId\": \"{{body 'client_id'}}\",\n \"userId\": \"{{faker 'string.uuid'}}\",\n \"redirectUri\": \"{{body 'redirect_uri'}}\",\n \"codeChallenge\": \"{{body 'code_challenge'}}\",\n \"codeChallengeMethod\": \"{{body 'code_challenge_method'}}\",\n \"isValid\": true,\n \"expiresAt\": \"{{dateTimeAdd (now) 10 'minutes'}}\"\n}", - "latency": 100, - "statusCode": 200, - "label": "Authorization Code Geçerli", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "245bc071-8c44-4764-a1fb-ebaecd939dfd", - "type": "http", - "documentation": "Device registration check - Cihaz kayıt durumu kontrolü", - "method": "get", - "endpoint": "api/oauth2/devices/check", - "responses": [ - { - "uuid": "a4675a02-beb7-49fd-b8a9-4cd6dd727ee6", - "body": "{\n \"isRegistered\": true,\n \"deviceId\": \"{{header 'X-Device-Id'}}\",\n \"deviceName\": \"iPhone 15 Pro\",\n \"deviceType\": \"mobile\",\n \"supportsPush\": true,\n \"registeredAt\": \"2024-09-10T01:48:20.501Z\",\n \"lastSeenAt\": \"{{now}}\"\n}", - "latency": 80, - "statusCode": 200, - "label": "Cihaz Kayıtlı", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "header", - "modifier": "X-Device-Id", - "value": "", - "invert": true, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "c662164e-172c-444b-a93b-75eb486ae0f7", - "body": "{\n \"isRegistered\": false,\n \"deviceId\": \"{{header 'X-Device-Id'}}\",\n \"supportsPush\": false,\n \"requiresRegistration\": true\n}", - "latency": 60, - "statusCode": 200, - "label": "Cihaz Kayıtlı Değil", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "header", - "modifier": "X-Device-Id", - "value": "unregistered-.*", - "invert": false, - "operator": "regex" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "08f6d62d-e6e0-46a5-a892-4a92bc1fc9db", - "type": "http", - "documentation": "Send push notification for MFA - MFA için push bildirimi gönder", - "method": "post", - "endpoint": "api/oauth2/push/send", - "responses": [ - { - "uuid": "715415ba-b603-4db8-902f-e954020b640d", - "body": "{\n \"success\": true,\n \"notificationId\": \"push_{{faker 'string.uuid'}}\",\n \"deviceId\": \"{{body 'deviceId'}}\",\n \"userId\": \"{{body 'userId'}}\",\n \"message\": \"Giriş onayı gerekli\",\n \"sentAt\": \"{{now}}\",\n \"expiresAt\": \"{{dateTimeAdd (now) 5 'minutes'}}\",\n \"status\": \"sent\"\n}", - "latency": 200, - "statusCode": 200, - "label": "Push Bildirimi Gönderildi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "07100aa8-2f4f-4b2e-8378-c75d3bd8199d", - "type": "http", - "documentation": "Check push notification response - Push bildirimi yanıtını kontrol et", - "method": "post", - "endpoint": "api/oauth2/push/status", - "responses": [ - { - "uuid": "c11d91fa-bdfc-4392-8758-fbdf025d1a39", - "body": "{\n \"notificationId\": \"{{body 'notificationId'}}\",\n \"status\": \"approved\",\n \"respondedAt\": \"{{now}}\",\n \"deviceId\": \"{{body 'deviceId'}}\",\n \"action\": \"approve\",\n \"success\": true\n}", - "latency": 100, - "statusCode": 200, - "label": "Push Onaylandı", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "notificationId", - "value": "push_.*", - "invert": false, - "operator": "regex" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "9321d160-f9aa-4457-ae78-d11c9f814f10", - "body": "{\n \"notificationId\": \"{{body 'notificationId'}}\",\n \"status\": \"denied\",\n \"respondedAt\": \"{{now}}\",\n \"deviceId\": \"{{body 'deviceId'}}\",\n \"action\": \"deny\",\n \"success\": false,\n \"reason\": \"User denied the request\"\n}", - "latency": 80, - "statusCode": 200, - "label": "Push Reddedildi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "action", - "value": "deny", - "invert": false, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "bbc31e7e-8753-4e84-97c6-2d27ed877a66", - "type": "http", - "documentation": "Send OTP notification - OTP bildirimi gönder (SMS/Email)", - "method": "post", - "endpoint": "api/oauth2/otp/send", - "responses": [ - { - "uuid": "a1ef6b5d-e65b-4280-a47d-29c106c5e47d", - "body": "{\n \"success\": true,\n \"otpId\": \"otp_{{faker 'string.uuid'}}\",\n \"userId\": \"{{body 'userId'}}\",\n \"method\": \"{{body 'method'}}\",\n \"target\": \"{{body 'target'}}\",\n \"maskedTarget\": \"***@***.com\",\n \"sentAt\": \"{{now}}\",\n \"expiresAt\": \"{{dateTimeAdd (now) 5 'minutes'}}\",\n \"length\": 6\n}", - "latency": 250, - "statusCode": 200, - "label": "OTP Gönderildi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "08ade138-cd5e-4e3d-a9eb-19db04a486df", - "type": "http", - "documentation": "Verify OTP code - OTP kodu doğrula", - "method": "post", - "endpoint": "api/oauth2/otp/verify", - "responses": [ - { - "uuid": "6492edce-ff30-4cd6-b3f3-27441464996f", - "body": "{\n \"success\": true,\n \"otpId\": \"{{body 'otpId'}}\",\n \"code\": \"{{body 'code'}}\",\n \"isValid\": true,\n \"verifiedAt\": \"{{now}}\",\n \"remainingAttempts\": 2\n}", - "latency": 100, - "statusCode": 200, - "label": "OTP Geçerli", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "code", - "value": "123456", - "invert": false, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "1772d12e-4d42-409d-97cd-a85821c1cc17", - "body": "{\n \"success\": false,\n \"otpId\": \"{{body 'otpId'}}\",\n \"code\": \"{{body 'code'}}\",\n \"isValid\": false,\n \"error\": \"Geçersiz OTP kodu\",\n \"remainingAttempts\": 1\n}", - "latency": 80, - "statusCode": 400, - "label": "OTP Geçersiz", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "b35d7102-3adb-474c-858f-32e244b8f837", - "type": "http", - "documentation": "Register device for MFA - MFA için cihaz kaydet", - "method": "post", - "endpoint": "api/oauth2/devices/register", - "responses": [ - { - "uuid": "0c587644-967c-45e4-be17-d049d7673a0f", - "body": "{\n \"success\": true,\n \"deviceId\": \"{{faker 'string.uuid'}}\",\n \"userId\": \"{{body 'userId'}}\",\n \"deviceName\": \"{{body 'deviceName'}}\",\n \"deviceType\": \"{{body 'deviceType'}}\",\n \"supportsPush\": true,\n \"registeredAt\": \"{{now}}\",\n \"token\": \"device_{{faker 'string.alphanumeric' 32}}\"\n}", - "latency": 150, - "statusCode": 201, - "label": "Cihaz Başarıyla Kaydedildi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "403d5665-e412-49a0-92fa-18905719f595", - "type": "http", - "documentation": "Generate OAuth2 tokens - OAuth2 token'ları oluştur", - "method": "post", - "endpoint": "api/oauth2/tokens/generate", - "responses": [ - { - "uuid": "80deddfb-c1c2-4513-bd47-458ad0a276ac", - "body": "{\n \"access_token\": \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.{{faker 'string.alphanumeric' 50}}\",\n \"refresh_token\": \"rt_{{faker 'string.alphanumeric' 32}}\",\n \"token_type\": \"Bearer\",\n \"expires_in\": 3600,\n \"scope\": \"{{body 'scope'}}\",\n \"client_id\": \"{{body 'clientId'}}\",\n \"user_id\": \"{{body 'userId'}}\",\n \"device_id\": \"{{body 'deviceId'}}\",\n \"issued_at\": \"{{now}}\",\n \"expires_at\": \"{{dateTimeAdd (now) 1 'hours'}}\"\n}", - "latency": 120, - "statusCode": 200, - "label": "Token'lar Oluşturuldu", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "02b3b785-c9af-4a4b-aa2c-6cd418b0efe5", - "type": "http", - "documentation": "Save Payment Configuration - Ödeme yapılandırmasını kaydet", - "method": "post", - "endpoint": "api/payments/schedules", - "responses": [ - { - "uuid": "2f7a335d-9110-4be7-95ad-6a60a129bf66", - "body": "{\n \"success\": true,\n \"scheduleId\": \"{{faker 'string.uuid'}}\",\n \"userId\": \"{{body 'userId'}}\",\n \"amount\": {{body 'amount'}},\n \"currency\": \"{{body 'currency'}}\",\n \"frequency\": \"{{body 'frequency'}}\",\n \"startDate\": \"{{body 'startDate'}}\",\n \"endDate\": \"{{body 'endDate'}}\",\n \"paymentMethodId\": \"{{body 'paymentMethodId'}}\",\n \"description\": \"{{body 'description'}}\",\n \"recipientId\": \"{{body 'recipientId'}}\",\n \"isAutoRetry\": {{body 'isAutoRetry'}},\n \"maxRetries\": {{body 'maxRetries'}},\n \"status\": \"inactive\",\n \"nextPaymentDate\": \"{{dateTimeAdd (now) 1 'days'}}\",\n \"createdAt\": \"{{now}}\",\n \"maxPayments\": 4\n}", - "latency": 200, - "statusCode": 201, - "label": "Ödeme Yapılandırması Kaydedildi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "25aa9a22-bc7d-4900-9f61-2ebd8e570d68", - "body": "{\n \"success\": false,\n \"error\": \"Geçersiz ödeme yapılandırması\",\n \"errorCode\": \"invalid_payment_config\",\n \"details\": \"Eksik veya geçersiz parametreler\"\n}", - "latency": 100, - "statusCode": 400, - "label": "Geçersiz Yapılandırma", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "userId", - "value": "", - "invert": false, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "0eb4b63a-2427-4ada-9ac7-af529eed675a", - "type": "http", - "documentation": "Process Payment - Ödeme işle", - "method": "post", - "endpoint": "api/payments/process", - "responses": [ - { - "uuid": "8db05c61-f267-4a9d-b8ee-eea1a9abcc3b", - "body": "{\n \"success\": true,\n \"transactionId\": \"txn_{{faker 'string.uuid'}}\",\n \"scheduleId\": \"{{body 'scheduleId'}}\",\n \"amount\": {{body 'amount'}},\n \"currency\": \"{{body 'currency'}}\",\n \"paymentMethod\": \"card\",\n \"processedAt\": \"{{now}}\",\n \"fees\": {\n \"amount\": {{faker 'number.float' 0.5 5.0 2}},\n \"currency\": \"{{body 'currency'}}\"\n },\n \"status\": \"completed\"\n}", - "latency": 1500, - "statusCode": 200, - "label": "Ödeme Başarılı", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "amount", - "value": "0", - "invert": true, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "dca2e98e-c04d-404f-b910-9c513940796a", - "body": "{\n \"success\": false,\n \"error\": \"Yetersiz bakiye\",\n \"errorCode\": \"insufficient_funds\",\n \"amount\": {{body 'amount'}},\n \"availableBalance\": {{faker 'number.float' 0 100 2}}\n}", - "latency": 800, - "statusCode": 402, - "label": "Yetersiz Bakiye", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "amount", - "value": "1000", - "invert": false, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "571f2962-ac2d-4681-938b-eb39741a8cd8", - "body": "{\n \"success\": false,\n \"error\": \"Ödeme işleme hatası\",\n \"errorCode\": \"payment_processing_error\",\n \"description\": \"Ödeme sağlayıcısı geçici olarak kullanılamıyor\"\n}", - "latency": 5000, - "statusCode": 503, - "label": "Servis Kullanılamıyor", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "06982e3f-70d6-47b3-8a2b-4912123ce302", - "type": "http", - "documentation": "Activate Payment Schedule - Ödeme planını aktifleştir", - "method": "patch", - "endpoint": "api/payments/schedules/:scheduleId/activate", - "responses": [ - { - "uuid": "3a4eab4b-9ea7-477f-804b-b3fd9328bca6", - "body": "{\n \"success\": true,\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\",\n \"status\": \"active\",\n \"activatedAt\": \"{{now}}\",\n \"nextPaymentDate\": \"{{dateTimeAdd (now) 1 'days'}}\",\n \"isActive\": true\n}", - "latency": 300, - "statusCode": 200, - "label": "Plan Aktifleştirildi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "ceab4a53-8a05-4760-b02d-cdc1e06f376f", - "body": "{\n \"success\": false,\n \"error\": \"Ödeme planı bulunamadı\",\n \"errorCode\": \"schedule_not_found\",\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\"\n}", - "latency": 100, - "statusCode": 404, - "label": "Plan Bulunamadı", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "params", - "modifier": "scheduleId", - "value": "invalid-.*", - "invert": false, - "operator": "regex" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "c5fb9466-1a2c-4344-8e2b-60462c358658", - "type": "http", - "documentation": "Deactivate Payment Schedule - Ödeme planını deaktifleştir", - "method": "patch", - "endpoint": "api/payments/schedules/:scheduleId/deactivate", - "responses": [ - { - "uuid": "b648f482-34c3-4ff6-a430-b26f0d9bcd77", - "body": "{\n \"success\": true,\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\",\n \"status\": \"deactive\",\n \"deactivatedAt\": \"{{now}}\",\n \"reason\": \"{{body 'reason'}}\",\n \"isActive\": false\n}", - "latency": 200, - "statusCode": 200, - "label": "Plan Deaktifleştirildi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "0df2b206-93a6-449b-bd44-826440e30b79", - "type": "http", - "documentation": "Archive Payment Record - Ödeme kaydını arşivle", - "method": "post", - "endpoint": "api/payments/schedules/:scheduleId/archive", - "responses": [ - { - "uuid": "2e7a5516-4304-4c93-8e3c-34f4b9ed05f8", - "body": "{\n \"success\": true,\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\",\n \"status\": \"archived\",\n \"archivedAt\": \"{{now}}\",\n \"completionReason\": \"{{body 'completionReason'}}\",\n \"finalPaymentCount\": {{body 'finalPaymentCount'}}\n}", - "latency": 150, - "statusCode": 200, - "label": "Kayıt Arşivlendi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "35e96b9c-5af3-4b31-97b1-da948cea8142", - "type": "http", - "documentation": "Increment Retry Counter - Yeniden deneme sayacını artır", - "method": "patch", - "endpoint": "api/payments/schedules/:scheduleId/retry", - "responses": [ - { - "uuid": "0634953a-076b-4f58-9237-d652abb25f09", - "body": "{\n \"success\": true,\n \"scheduleId\": \"{{urlParam 'scheduleId'}}\",\n \"retryCount\": {{body 'retryCount'}},\n \"retryAt\": \"{{body 'retryAt'}}\",\n \"maxRetries\": 3,\n \"retriesRemaining\": {{subtract 3 (body 'retryCount')}}\n}", - "latency": 100, - "statusCode": 200, - "label": "Sayaç Güncellendi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "28438e54-1302-4aec-8cde-c5b81fcea084", - "type": "http", - "documentation": "Send Payment Notification Sms - Sms Bilgilendirme", - "method": "post", - "endpoint": "api/payments/notify/sms", - "responses": [ - { - "uuid": "1cbd8b2e-368b-4e41-b3ca-b46fa3ec724a", - "body": "{\n \"success\": true,\n \"sendedAt\": \"{{now}}\"\n}", - "latency": 200, - "statusCode": 201, - "label": "Sms Gönderildi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "ba619503-bb6f-404f-9450-e68089961e48", - "body": "{\n \"success\": false,\n \"error\": \"Geçersiz ödeme yapılandırması\",\n \"errorCode\": \"invalid_payment_config\",\n \"details\": \"Eksik veya geçersiz parametreler\"\n}", - "latency": 100, - "statusCode": 400, - "label": "Geçersiz Yapılandırma", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "userId", - "value": "", - "invert": false, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "ebbd66c6-e6dc-4ca5-8ad1-3ad6c379e7d5", - "type": "http", - "documentation": "Send Payment Notification Push - Mobile Bilgilendirme", - "method": "post", - "endpoint": "api/payments/notify/push", - "responses": [ - { - "uuid": "b24a7512-c03b-4c23-b2f3-3338953cb87c", - "body": "{\n \"success\": true,\n \"sendedAt\": \"{{now}}\"\n}", - "latency": 200, - "statusCode": 201, - "label": "Push Gönderildi", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "5c9cf8d8-edf8-4fde-afa9-aa53d17291f6", - "body": "{\n \"success\": false,\n \"error\": \"Geçersiz ödeme yapılandırması\",\n \"errorCode\": \"invalid_payment_config\",\n \"details\": \"Eksik veya geçersiz parametreler\"\n}", - "latency": 100, - "statusCode": 400, - "label": "Geçersiz Yapılandırma", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "userId", - "value": "", - "invert": false, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "a4a1879f-b2c6-4387-926a-c12a4c677b60", - "type": "http", - "documentation": "Get User Info - Kullanıcı Bilgisini Getir", - "method": "get", - "endpoint": "api/payments/users/:userId", - "responses": [ - { - "uuid": "849e834c-c753-4122-bbe9-74e38a33b8b1", - "body": "{\n \"name\": \"John\",\n \"surname\": \"Smith\",\n \"email\": \"john.smith@example.com\",\n \"phoneNumber\": \"905452424847\",\n \"registeredDevices\": [{\n \"deviceId\": \"{{faker 'string.uuid'}}\",\n \"deviceInfo\": \"Ios 18\",\n \"active\": true\n }],\n \"language\": \"tr-TR\"\n}", - "latency": 200, - "statusCode": 200, - "label": "Kullanıcı Bilgisi Döner", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "f9e7549f-4247-4873-bab2-762068985673", - "type": "http", - "documentation": "Validates account opening against bank policies", - "method": "post", - "endpoint": "api/banking/policies/validate-account-opening", - "responses": [ - { - "uuid": "5a48a42f-5adb-4f25-b52e-3473b3827bc8", - "body": "{\n \"validationId\": \"{{faker 'string.uuid'}}\",\n \"complianceChecks\": {\n \"kycCompliant\": true,\n \"amlCompliant\": true,\n \"sanctionsCheck\": true,\n \"riskAssessment\": \"low\"\n },\n \"accountLimits\": {\n \"dailyTransactionLimit\": 50000,\n \"monthlyTransactionLimit\": 500000,\n \"minimumBalance\": 0,\n \"maximumBalance\": 1000000\n },\n \"additionalRequirements\": [],\n \"approvedBy\": \"system\",\n \"approvalLevel\": \"automated\",\n \"policyVersion\": \"1.0.0\",\n \"validationScore\": {{faker 'number.int' min=85 max=100}}\n}", - "latency": 0, - "statusCode": 200, - "label": "Policy Validation Passed", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "currency", - "value": "TRY|USD|EUR|GBP", - "invert": false, - "operator": "regex" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "3d8c58a4-7d77-4f2c-b38b-3645cd80a674", - "body": "{\n \"validationId\": \"{{faker 'string.uuid'}}\",\n \"error\": {\n \"message\": \"Policy validation failed\",\n \"code\": \"policy_violation\",\n \"description\": \"Account opening request does not meet policy requirements\"\n },\n \"failedChecks\": [\n \"risk_assessment\"\n ],\n \"recommendations\": [\n \"Please review your account information\",\n \"Contact customer support for assistance\"\n ],\n \"canRetry\": true,\n \"retryAfter\": 300\n}", - "latency": 0, - "statusCode": 403, - "label": "Policy Validation Failed", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "cf9264ea-b900-4076-a9c4-b35bdc35c942", - "type": "http", - "documentation": "Creates a new bank account in core banking system", - "method": "post", - "endpoint": "api/banking/accounts/create", - "responses": [ - { - "uuid": "8e2147df-ffbd-42b9-a0cc-46fecb6a488f", - "body": "{\n \"accountId\": \"{{faker 'string.uuid'}}\",\n \"accountNumber\": \"{{faker 'finance.accountNumber'}}\",\n \"iban\": \"TR{{faker 'string.numeric' 24}}\",\n \"accountType\": \"demand-deposit\",\n \"currency\": \"{{body 'currency'}}\",\n \"branchCode\": \"{{body 'branchCode'}}\",\n \"status\": \"active\",\n \"isActive\": true,\n \"currentBalance\": {{body 'initialDeposit' 0}},\n \"availableBalance\": {{body 'initialDeposit' 0}},\n \"limits\": {\n \"dailyTransactionLimit\": 50000,\n \"monthlyTransactionLimit\": 500000,\n \"minimumBalance\": 0,\n \"maximumBalance\": 1000000\n },\n \"debitCardRequested\": false,\n \"onlineBankingEnabled\": true,\n \"mobileBankingEnabled\": true,\n \"creationReference\": \"{{faker 'string.uuid'}}\",\n \"coreBankingId\": \"CB{{faker 'string.numeric' 10}}\",\n \"services\": [\n \"online-banking\",\n \"mobile-banking\",\n \"sms-banking\"\n ]\n}", - "latency": 0, - "statusCode": 201, - "label": "Account Created Successfully", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "accountName", - "value": ".+", - "invert": false, - "operator": "regex" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "83326ab5-0084-4b4a-84fb-969f43c0e8c9", - "body": "{\n \"error\": {\n \"message\": \"Account creation failed\",\n \"code\": \"validation_error\",\n \"description\": \"Account data validation failed\"\n },\n \"failureReason\": \"invalid_account_name\",\n \"failureCategory\": \"validation_error\",\n \"canRetry\": true,\n \"retryAfter\": 300,\n \"maxRetries\": 3,\n \"recommendations\": [\n \"Please check your account information and try again\",\n \"Account name must be between 1-50 characters\"\n ],\n \"supportReference\": \"{{faker 'string.uuid'}}\"\n}", - "latency": 0, - "statusCode": 422, - "label": "Account Creation Failed", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "ae0e765d-c39b-45a7-8eb8-4fc992177c18", - "type": "http", - "documentation": "", - "method": "post", - "endpoint": "api/contract/get-documents", - "responses": [ - { - "uuid": "cfb4904f-d56e-4dc7-999e-ab48bcd066dd", - "body": "{\n \"statusCode\": 200,\n \"data\": {\n \"groupCode\": \"{{body 'groupCode'}}\",\n \"contracts\": [\n {\n \"contractId\": \"{{faker 'string.uuid'}}\",\n \"contractType\": \"account-opening\",\n \"contractName\": \"Hesap Açılış Sözleşmesi\",\n \"templateId\": \"TPL-ACCOUNT-001\",\n \"contractData\": {\n \"accountType\": \"demand-deposit\",\n \"currency\": \"TRY\"\n }\n },\n {\n \"contractId\": \"{{faker 'string.uuid'}}\",\n \"contractType\": \"terms-conditions\",\n \"contractName\": \"Genel Hüküm ve Koşullar\",\n \"templateId\": \"TPL-TERMS-001\",\n \"contractData\": {\n \"version\": \"2.0\"\n }\n },\n {\n \"contractId\": \"{{faker 'string.uuid'}}\",\n \"contractType\": \"kvkk\",\n \"contractName\": \"KVKK Aydınlatma Metni\",\n \"templateId\": \"TPL-KVKK-001\",\n \"contractData\": {\n \"consentDate\": \"{{now 'yyyy-MM-dd'}}\"\n }\n }\n ],\n \"totalContracts\": 3,\n \"retrievedAt\": \"{{now}}\"\n }\n}", - "latency": 0, - "statusCode": 200, - "label": "Contracts Retrieved Successfully", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "6d59acc7-3ab8-4f81-a9fb-b1b84e2f3d86", - "body": "{\n \"statusCode\": 404,\n \"data\": {\n \"error\": {\n \"message\": \"Contract group not found\",\n \"code\": \"group_not_found\",\n \"description\": \"The specified contract group code does not exist\"\n }\n }\n}", - "latency": 0, - "statusCode": 404, - "label": "Contract Group Not Found", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "a154307e-112d-4ba8-972a-e8d1254d0cda", - "type": "http", - "documentation": "", - "method": "post", - "endpoint": "api/contract/render-document", - "responses": [ - { - "uuid": "674dd2b3-df43-4a22-957b-14db70b95656", - "body": "{\n \"statusCode\": 200,\n \"data\": {\n \"documentId\": \"{{faker 'string.uuid'}}\",\n \"documentUrl\": \"https://cdn.example.com/contracts/{{faker 'string.alphanumeric' 32}}.pdf\",\n \"documentSize\": {{faker 'number.int' min=50000 max=500000}},\n \"pageCount\": {{faker 'number.int' min=1 max=10}},\n \"checksum\": \"{{faker 'string.alphanumeric' 64}}\",\n \"expiresAt\": \"{{faker 'date.future'}}\",\n \"renderedAt\": \"{{now}}\",\n \"format\": \"pdf\",\n \"templateVersion\": \"1.0.0\"\n }\n}", - "latency": 0, - "statusCode": 200, - "label": "Document Rendered Successfully", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "69af2566-542e-4859-93b7-34b408924232", - "body": "{\n \"statusCode\": 500,\n \"data\": {\n \"error\": {\n \"message\": \"Document rendering failed\",\n \"code\": \"render_failed\",\n \"description\": \"Unable to render the contract document\"\n }\n }\n}", - "latency": 0, - "statusCode": 500, - "label": "Document Render Failed", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "d7de7b48-ece3-4d22-be22-03099c742c64", - "type": "http", - "documentation": "Task Test HTTP Endpoint - Test for HttpTask type", - "method": "post", - "endpoint": "api/task-test/http-endpoint", - "responses": [ - { - "uuid": "6a78c8ca-8522-4806-b366-6401885c8817", - "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"taskType\": \"HttpTask\",\n \"message\": \"HTTP task test successful\",\n \"receivedData\": {{body}},\n \"processedAt\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n },\n \"metadata\": {\n \"endpoint\": \"api/task-test/http-endpoint\",\n \"method\": \"POST\",\n \"responseTime\": {{faker 'number.int' min=50 max=200}}\n }\n}", - "latency": 500, - "statusCode": 200, - "label": "Success Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "X-Task-Type", - "value": "HttpTask" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "48844960-4754-47d1-b90e-0d3d4478ccf0", - "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", - "latency": 200, - "statusCode": 500, - "label": "Error Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "body", - "modifier": "simulateError", - "value": "true", - "invert": false, - "operator": "equals" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "116204aa-7cfc-4722-bfbf-e47849bf7615", - "type": "http", - "documentation": "Task Test Consume Endpoint - Test for PubSub type", - "method": "post", - "endpoint": "api/task-test/consume", - "responses": [ - { - "uuid": "ca697a7f-050a-4cab-ab78-8f15a1e1225b", - "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"taskType\": \"DaprPubsub\",\n \"message\": \"HTTP task test successful\",\n \"receivedData\": {{body}},\n \"processedAt\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n },\n \"metadata\": {\n \"endpoint\": \"api/task-test/consume\",\n \"method\": \"POST\",\n \"responseTime\": {{faker 'number.int' min=50 max=200}}\n }\n}", - "latency": 0, - "statusCode": 200, - "label": "Success Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "X-Task-Type", - "value": "DaprPubSub" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "923377a8-e8fb-42e4-b742-a496e3d110b6", - "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", - "latency": 0, - "statusCode": 500, - "label": "Error Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "280c208d-cd51-4843-ac10-9ffe63191140", - "type": "http", - "documentation": "Task Test HTTP Endpoint - Test for DaprService type", - "method": "post", - "endpoint": "api/task-test/dapr-endpoint", - "responses": [ - { - "uuid": "f2d3194a-db97-409c-a7f6-3bf8d3f2bea7", - "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"taskType\": \"DaprService\",\n \"message\": \"HTTP task test successful\",\n \"receivedData\": {{body}},\n \"processedAt\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n },\n \"metadata\": {\n \"endpoint\": \"api/task-test/dapr-endpoint\",\n \"method\": \"POST\",\n \"responseTime\": {{faker 'number.int' min=50 max=200}}\n }\n}", - "latency": 0, - "statusCode": 200, - "label": "Success Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "X-Task-Type", - "value": "DaprService" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "666e268f-a726-4dc9-97f9-b400b2c0ed57", - "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", - "latency": 0, - "statusCode": 500, - "label": "Error Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "a56487a3-7288-4931-a33d-ba518745b642", - "type": "http", - "documentation": "Task Test HTTP Endpoint - Test for HttpTask type", - "method": "post", - "endpoint": "api/task-test/list-items", - "responses": [ - { - "uuid": "ac9d4ded-465e-4bbb-bfcd-c29e92b26328", - "body": "[\n {\n \"id\": \"{{faker 'string.uuid'}}\",\n \"name\": \"item_{{faker 'string.alphanumeric' 10}}\",\n \"isActive\": true\n },\n {\n \"id\": \"{{faker 'string.uuid'}}\",\n \"name\": \"item_{{faker 'string.alphanumeric' 10}}\",\n \"isActive\": true\n },\n {\n \"id\": \"{{faker 'string.uuid'}}\",\n \"name\": \"item_{{faker 'string.alphanumeric' 10}}\",\n \"isActive\": true\n },\n {\n \"id\": \"{{faker 'string.uuid'}}\",\n \"name\": \"item_{{faker 'string.alphanumeric' 10}}\",\n \"isActive\": true\n }\n]", - "latency": 0, - "statusCode": 200, - "label": "Success Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "X-Task-Type", - "value": "HttpTasks" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "3dbdfc91-716b-44ba-8956-0f6f412847bc", - "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", - "latency": 0, - "statusCode": 500, - "label": "Error Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "7434390e-a030-4a22-bafc-c81e22580100", - "type": "http", - "documentation": "Task Test HTTP Endpoint - Test for NotificationTask type", - "method": "post", - "endpoint": "api/notification/send", - "responses": [ - { - "uuid": "dc8b218b-8d43-4465-9e3b-38c0d52782cd", - "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"taskType\": \"NotificationTask\",\n \"message\": \"HTTP task test successful\",\n \"receivedData\": {{body}},\n \"processedAt\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n },\n \"metadata\": {\n \"endpoint\": \"api/notification/send\",\n \"method\": \"POST\",\n \"responseTime\": {{faker 'number.int' min=50 max=200}}\n }\n}", - "latency": 0, - "statusCode": 200, - "label": "Success Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "5bf29053-f5f2-4359-bbd9-85b853934a88", - "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_ERROR\",\n \"message\": \"Task test HTTP endpoint error\",\n \"timestamp\": \"{{now}}\"\n }\n}", - "latency": 0, - "statusCode": 500, - "label": "Error Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "343bb629-13a2-453a-911e-175e9f497cd7", - "type": "http", - "documentation": "ErrorBoundary Test - Simulate 503 Service Unavailable for Retry testing", - "method": "post", - "endpoint": "api/error-boundary/simulate-503", - "responses": [ - { - "uuid": "28f418fb-d189-4a80-b04e-0ab90f31b300", - "body": "{\n \"statusCode\": 503,\n \"success\": false,\n \"error\": {\n \"code\": \"SERVICE_UNAVAILABLE\",\n \"message\": \"Service temporarily unavailable\",\n \"description\": \"The service is currently undergoing maintenance or is overloaded\",\n \"retryAfter\": 5\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", - "latency": 500, - "statusCode": 503, - "label": "Service Unavailable - Retry Test", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "Retry-After", - "value": "5" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "1c4fdf32-e7f3-4ac0-adbe-bb22e4f7d894", - "type": "http", - "documentation": "ErrorBoundary Test - Simulate 500 Internal Server Error for Abort testing", - "method": "post", - "endpoint": "api/error-boundary/simulate-500", - "responses": [ - { - "uuid": "ec79ccf6-4abc-460d-8fff-347f39fabc6e", - "body": "{\n \"statusCode\": 500,\n \"success\": false,\n \"error\": {\n \"code\": \"INTERNAL_SERVER_ERROR\",\n \"message\": \"An unexpected error occurred\",\n \"description\": \"Critical system failure - operation cannot be completed\",\n \"errorType\": \"HttpRequestException\"\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", - "latency": 200, - "statusCode": 500, - "label": "Internal Server Error - Abort Test", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "315ac914-3203-4286-b47c-127152f17839", - "type": "http", - "documentation": "ErrorBoundary Test - Simulate 400 Bad Request for Ignore testing", - "method": "post", - "endpoint": "api/error-boundary/simulate-400", - "responses": [ - { - "uuid": "8711b76c-ce2a-48bc-abc9-8a171f8d25da", - "body": "{\n \"statusCode\": 400,\n \"success\": false,\n \"error\": {\n \"code\": \"BAD_REQUEST\",\n \"message\": \"Invalid request parameters\",\n \"description\": \"The request contains invalid or missing parameters\",\n \"validationErrors\": [\n {\n \"field\": \"testField\",\n \"message\": \"Field is required\"\n }\n ]\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", - "latency": 100, - "statusCode": 400, - "label": "Bad Request - Ignore Test", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "5227d151-33bb-487e-9419-7a2fcdca45cd", - "type": "http", - "documentation": "ErrorBoundary Test - Simulate timeout with delayed response", - "method": "post", - "endpoint": "api/error-boundary/simulate-timeout", - "responses": [ - { - "uuid": "bfa529d3-8b52-4529-ab89-dd141bd3303f", - "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"message\": \"This response is intentionally delayed to trigger timeout\",\n \"delayedBy\": \"30 seconds\"\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", - "latency": 30000, - "statusCode": 200, - "label": "Delayed Response - Timeout Test", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "e4975b46-d6e9-4e79-b30c-c91b45ce270e", - "type": "http", - "documentation": "ErrorBoundary Test - Successful response for happy path testing", - "method": "post", - "endpoint": "api/error-boundary/simulate-success", - "responses": [ - { - "uuid": "2ad9a371-c101-4069-bba2-262aeb52043b", - "body": "{\n \"statusCode\": 200,\n \"success\": true,\n \"data\": {\n \"message\": \"Operation completed successfully\",\n \"result\": {\n \"operationId\": \"{{faker 'string.uuid'}}\",\n \"status\": \"completed\",\n \"processedAt\": \"{{now}}\"\n }\n },\n \"timestamp\": \"{{now}}\",\n \"requestId\": \"{{faker 'string.uuid'}}\"\n}", - "latency": 200, - "statusCode": 200, - "label": "Success Response", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "18f05afb-8eca-488f-b17f-89ccc29b1277", - "type": "http", - "documentation": "Domain Resolver", - "method": "get", - "endpoint": "api/v1/discovery/workflows/domain/instances/:domain/functions/data", - "responses": [ - { - "uuid": "ded6baeb-bd9b-42b0-8e63-89c979d350e0", - "body": "{{setVar 'eTag' (faker 'string.alphanumeric' 32)}}\n\n{{#if (eq (urlParam 'domain') 'core')}}\n {{setVar 'port' 4201}}\n{{else}}\n {{setVar 'port' (faker 'number.int' min=4200 max=5000)}}\n{{/if}}\n\n{\n \"data\": {\n \"eTag\": \"\\\"{{@eTag}}\\\"\",\n \"appId\": \"vnext-{{urlParam 'domain'}}.test-vnext-{{urlParam 'domain'}}\",\n \"baseUrl\": \"http://localhost:{{@port}}\",\n \"healthUrl\": \"https://localhost:{{@port}}/health\",\n \"domainName\": \"{{urlParam 'domain'}}\"\n },\n \"etag\": \"\\\"{{@eTag}}\\\"\",\n \"extensions\": {}\n}\n ", - "latency": 0, - "statusCode": 200, - "label": "Domain servis bilgisini döner", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "x-change-port", - "value": "true" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "119464c2-bcae-439b-a10b-c64124471ed1", - "body": "{}", - "latency": 0, - "statusCode": 404, - "label": "Domain bulunamadı", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - }, - { - "uuid": "041d2ef4-6a8f-4c9e-8951-bf54f827381d", - "body": "{}", - "latency": 0, - "statusCode": 304, - "label": "Değişiklik bulunamadı", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [ - { - "target": "header", - "modifier": "If-None-Match", - "value": "", - "invert": true, - "operator": "null" - } - ], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": false, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - }, - { - "uuid": "4f0c29fe-110b-421b-90c2-065a61be8229", - "type": "http", - "documentation": "Domain Registration", - "method": "post", - "endpoint": "api/v1/discovery/workflows/domain-registration/instances/start", - "responses": [ - { - "uuid": "7f6de031-b3bc-4d40-91e9-2290474a7946", - "body": "{\n \"id\": \"{{faker 'string.uuid'}}\",\n \"status\": \"C\"\n}", - "latency": 0, - "statusCode": 200, - "label": "", - "headers": [ - { - "key": "Content-Type", - "value": "application/json" - } - ], - "bodyType": "INLINE", - "filePath": "", - "databucketID": "", - "sendFileAsBody": false, - "rules": [], - "rulesOperator": "OR", - "disableTemplating": false, - "fallbackTo404": false, - "default": true, - "crudKey": "id", - "callbacks": [] - } - ], - "responseMode": null, - "streamingMode": null, - "streamingInterval": 0 - } - ], - "rootChildren": [ - { - "type": "route", - "uuid": "33dc9cb7-3f22-42d7-8f68-7e718467141f" - }, - { - "type": "folder", - "uuid": "eceef4f3-226b-4d95-b385-451288693d58" - }, - { - "type": "folder", - "uuid": "01866f78-cc06-4173-b027-0f105cc589e1" - }, - { - "type": "folder", - "uuid": "b720fd06-ecfd-423b-b9f8-1f043cd03f14" - }, - { - "type": "folder", - "uuid": "e4aa74c7-15b5-41d5-9c2b-fd4efc30da49" - }, - { - "type": "folder", - "uuid": "e28601d8-d4e7-42ef-ab04-0abaf99de45e" - }, - { - "type": "folder", - "uuid": "b4988da1-6b57-4783-8a36-79e9fd497ec9" - }, - { - "type": "folder", - "uuid": "898985c3-5c97-46f6-84db-82b651eb070a" - }, - { - "type": "folder", - "uuid": "93e1285c-17d1-4cd7-9d46-7b93c8021709" - } - ], - "proxyMode": false, - "proxyHost": "", - "proxyRemovePrefix": true, - "tlsOptions": { - "enabled": false, - "type": "CERT", - "pfxPath": "", - "certPath": "", - "keyPath": "", - "caPath": "", - "passphrase": "" - }, - "cors": true, - "headers": [ - { - "key": "Access-Control-Allow-Origin", - "value": "*" - }, - { - "key": "Access-Control-Allow-Methods", - "value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS" - }, - { - "key": "Access-Control-Allow-Headers", - "value": "Content-Type,Origin,Accept,Authorization,Content-Length,X-Requested-With" - } - ], - "proxyReqHeaders": [ - { - "key": "", - "value": "" - } - ], - "proxyResHeaders": [ - { - "key": "", - "value": "" - } - ], - "data": [], - "callbacks": [] -} \ No newline at end of file