From 45ca92d30f596bbc72e0c459b3e629d19af33a73 Mon Sep 17 00:00:00 2001 From: Viren Baraiya Date: Mon, 2 Sep 2024 13:35:10 -0700 Subject: [PATCH] remove java sdk --- build.gradle | 11 +- java-sdk/README.md | 11 - java-sdk/build.gradle | 33 - .../conductor/sdk/example/shipment/Order.java | 103 -- .../sdk/example/shipment/Shipment.java | 43 - .../sdk/example/shipment/ShipmentState.java | 56 - .../sdk/example/shipment/ShipmentWorkers.java | 141 -- .../example/shipment/ShipmentWorkflow.java | 219 --- .../conductor/sdk/example/shipment/User.java | 117 -- java-sdk/example/resources/script.js | 11 - .../sdk/healthcheck/HealthCheckClient.java | 66 - .../sdk/testing/LocalServerRunner.java | 206 --- .../sdk/testing/WorkflowTestRunner.java | 63 - .../sdk/workflow/def/ConductorWorkflow.java | 355 ----- .../sdk/workflow/def/ValidationError.java | 20 - .../sdk/workflow/def/WorkflowBuilder.java | 209 --- .../sdk/workflow/def/tasks/DoWhile.java | 97 -- .../sdk/workflow/def/tasks/Dynamic.java | 41 - .../sdk/workflow/def/tasks/DynamicFork.java | 115 -- .../workflow/def/tasks/DynamicForkInput.java | 51 - .../sdk/workflow/def/tasks/Event.java | 46 - .../sdk/workflow/def/tasks/ForkJoin.java | 130 -- .../sdk/workflow/def/tasks/Http.java | 308 ---- .../conductor/sdk/workflow/def/tasks/JQ.java | 43 - .../sdk/workflow/def/tasks/Javascript.java | 162 --- .../sdk/workflow/def/tasks/Join.java | 46 - .../sdk/workflow/def/tasks/SetVariable.java | 33 - .../sdk/workflow/def/tasks/SimpleTask.java | 47 - .../sdk/workflow/def/tasks/SubWorkflow.java | 87 -- .../sdk/workflow/def/tasks/Switch.java | 163 --- .../sdk/workflow/def/tasks/Task.java | 238 ---- .../sdk/workflow/def/tasks/TaskRegistry.java | 48 - .../sdk/workflow/def/tasks/Terminate.java | 66 - .../sdk/workflow/def/tasks/Wait.java | 63 - .../workflow/executor/WorkflowExecutor.java | 253 ---- .../executor/task/AnnotatedWorker.java | 247 ---- .../task/AnnotatedWorkerExecutor.java | 231 --- .../executor/task/DynamicForkWorker.java | 119 -- .../executor/task/NonRetryableException.java | 32 - .../workflow/executor/task/TaskContext.java | 79 -- .../executor/task/WorkerConfiguration.java | 36 - .../sdk/workflow/task/InputParam.java | 26 - .../sdk/workflow/task/OutputParam.java | 24 - .../sdk/workflow/task/WorkerTask.java | 32 - .../sdk/workflow/utils/InputOutputGetter.java | 105 -- .../sdk/workflow/utils/MapBuilder.java | 39 - .../workflow/utils/ObjectMapperProvider.java | 40 - .../src/main/resources/test-server.properties | 5 - .../workflow/def/TaskConversionsTests.java | 533 ------- .../workflow/def/WorkflowCreationTests.java | 216 --- .../workflow/def/WorkflowDefTaskTests.java | 55 - .../sdk/workflow/def/WorkflowState.java | 36 - .../executor/task/AnnotatedWorkerTests.java | 343 ----- .../executor/task/TestWorkerConfig.java | 41 - .../sdk/workflow/testing/Task1Input.java | 41 - .../workflow/testing/TestWorkflowInput.java | 54 - .../testing/WorkflowTestFrameworkTests.java | 205 --- .../application-integrationtest.properties | 55 - java-sdk/src/test/resources/log4j2.xml | 31 - java-sdk/src/test/resources/script.js | 11 - .../src/test/resources/simple_workflow.json | 151 -- java-sdk/src/test/resources/tasks.json | 1252 ----------------- java-sdk/testing_framework.md | 74 - java-sdk/worker_sdk.md | 117 -- java-sdk/workflow_sdk.md | 122 -- settings.gradle | 1 - 66 files changed, 1 insertion(+), 8053 deletions(-) delete mode 100644 java-sdk/README.md delete mode 100644 java-sdk/build.gradle delete mode 100644 java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/Order.java delete mode 100644 java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/Shipment.java delete mode 100644 java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentState.java delete mode 100644 java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentWorkers.java delete mode 100644 java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentWorkflow.java delete mode 100644 java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/User.java delete mode 100644 java-sdk/example/resources/script.js delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/healthcheck/HealthCheckClient.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/testing/LocalServerRunner.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/testing/WorkflowTestRunner.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/ConductorWorkflow.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/ValidationError.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/WorkflowBuilder.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DoWhile.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Dynamic.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DynamicFork.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DynamicForkInput.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Event.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/ForkJoin.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Http.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/JQ.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Javascript.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Join.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SetVariable.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SimpleTask.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SubWorkflow.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Switch.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Task.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/TaskRegistry.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Terminate.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Wait.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/WorkflowExecutor.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorker.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorkerExecutor.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/DynamicForkWorker.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/NonRetryableException.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/TaskContext.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/WorkerConfiguration.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/InputParam.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/OutputParam.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/WorkerTask.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/InputOutputGetter.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/MapBuilder.java delete mode 100644 java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/ObjectMapperProvider.java delete mode 100644 java-sdk/src/main/resources/test-server.properties delete mode 100644 java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/TaskConversionsTests.java delete mode 100644 java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowCreationTests.java delete mode 100644 java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowDefTaskTests.java delete mode 100644 java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowState.java delete mode 100644 java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorkerTests.java delete mode 100644 java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/executor/task/TestWorkerConfig.java delete mode 100644 java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/Task1Input.java delete mode 100644 java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/TestWorkflowInput.java delete mode 100644 java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/WorkflowTestFrameworkTests.java delete mode 100644 java-sdk/src/test/resources/application-integrationtest.properties delete mode 100644 java-sdk/src/test/resources/log4j2.xml delete mode 100644 java-sdk/src/test/resources/script.js delete mode 100644 java-sdk/src/test/resources/simple_workflow.json delete mode 100644 java-sdk/src/test/resources/tasks.json delete mode 100644 java-sdk/testing_framework.md delete mode 100644 java-sdk/worker_sdk.md delete mode 100644 java-sdk/workflow_sdk.md diff --git a/build.gradle b/build.gradle index c6ffda75d..0671190c2 100644 --- a/build.gradle +++ b/build.gradle @@ -125,15 +125,6 @@ allprojects { } } -// all client and their related modules are published with Java 17 compatibility -["annotations", "common", "client", "client-spring", "grpc", "grpc-client"].each { - project(":conductor-$it") { - compileJava { - options.release = 17 - } - } -} - task server { dependsOn ':conductor-server:bootRun' } @@ -151,7 +142,7 @@ configure(allprojects - project(':conductor-grpc')) { } } -['cassandra-persistence', 'core', 'redis-concurrency-limit', 'test-harness', 'client'].each { +['cassandra-persistence', 'core', 'redis-concurrency-limit', 'test-harness'].each { configure(project(":conductor-$it")) { spotless { groovy { diff --git a/java-sdk/README.md b/java-sdk/README.md deleted file mode 100644 index 111470ec5..000000000 --- a/java-sdk/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# SDK for Conductor -Conductor SDK allows developers to create, test and execute workflows using code. - -There are three main features of the SDK: - -1. [Create and run workflows using code](workflow_sdk.md) -2. [Create and run strongly typed workers](worker_sdk.md) -3. [Unit Testing framework for workflows and workers](testing_framework.md) - - - diff --git a/java-sdk/build.gradle b/java-sdk/build.gradle deleted file mode 100644 index 91ce0f4cb..000000000 --- a/java-sdk/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -apply plugin: 'groovy' - -dependencies { - - implementation project(':conductor-common') - implementation project(':conductor-client') - - implementation "com.fasterxml.jackson.core:jackson-databind:${revFasterXml}" - implementation "com.google.guava:guava:${revGuava}" - implementation "cglib:cglib:3.3.0" - implementation "com.sun.jersey:jersey-client:${revJersey}" - implementation "javax.ws.rs:javax.ws.rs-api:${revJAXRS}" - implementation "org.glassfish.jersey.core:jersey-common:${revJerseyCommon}" - implementation "org.openjdk.nashorn:nashorn-core:15.4" - - testImplementation "org.springframework:spring-web" - testImplementation "org.spockframework:spock-core:${revSpock}" - testImplementation "org.spockframework:spock-spring:${revSpock}" - - testImplementation "com.fasterxml.jackson.core:jackson-core:${revFasterXml}" - testImplementation "org.apache.commons:commons-lang3" - - testImplementation "org.apache.groovy:groovy-all:${revGroovy}" - -} - -test { - testLogging { - exceptionFormat = 'full' - } -} -sourceSets.main.java.srcDirs += ['example/java', 'example/resources'] - diff --git a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/Order.java b/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/Order.java deleted file mode 100644 index 7d8a4829f..000000000 --- a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/Order.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.example.shipment; - -import java.math.BigDecimal; - -public class Order { - - public enum ShippingMethod { - GROUND, - NEXT_DAY_AIR, - SAME_DAY - } - - private String orderNumber; - - private String sku; - - private int quantity; - - private BigDecimal unitPrice; - - private String zipCode; - - private String countryCode; - - private ShippingMethod shippingMethod; - - public Order(String orderNumber, String sku, int quantity, BigDecimal unitPrice) { - this.orderNumber = orderNumber; - this.sku = sku; - this.quantity = quantity; - this.unitPrice = unitPrice; - } - - public Order() {} - - public String getOrderNumber() { - return orderNumber; - } - - public void setOrderNumber(String orderNumber) { - this.orderNumber = orderNumber; - } - - public String getSku() { - return sku; - } - - public void setSku(String sku) { - this.sku = sku; - } - - public int getQuantity() { - return quantity; - } - - public void setQuantity(int quantity) { - this.quantity = quantity; - } - - public BigDecimal getUnitPrice() { - return unitPrice; - } - - public void setUnitPrice(BigDecimal unitPrice) { - this.unitPrice = unitPrice; - } - - public String getZipCode() { - return zipCode; - } - - public void setZipCode(String zipCode) { - this.zipCode = zipCode; - } - - public String getCountryCode() { - return countryCode; - } - - public void setCountryCode(String countryCode) { - this.countryCode = countryCode; - } - - public ShippingMethod getShippingMethod() { - return shippingMethod; - } - - public void setShippingMethod(ShippingMethod shippingMethod) { - this.shippingMethod = shippingMethod; - } -} diff --git a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/Shipment.java b/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/Shipment.java deleted file mode 100644 index ba621a564..000000000 --- a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/Shipment.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.example.shipment; - -public class Shipment { - - private String userId; - - private String orderNo; - - public Shipment(String userId, String orderNo) { - this.userId = userId; - this.orderNo = orderNo; - } - - public Shipment() {} - - public String getUserId() { - return userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - public String getOrderNo() { - return orderNo; - } - - public void setOrderNo(String orderNo) { - this.orderNo = orderNo; - } -} diff --git a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentState.java b/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentState.java deleted file mode 100644 index d71f58436..000000000 --- a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentState.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.example.shipment; - -public class ShipmentState { - - private boolean paymentCompleted; - - private boolean emailSent; - - private boolean shipped; - - private String trackingNumber; - - public boolean isPaymentCompleted() { - return paymentCompleted; - } - - public void setPaymentCompleted(boolean paymentCompleted) { - this.paymentCompleted = paymentCompleted; - } - - public boolean isEmailSent() { - return emailSent; - } - - public void setEmailSent(boolean emailSent) { - this.emailSent = emailSent; - } - - public boolean isShipped() { - return shipped; - } - - public void setShipped(boolean shipped) { - this.shipped = shipped; - } - - public String getTrackingNumber() { - return trackingNumber; - } - - public void setTrackingNumber(String trackingNumber) { - this.trackingNumber = trackingNumber; - } -} diff --git a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentWorkers.java b/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentWorkers.java deleted file mode 100644 index 9698f1e08..000000000 --- a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentWorkers.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.example.shipment; - -import java.math.BigDecimal; -import java.util.*; - -import com.netflix.conductor.sdk.workflow.def.tasks.DynamicForkInput; -import com.netflix.conductor.sdk.workflow.def.tasks.SubWorkflow; -import com.netflix.conductor.sdk.workflow.def.tasks.Task; -import com.netflix.conductor.sdk.workflow.task.InputParam; -import com.netflix.conductor.sdk.workflow.task.OutputParam; -import com.netflix.conductor.sdk.workflow.task.WorkerTask; - -public class ShipmentWorkers { - - @WorkerTask(value = "generateDynamicFork", threadCount = 3) - public DynamicForkInput generateDynamicFork( - @InputParam("orderDetails") List orderDetails, - @InputParam("userDetails") User userDetails) { - DynamicForkInput input = new DynamicForkInput(); - List> tasks = new ArrayList<>(); - Map inputs = new HashMap<>(); - - for (int i = 0; i < orderDetails.size(); i++) { - Order detail = orderDetails.get(i); - String referenceName = "order_flow_sub_" + i; - tasks.add( - new SubWorkflow(referenceName, "order_flow", null) - .input("orderDetail", detail) - .input("userDetails", userDetails)); - inputs.put(referenceName, new HashMap<>()); - } - input.setInputs(inputs); - input.setTasks(tasks); - return input; - } - - @WorkerTask(value = "get_order_details", threadCount = 5) - public List getOrderDetails(@InputParam("orderNo") String orderNo) { - int lineItemCount = new Random().nextInt(10); - List orderDetails = new ArrayList<>(); - for (int i = 0; i < lineItemCount; i++) { - Order orderDetail = new Order(orderNo, "sku_" + i, 2, BigDecimal.valueOf(20.5)); - orderDetail.setOrderNumber(UUID.randomUUID().toString()); - orderDetail.setCountryCode(i % 2 == 0 ? "US" : "CA"); - if (i % 3 == 0) { - orderDetail.setCountryCode("UK"); - } - - if (orderDetail.getCountryCode().equals("US")) - orderDetail.setShippingMethod(Order.ShippingMethod.SAME_DAY); - else if (orderDetail.getCountryCode().equals("CA")) - orderDetail.setShippingMethod(Order.ShippingMethod.NEXT_DAY_AIR); - else orderDetail.setShippingMethod(Order.ShippingMethod.GROUND); - - orderDetails.add(orderDetail); - } - return orderDetails; - } - - @WorkerTask("get_user_details") - public User getUserDetails(@InputParam("userId") String userId) { - User user = - new User( - "User Name", - userId + "@example.com", - "1234 forline street", - "mountain view", - "95030", - "US", - "Paypal", - "biling_001"); - - return user; - } - - @WorkerTask("calculate_tax_and_total") - public @OutputParam("total_amount") BigDecimal calculateTax( - @InputParam("orderDetail") Order orderDetails) { - BigDecimal preTaxAmount = - orderDetails.getUnitPrice().multiply(new BigDecimal(orderDetails.getQuantity())); - BigDecimal tax = BigDecimal.valueOf(0.2).multiply(preTaxAmount); - if (!"US".equals(orderDetails.getCountryCode())) { - tax = BigDecimal.ZERO; - } - return preTaxAmount.add(tax); - } - - @WorkerTask("ground_shipping_label") - public @OutputParam("reference_number") String prepareGroundShipping( - @InputParam("name") String name, - @InputParam("address") String address, - @InputParam("orderNo") String orderNo) { - - return "Ground_" + orderNo; - } - - @WorkerTask("air_shipping_label") - public @OutputParam("reference_number") String prepareAirShipping( - @InputParam("name") String name, - @InputParam("address") String address, - @InputParam("orderNo") String orderNo) { - - return "Air_" + orderNo; - } - - @WorkerTask("same_day_shipping_label") - public @OutputParam("reference_number") String prepareSameDayShipping( - @InputParam("name") String name, - @InputParam("address") String address, - @InputParam("orderNo") String orderNo) { - - return "SameDay_" + orderNo; - } - - @WorkerTask("charge_payment") - public @OutputParam("reference") String chargePayment( - @InputParam("amount") BigDecimal amount, - @InputParam("billingId") String billingId, - @InputParam("billingType") String billingType) { - - return UUID.randomUUID().toString(); - } - - @WorkerTask("send_email") - public void sendEmail( - @InputParam("name") String name, - @InputParam("email") String email, - @InputParam("orderNo") String orderNo) {} -} diff --git a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentWorkflow.java b/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentWorkflow.java deleted file mode 100644 index 809dec6b3..000000000 --- a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/ShipmentWorkflow.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.example.shipment; - -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; - -import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; -import com.netflix.conductor.sdk.workflow.def.ConductorWorkflow; -import com.netflix.conductor.sdk.workflow.def.WorkflowBuilder; -import com.netflix.conductor.sdk.workflow.def.tasks.*; -import com.netflix.conductor.sdk.workflow.executor.WorkflowExecutor; - -public class ShipmentWorkflow { - - private final WorkflowExecutor executor; - - public ShipmentWorkflow(WorkflowExecutor executor) { - this.executor = executor; - this.executor.initWorkers(ShipmentWorkflow.class.getPackageName()); - } - - public ConductorWorkflow createOrderFlow() { - WorkflowBuilder builder = new WorkflowBuilder<>(executor); - builder.name("order_flow") - .version(1) - .ownerEmail("user@example.com") - .timeoutPolicy(WorkflowDef.TimeoutPolicy.TIME_OUT_WF, 60) // 1 day max - .description("Workflow to track shipment") - .add( - new SimpleTask("calculate_tax_and_total", "calculate_tax_and_total") - .input("orderDetail", ConductorWorkflow.input.get("orderDetail"))) - .add( - new SimpleTask("charge_payment", "charge_payment") - .input( - "billingId", - ConductorWorkflow.input - .map("userDetails") - .get("billingId"), - "billingType", - ConductorWorkflow.input - .map("userDetails") - .get("billingType"), - "amount", "${calculate_tax_and_total.output.total_amount}")) - .add( - new Switch("shipping_label", "${workflow.input.orderDetail.shippingMethod}") - .switchCase( - Order.ShippingMethod.GROUND.toString(), - new SimpleTask( - "ground_shipping_label", - "ground_shipping_label") - .input( - "name", - ConductorWorkflow.input - .map("userDetails") - .get("name"), - "address", - ConductorWorkflow.input - .map("userDetails") - .get("addressLine"), - "orderNo", - ConductorWorkflow.input - .map("orderDetail") - .get("orderNumber"))) - .switchCase( - Order.ShippingMethod.NEXT_DAY_AIR.toString(), - new SimpleTask("air_shipping_label", "air_shipping_label") - .input( - "name", - ConductorWorkflow.input - .map("userDetails") - .get("name"), - "address", - ConductorWorkflow.input - .map("userDetails") - .get("addressLine"), - "orderNo", - ConductorWorkflow.input - .map("orderDetail") - .get("orderNumber"))) - .switchCase( - Order.ShippingMethod.SAME_DAY.toString(), - new SimpleTask( - "same_day_shipping_label", - "same_day_shipping_label") - .input( - "name", - ConductorWorkflow.input - .map("userDetails") - .get("name"), - "address", - ConductorWorkflow.input - .map("userDetails") - .get("addressLine"), - "orderNo", - ConductorWorkflow.input - .map("orderDetail") - .get("orderNumber"))) - .defaultCase( - new Terminate( - "unsupported_shipping_type", - Workflow.WorkflowStatus.FAILED, - "Unsupported Shipping Method"))) - .add( - new SimpleTask("send_email", "send_email") - .input( - "name", - ConductorWorkflow.input - .map("userDetails") - .get("name"), - "email", - ConductorWorkflow.input - .map("userDetails") - .get("email"), - "orderNo", - ConductorWorkflow.input - .map("orderDetail") - .get("orderNumber"))); - ConductorWorkflow conductorWorkflow = builder.build(); - conductorWorkflow.registerWorkflow(true, true); - return conductorWorkflow; - } - - public ConductorWorkflow createShipmentWorkflow() { - - WorkflowBuilder builder = new WorkflowBuilder<>(executor); - - SimpleTask getOrderDetails = - new SimpleTask("get_order_details", "get_order_details") - .input("orderNo", ConductorWorkflow.input.get("orderNo")); - - SimpleTask getUserDetails = - new SimpleTask("get_user_details", "get_user_details") - .input("userId", ConductorWorkflow.input.get("userId")); - - ConductorWorkflow conductorWorkflow = - builder.name("shipment_workflow") - .version(1) - .ownerEmail("user@example.com") - .variables(new ShipmentState()) - .timeoutPolicy(WorkflowDef.TimeoutPolicy.TIME_OUT_WF, 60) // 30 days - .description("Workflow to track shipment") - .add( - new ForkJoin( - "get_in_parallel", - new Task[] {getOrderDetails}, - new Task[] {getUserDetails})) - - // For all the line items in the order, run in parallel: - // (calculate tax, charge payment, set state, prepare shipment, send - // shipment, set state) - .add( - new DynamicFork( - "process_order", - new SimpleTask("generateDynamicFork", "generateDynamicFork") - .input( - "orderDetails", - getOrderDetails.taskOutput.get("result")) - .input("userDetails", getUserDetails.taskOutput))) - - // Update the workflow state with shipped = true - .add(new SetVariable("update_state").input("shipped", true)) - .build(); - - conductorWorkflow.registerWorkflow(true, true); - - return conductorWorkflow; - } - - public static void main(String[] args) { - - String conductorServerURL = - "http://localhost:8080/api/"; // Change this to your Conductor server - WorkflowExecutor executor = new WorkflowExecutor(conductorServerURL); - - // Create the new shipment workflow - ShipmentWorkflow shipmentWorkflow = new ShipmentWorkflow(executor); - - // Create two workflows - - // 1. Order flow that ships an individual order - // 2. Shipment Workflow that tracks multiple orders in a shipment - shipmentWorkflow.createOrderFlow(); - ConductorWorkflow workflow = shipmentWorkflow.createShipmentWorkflow(); - - // Execute the workflow and wait for it to complete - try { - Shipment workflowInput = new Shipment("userA", "order123"); - - // Execute returns a completable future. - CompletableFuture executionFuture = workflow.execute(workflowInput); - - // Wait for a maximum of a minute for the workflow to complete. - Workflow run = executionFuture.get(1, TimeUnit.MINUTES); - - System.out.println("Workflow Id: " + run); - System.out.println("Workflow Status: " + run.getStatus()); - System.out.println("Workflow Output: " + run.getOutput()); - - } catch (Exception e) { - e.printStackTrace(); - } finally { - System.exit(0); - } - - System.out.println("Done"); - } -} diff --git a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/User.java b/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/User.java deleted file mode 100644 index 0c8324a93..000000000 --- a/java-sdk/example/java/com/netflix/conductor/sdk/example/shipment/User.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.example.shipment; - -public class User { - - private String name; - - private String email; - - private String addressLine; - - private String city; - - private String zipCode; - - private String countryCode; - - private String billingType; - - private String billingId; - - public User( - String name, - String email, - String addressLine, - String city, - String zipCode, - String countryCode, - String billingType, - String billingId) { - this.name = name; - this.email = email; - this.addressLine = addressLine; - this.city = city; - this.zipCode = zipCode; - this.countryCode = countryCode; - this.billingType = billingType; - this.billingId = billingId; - } - - public User() {} - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getAddressLine() { - return addressLine; - } - - public void setAddressLine(String addressLine) { - this.addressLine = addressLine; - } - - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getZipCode() { - return zipCode; - } - - public void setZipCode(String zipCode) { - this.zipCode = zipCode; - } - - public String getCountryCode() { - return countryCode; - } - - public void setCountryCode(String countryCode) { - this.countryCode = countryCode; - } - - public String getBillingType() { - return billingType; - } - - public void setBillingType(String billingType) { - this.billingType = billingType; - } - - public String getBillingId() { - return billingId; - } - - public void setBillingId(String billingId) { - this.billingId = billingId; - } -} diff --git a/java-sdk/example/resources/script.js b/java-sdk/example/resources/script.js deleted file mode 100644 index af6d42c43..000000000 --- a/java-sdk/example/resources/script.js +++ /dev/null @@ -1,11 +0,0 @@ -function e() { - if ($.value > 1){ - return { - "key": "value", - "key2": 42 - }; - } else { - return {}; - } -} -e(); \ No newline at end of file diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/healthcheck/HealthCheckClient.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/healthcheck/HealthCheckClient.java deleted file mode 100644 index 014ab1d80..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/healthcheck/HealthCheckClient.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.healthcheck; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.URL; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; - -public class HealthCheckClient { - - private final String healthCheckURL; - - private final ObjectMapper objectMapper; - - public HealthCheckClient(String healthCheckURL) { - this.healthCheckURL = healthCheckURL; - this.objectMapper = - new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } - - public boolean isServerRunning() { - try { - - BufferedReader in = - new BufferedReader(new InputStreamReader(new URL(healthCheckURL).openStream())); - StringBuilder response = new StringBuilder(); - String inputLine; - while ((inputLine = in.readLine()) != null) { - response.append(inputLine); - } - in.close(); - HealthCheckResults healthCheckResults = - objectMapper.readValue(response.toString(), HealthCheckResults.class); - return healthCheckResults.healthy; - } catch (Throwable t) { - return false; - } - } - - private static final class HealthCheckResults { - - private boolean healthy; - - public boolean isHealthy() { - return healthy; - } - - public void setHealthy(boolean healthy) { - this.healthy = healthy; - } - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/testing/LocalServerRunner.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/testing/LocalServerRunner.java deleted file mode 100644 index 5bf2bb5fe..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/testing/LocalServerRunner.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.testing; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.conductor.sdk.healthcheck.HealthCheckClient; - -import com.google.common.util.concurrent.Uninterruptibles; - -public class LocalServerRunner { - - private static final Logger LOGGER = LoggerFactory.getLogger(LocalServerRunner.class); - - private final HealthCheckClient healthCheck; - - private Process serverProcess; - - private final ScheduledExecutorService healthCheckExecutor = - Executors.newSingleThreadScheduledExecutor(); - - private final CountDownLatch serverProcessLatch = new CountDownLatch(1); - - private final int port; - - private final String conductorVersion; - - private final String serverURL; - - private static Map serverInstances = new HashMap<>(); - - public LocalServerRunner(int port, String conductorVersion) { - this.port = port; - this.conductorVersion = conductorVersion; - this.serverURL = "http://localhost:" + port + "/"; - healthCheck = new HealthCheckClient(serverURL + "health"); - } - - public String getServerAPIUrl() { - return this.serverURL + "api/"; - } - - /** - * Starts the local server. Downloads the latest conductor build from the maven repo If you want - * to start the server from a specific download location, set `repositoryURL` system property - * with the link to the actual downloadable server boot jar file. - * - *

System Properties that can be set conductorVersion: when specified, uses this - * version of conductor to run tests (and downloads from maven repo) repositoryURL: full url - * where the server boot jar can be downloaded from. This can be a public repo or internal - * repository, allowing full control over the location and version of the conductor server - */ - public void startLocalServer() { - synchronized (serverInstances) { - if (serverInstances.get(port) != null) { - throw new IllegalStateException( - "Another server has already been started at port " + port); - } - serverInstances.put(port, this); - } - - try { - String downloadURL = - "https://repo1.maven.org/maven2/com/netflix/conductor/conductor-server/" - + conductorVersion - + "/conductor-server-" - + conductorVersion - + "-boot.jar"; - - String repositoryURL = - Optional.ofNullable(System.getProperty("repositoryURL")).orElse(downloadURL); - - LOGGER.info( - "Running conductor with version {} from repo url {}", - conductorVersion, - repositoryURL); - - Runtime.getRuntime().addShutdownHook(new Thread(this::shutdown)); - installAndStartServer(repositoryURL, port); - healthCheckExecutor.scheduleAtFixedRate( - () -> { - try { - if (serverProcessLatch.getCount() > 0) { - boolean isRunning = healthCheck.isServerRunning(); - if (isRunning) { - serverProcessLatch.countDown(); - } - } - } catch (Exception e) { - LOGGER.warn( - "Caught an exception while polling for server running status {}", - e.getMessage()); - } - }, - 100, - 100, - TimeUnit.MILLISECONDS); - Uninterruptibles.awaitUninterruptibly(serverProcessLatch, 1, TimeUnit.MINUTES); - - if (serverProcessLatch.getCount() > 0) { - throw new RuntimeException("Server not healthy"); - } - healthCheckExecutor.shutdownNow(); - - } catch (IOException e) { - throw new Error(e); - } - } - - public void shutdown() { - if (serverProcess != null) { - serverProcess.destroyForcibly(); - serverInstances.remove(port); - } - } - - private synchronized void installAndStartServer(String repositoryURL, int localServerPort) - throws IOException { - if (serverProcess != null) { - return; - } - - String configFile = - LocalServerRunner.class.getResource("/test-server.properties").getFile(); - String tempDir = System.getProperty("java.io.tmpdir"); - Path serverFile = Paths.get(tempDir, "conductor-server.jar"); - if (!Files.exists(serverFile)) { - Files.copy(new URL(repositoryURL).openStream(), serverFile); - } - - String command = - "java -Dserver.port=" - + localServerPort - + " -DCONDUCTOR_CONFIG_FILE=" - + configFile - + " -jar " - + serverFile; - LOGGER.info("Running command {}", command); - - serverProcess = Runtime.getRuntime().exec(new String[] {"bash", "-l", "-c", command}); - BufferedReader error = - new BufferedReader(new InputStreamReader(serverProcess.getErrorStream())); - BufferedReader op = - new BufferedReader(new InputStreamReader(serverProcess.getInputStream())); - - // This captures the stream and copies to a visible log for tracking errors asynchronously - // using a separate thread - Executors.newSingleThreadScheduledExecutor() - .execute( - () -> { - String line = null; - while (true) { - try { - if ((line = error.readLine()) == null) break; - } catch (IOException e) { - LOGGER.error("Exception reading input stream:", e); - } - // copy to standard error - LOGGER.error("Server error stream - {}", line); - } - }); - - // This captures the stream and copies to a visible log for tracking errors asynchronously - // using a separate thread - Executors.newSingleThreadScheduledExecutor() - .execute( - () -> { - String line = null; - while (true) { - try { - if ((line = op.readLine()) == null) break; - } catch (IOException e) { - LOGGER.error("Exception reading input stream:", e); - } - // copy to standard out - LOGGER.trace("Server input stream - {}", line); - } - }); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/testing/WorkflowTestRunner.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/testing/WorkflowTestRunner.java deleted file mode 100644 index 398d5c29f..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/testing/WorkflowTestRunner.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.testing; - -import com.netflix.conductor.client.http.TaskClient; -import com.netflix.conductor.sdk.workflow.executor.WorkflowExecutor; -import com.netflix.conductor.sdk.workflow.executor.task.AnnotatedWorkerExecutor; - -public class WorkflowTestRunner { - - private LocalServerRunner localServerRunner; - - private final AnnotatedWorkerExecutor annotatedWorkerExecutor; - - private final WorkflowExecutor workflowExecutor; - - public WorkflowTestRunner(String serverApiUrl) { - - TaskClient taskClient = new TaskClient(); - taskClient.setRootURI(serverApiUrl); - this.annotatedWorkerExecutor = new AnnotatedWorkerExecutor(taskClient); - - this.workflowExecutor = new WorkflowExecutor(serverApiUrl); - } - - public WorkflowTestRunner(int port, String conductorVersion) { - - localServerRunner = new LocalServerRunner(port, conductorVersion); - - TaskClient taskClient = new TaskClient(); - taskClient.setRootURI(localServerRunner.getServerAPIUrl()); - this.annotatedWorkerExecutor = new AnnotatedWorkerExecutor(taskClient); - - this.workflowExecutor = new WorkflowExecutor(localServerRunner.getServerAPIUrl()); - } - - public WorkflowExecutor getWorkflowExecutor() { - return workflowExecutor; - } - - public void init(String basePackages) { - if (localServerRunner != null) { - localServerRunner.startLocalServer(); - } - annotatedWorkerExecutor.initWorkers(basePackages); - } - - public void shutdown() { - localServerRunner.shutdown(); - annotatedWorkerExecutor.shutdown(); - workflowExecutor.shutdown(); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/ConductorWorkflow.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/ConductorWorkflow.java deleted file mode 100644 index d3bc031ca..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/ConductorWorkflow.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def; - -import java.util.*; -import java.util.concurrent.CompletableFuture; - -import com.netflix.conductor.client.exception.ConductorClientException; -import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; -import com.netflix.conductor.sdk.workflow.def.tasks.Task; -import com.netflix.conductor.sdk.workflow.def.tasks.TaskRegistry; -import com.netflix.conductor.sdk.workflow.executor.WorkflowExecutor; -import com.netflix.conductor.sdk.workflow.utils.InputOutputGetter; -import com.netflix.conductor.sdk.workflow.utils.ObjectMapperProvider; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * @param Type of the workflow input - */ -public class ConductorWorkflow { - - public static final InputOutputGetter input = - new InputOutputGetter("workflow", InputOutputGetter.Field.input); - - public static final InputOutputGetter output = - new InputOutputGetter("workflow", InputOutputGetter.Field.output); - - private String name; - - private String description; - - private int version; - - private String failureWorkflow; - - private String ownerEmail; - - private WorkflowDef.TimeoutPolicy timeoutPolicy; - - private Map workflowOutput; - - private long timeoutSeconds; - - private boolean restartable = true; - - private T defaultInput; - - private Map variables; - - private List tasks = new ArrayList<>(); - - private final ObjectMapper objectMapper = new ObjectMapperProvider().getObjectMapper(); - - private final WorkflowExecutor workflowExecutor; - - public ConductorWorkflow(WorkflowExecutor workflowExecutor) { - this.workflowOutput = new HashMap<>(); - this.workflowExecutor = workflowExecutor; - this.restartable = true; - } - - public void setName(String name) { - this.name = name; - } - - public void setVersion(int version) { - this.version = version; - } - - public void setDescription(String description) { - this.description = description; - } - - public void setFailureWorkflow(String failureWorkflow) { - this.failureWorkflow = failureWorkflow; - } - - public void add(Task task) { - this.tasks.add(task); - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public int getVersion() { - return version; - } - - public String getFailureWorkflow() { - return failureWorkflow; - } - - public String getOwnerEmail() { - return ownerEmail; - } - - public void setOwnerEmail(String ownerEmail) { - this.ownerEmail = ownerEmail; - } - - public WorkflowDef.TimeoutPolicy getTimeoutPolicy() { - return timeoutPolicy; - } - - public void setTimeoutPolicy(WorkflowDef.TimeoutPolicy timeoutPolicy) { - this.timeoutPolicy = timeoutPolicy; - } - - public long getTimeoutSeconds() { - return timeoutSeconds; - } - - public void setTimeoutSeconds(long timeoutSeconds) { - this.timeoutSeconds = timeoutSeconds; - } - - public boolean isRestartable() { - return restartable; - } - - public void setRestartable(boolean restartable) { - this.restartable = restartable; - } - - public T getDefaultInput() { - return defaultInput; - } - - public void setDefaultInput(T defaultInput) { - this.defaultInput = defaultInput; - } - - public Map getWorkflowOutput() { - return workflowOutput; - } - - public void setWorkflowOutput(Map workflowOutput) { - this.workflowOutput = workflowOutput; - } - - public Object getVariables() { - return variables; - } - - public void setVariables(Map variables) { - this.variables = variables; - } - - /** - * Execute a dynamic workflow without creating a definition in metadata store. - * - *


- * Note: Use this with caution - as this does not promote re-usability of the workflows - * - * @param input Workflow Input - The input object is converted a JSON doc as an input to the - * workflow - * @return - */ - public CompletableFuture executeDynamic(T input) { - return workflowExecutor.executeWorkflow(this, input); - } - - /** - * Executes the workflow using registered metadata definitions - * - * @see #registerWorkflow() - * @param input - * @return - */ - public CompletableFuture execute(T input) { - return workflowExecutor.executeWorkflow(this.getName(), this.getVersion(), input); - } - - /** - * Registers a new workflow in the server. - * - * @return true if the workflow is successfully registered. False if the workflow cannot be - * registered and the workflow definition already exists on the server with given name + - * version The call will throw a runtime exception if any of the tasks are missing - * definitions on the server. - */ - public boolean registerWorkflow() { - return registerWorkflow(false, false); - } - - /** - * @param overwrite set to true if the workflow should be overwritten if the definition already - * exists with the given name and version. Use with caution - * @return true if success, false otherwise. - */ - public boolean registerWorkflow(boolean overwrite) { - return registerWorkflow(overwrite, false); - } - - /** - * @param overwrite set to true if the workflow should be overwritten if the definition already - * exists with the given name and version. Use with caution - * @param registerTasks if set to true, missing task definitions are registered with the default - * configuration. - * @return true if success, false otherwise. - */ - public boolean registerWorkflow(boolean overwrite, boolean registerTasks) { - WorkflowDef workflowDef = toWorkflowDef(); - List missing = getMissingTasks(workflowDef); - if (!missing.isEmpty()) { - if (!registerTasks) { - throw new RuntimeException( - "Workflow cannot be registered. The following tasks do not have definitions. " - + "Please register these tasks before creating the workflow. Missing Tasks = " - + missing); - } else { - String ownerEmail = this.ownerEmail; - missing.stream().forEach(taskName -> registerTaskDef(taskName, ownerEmail)); - } - } - return workflowExecutor.registerWorkflow(workflowDef, overwrite); - } - - /** - * @return Convert to the WorkflowDef model used by the Metadata APIs - */ - public WorkflowDef toWorkflowDef() { - - WorkflowDef def = new WorkflowDef(); - def.setName(name); - def.setDescription(description); - def.setVersion(version); - def.setFailureWorkflow(failureWorkflow); - def.setOwnerEmail(ownerEmail); - def.setTimeoutPolicy(timeoutPolicy); - def.setTimeoutSeconds(timeoutSeconds); - def.setRestartable(restartable); - def.setOutputParameters(workflowOutput); - def.setVariables(variables); - def.setInputTemplate(objectMapper.convertValue(defaultInput, Map.class)); - - for (Task task : tasks) { - def.getTasks().addAll(task.getWorkflowDefTasks()); - } - return def; - } - - /** - * Generate ConductorWorkflow based on the workflow metadata definition - * - * @param def - * @return - */ - public static ConductorWorkflow fromWorkflowDef(WorkflowDef def) { - ConductorWorkflow workflow = new ConductorWorkflow<>(null); - fromWorkflowDef(workflow, def); - return workflow; - } - - public ConductorWorkflow from(String workflowName, Integer workflowVersion) { - WorkflowDef def = - workflowExecutor.getMetadataClient().getWorkflowDef(workflowName, workflowVersion); - fromWorkflowDef(this, def); - return this; - } - - private static void fromWorkflowDef(ConductorWorkflow workflow, WorkflowDef def) { - workflow.setName(def.getName()); - workflow.setVersion(def.getVersion()); - workflow.setFailureWorkflow(def.getFailureWorkflow()); - workflow.setRestartable(def.isRestartable()); - workflow.setVariables(def.getVariables()); - workflow.setDefaultInput((T) def.getInputTemplate()); - - workflow.setWorkflowOutput(def.getOutputParameters()); - workflow.setOwnerEmail(def.getOwnerEmail()); - workflow.setDescription(def.getDescription()); - workflow.setTimeoutSeconds(def.getTimeoutSeconds()); - workflow.setTimeoutPolicy(def.getTimeoutPolicy()); - - List workflowTasks = def.getTasks(); - for (WorkflowTask workflowTask : workflowTasks) { - Task task = TaskRegistry.getTask(workflowTask); - workflow.tasks.add(task); - } - } - - private List getMissingTasks(WorkflowDef workflowDef) { - List missing = new ArrayList<>(); - workflowDef.collectTasks().stream() - .filter(workflowTask -> workflowTask.getType().equals(TaskType.TASK_TYPE_SIMPLE)) - .map(WorkflowTask::getName) - .distinct() - .parallel() - .forEach( - taskName -> { - try { - TaskDef taskDef = - workflowExecutor.getMetadataClient().getTaskDef(taskName); - } catch (ConductorClientException cce) { - if (cce.getStatus() == 404) { - missing.add(taskName); - } else { - throw cce; - } - } - }); - return missing; - } - - private void registerTaskDef(String taskName, String ownerEmail) { - TaskDef taskDef = new TaskDef(); - taskDef.setName(taskName); - taskDef.setOwnerEmail(ownerEmail); - workflowExecutor.getMetadataClient().registerTaskDefs(Arrays.asList(taskDef)); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ConductorWorkflow workflow = (ConductorWorkflow) o; - return version == workflow.version && Objects.equals(name, workflow.name); - } - - @Override - public int hashCode() { - return Objects.hash(name, version); - } - - @Override - public String toString() { - try { - return objectMapper.writeValueAsString(toWorkflowDef()); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/ValidationError.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/ValidationError.java deleted file mode 100644 index f795ab5f9..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/ValidationError.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def; - -public class ValidationError extends RuntimeException { - - public ValidationError(String message) { - super(message); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/WorkflowBuilder.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/WorkflowBuilder.java deleted file mode 100644 index 2e90f7aa6..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/WorkflowBuilder.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def; - -import java.util.*; - -import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.sdk.workflow.def.tasks.*; -import com.netflix.conductor.sdk.workflow.executor.WorkflowExecutor; -import com.netflix.conductor.sdk.workflow.utils.InputOutputGetter; -import com.netflix.conductor.sdk.workflow.utils.MapBuilder; -import com.netflix.conductor.sdk.workflow.utils.ObjectMapperProvider; - -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * @param Input type for the workflow - */ -public class WorkflowBuilder { - - private String name; - - private String description; - - private int version; - - private String failureWorkflow; - - private String ownerEmail; - - private WorkflowDef.TimeoutPolicy timeoutPolicy; - - private long timeoutSeconds; - - private boolean restartable = true; - - private T defaultInput; - - private Map output = new HashMap<>(); - - private Map state; - - protected List> tasks = new ArrayList<>(); - - private WorkflowExecutor workflowExecutor; - - public final InputOutputGetter input = - new InputOutputGetter("workflow", InputOutputGetter.Field.input); - - private final ObjectMapper objectMapper = new ObjectMapperProvider().getObjectMapper(); - - public WorkflowBuilder(WorkflowExecutor workflowExecutor) { - this.workflowExecutor = workflowExecutor; - this.tasks = new ArrayList<>(); - } - - public WorkflowBuilder name(String name) { - this.name = name; - return this; - } - - public WorkflowBuilder version(int version) { - this.version = version; - return this; - } - - public WorkflowBuilder description(String description) { - this.description = description; - return this; - } - - public WorkflowBuilder failureWorkflow(String failureWorkflow) { - this.failureWorkflow = failureWorkflow; - return this; - } - - public WorkflowBuilder ownerEmail(String ownerEmail) { - this.ownerEmail = ownerEmail; - return this; - } - - public WorkflowBuilder timeoutPolicy( - WorkflowDef.TimeoutPolicy timeoutPolicy, long timeoutSeconds) { - this.timeoutPolicy = timeoutPolicy; - this.timeoutSeconds = timeoutSeconds; - return this; - } - - public WorkflowBuilder add(Task... tasks) { - Collections.addAll(this.tasks, tasks); - return this; - } - - public WorkflowBuilder defaultInput(T defaultInput) { - this.defaultInput = defaultInput; - return this; - } - - public WorkflowBuilder restartable(boolean restartable) { - this.restartable = restartable; - return this; - } - - public WorkflowBuilder variables(Object variables) { - try { - this.state = objectMapper.convertValue(variables, Map.class); - } catch (Exception e) { - throw new IllegalArgumentException( - "Workflow Variables cannot be converted to Map. Supplied: " - + variables.getClass().getName()); - } - return this; - } - - public WorkflowBuilder output(String key, boolean value) { - output.put(key, value); - return this; - } - - public WorkflowBuilder output(String key, String value) { - output.put(key, value); - return this; - } - - public WorkflowBuilder output(String key, Number value) { - output.put(key, value); - return this; - } - - public WorkflowBuilder output(String key, Object value) { - output.put(key, value); - return this; - } - - public WorkflowBuilder output(MapBuilder mapBuilder) { - output.putAll(mapBuilder.build()); - return this; - } - - public ConductorWorkflow build() throws ValidationError { - - validate(); - - ConductorWorkflow workflow = new ConductorWorkflow(workflowExecutor); - if (description != null) { - workflow.setDescription(description); - } - - workflow.setName(name); - workflow.setVersion(version); - workflow.setDescription(description); - workflow.setFailureWorkflow(failureWorkflow); - workflow.setOwnerEmail(ownerEmail); - workflow.setTimeoutPolicy(timeoutPolicy); - workflow.setTimeoutSeconds(timeoutSeconds); - workflow.setRestartable(restartable); - workflow.setDefaultInput(defaultInput); - workflow.setWorkflowOutput(output); - workflow.setVariables(state); - - for (Task task : tasks) { - workflow.add(task); - } - - return workflow; - } - - /** - * Validate: 1. There are no tasks with duplicate reference names 2. Each of the task is - * consistent with its definition 3. - */ - private void validate() throws ValidationError { - - List allTasks = new ArrayList<>(); - for (Task task : tasks) { - List workflowDefTasks = task.getWorkflowDefTasks(); - for (WorkflowTask workflowDefTask : workflowDefTasks) { - allTasks.addAll(workflowDefTask.collectTasks()); - } - } - - Map taskMap = new HashMap<>(); - Set duplicateTasks = new HashSet<>(); - for (WorkflowTask task : allTasks) { - if (taskMap.containsKey(task.getTaskReferenceName())) { - duplicateTasks.add(task.getTaskReferenceName()); - } else { - taskMap.put(task.getTaskReferenceName(), task); - } - } - if (!duplicateTasks.isEmpty()) { - throw new ValidationError( - "Task Reference Names MUST be unique across all the tasks in the workkflow. " - + "Please update/change reference names to be unique for the following tasks: " - + duplicateTasks); - } - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DoWhile.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DoWhile.java deleted file mode 100644 index 6d616542e..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DoWhile.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -public class DoWhile extends Task { - - private String loopCondition; - - private List> loopTasks = new ArrayList<>(); - - /** - * Execute tasks in a loop determined by the condition set using condition parameter. The loop - * will continue till the condition is true - * - * @param taskReferenceName - * @param condition Javascript that evaluates to a boolean value - * @param tasks - */ - public DoWhile(String taskReferenceName, String condition, Task... tasks) { - super(taskReferenceName, TaskType.DO_WHILE); - Collections.addAll(this.loopTasks, tasks); - this.loopCondition = condition; - } - - /** - * Similar to a for loop, run tasks for N times - * - * @param taskReferenceName - * @param loopCount - * @param tasks - */ - public DoWhile(String taskReferenceName, int loopCount, Task... tasks) { - super(taskReferenceName, TaskType.DO_WHILE); - Collections.addAll(this.loopTasks, tasks); - this.loopCondition = getForLoopCondition(loopCount); - } - - DoWhile(WorkflowTask workflowTask) { - super(workflowTask); - this.loopCondition = workflowTask.getLoopCondition(); - for (WorkflowTask task : workflowTask.getLoopOver()) { - Task loopTask = TaskRegistry.getTask(task); - this.loopTasks.add(loopTask); - } - } - - public DoWhile loopOver(Task... tasks) { - for (Task task : tasks) { - this.loopTasks.add(task); - } - return this; - } - - private String getForLoopCondition(int loopCount) { - return "if ( $." - + getTaskReferenceName() - + "['iteration'] < " - + loopCount - + ") { true; } else { false; }"; - } - - public String getLoopCondition() { - return loopCondition; - } - - public List getLoopTasks() { - return loopTasks; - } - - @Override - public void updateWorkflowTask(WorkflowTask workflowTask) { - workflowTask.setLoopCondition(loopCondition); - - List loopWorkflowTasks = new ArrayList<>(); - for (Task task : this.loopTasks) { - loopWorkflowTasks.addAll(task.getWorkflowDefTasks()); - } - workflowTask.setLoopOver(loopWorkflowTasks); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Dynamic.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Dynamic.java deleted file mode 100644 index 9ad9b3593..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Dynamic.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -import com.google.common.base.Strings; - -/** Wait task */ -public class Dynamic extends Task { - - public static final String TASK_NAME_INPUT_PARAM = "taskToExecute"; - - public Dynamic(String taskReferenceName, String dynamicTaskNameValue) { - super(taskReferenceName, TaskType.DYNAMIC); - if (Strings.isNullOrEmpty(dynamicTaskNameValue)) { - throw new AssertionError("Null/Empty dynamicTaskNameValue"); - } - super.input(TASK_NAME_INPUT_PARAM, dynamicTaskNameValue); - } - - Dynamic(WorkflowTask workflowTask) { - super(workflowTask); - } - - @Override - public void updateWorkflowTask(WorkflowTask task) { - task.setDynamicTaskNameParam(TASK_NAME_INPUT_PARAM); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DynamicFork.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DynamicFork.java deleted file mode 100644 index e3ae4f182..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DynamicFork.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -public class DynamicFork extends Task { - - public static final String FORK_TASK_PARAM = "forkedTasks"; - - public static final String FORK_TASK_INPUT_PARAM = "forkedTasksInputs"; - - private String forkTasksParameter; - - private String forkTasksInputsParameter; - - private Join join; - - private SimpleTask forkPrepareTask; - - /** - * Dynamic fork task that executes a set of tasks in parallel which are determined at run time. - * Use cases: Based on the input, you want to fork N number of processes in parallel to be - * executed. The number N is not pre-determined at the definition time and so a regular ForkJoin - * cannot be used. - * - * @param taskReferenceName - */ - public DynamicFork( - String taskReferenceName, String forkTasksParameter, String forkTasksInputsParameter) { - super(taskReferenceName, TaskType.FORK_JOIN_DYNAMIC); - this.join = new Join(taskReferenceName + "_join"); - this.forkTasksParameter = forkTasksParameter; - this.forkTasksInputsParameter = forkTasksInputsParameter; - super.input(FORK_TASK_PARAM, forkTasksParameter); - super.input(FORK_TASK_INPUT_PARAM, forkTasksInputsParameter); - } - - /** - * Dynamic fork task that executes a set of tasks in parallel which are determined at run time. - * Use cases: Based on the input, you want to fork N number of processes in parallel to be - * executed. The number N is not pre-determined at the definition time and so a regular ForkJoin - * cannot be used. - * - * @param taskReferenceName - * @param forkPrepareTask A Task that produces the output as {@link DynamicForkInput} to specify - * which tasks to fork. - */ - public DynamicFork(String taskReferenceName, SimpleTask forkPrepareTask) { - super(taskReferenceName, TaskType.FORK_JOIN_DYNAMIC); - this.forkPrepareTask = forkPrepareTask; - this.join = new Join(taskReferenceName + "_join"); - this.forkTasksParameter = forkPrepareTask.taskOutput.get(FORK_TASK_PARAM); - this.forkTasksInputsParameter = forkPrepareTask.taskOutput.get(FORK_TASK_INPUT_PARAM); - super.input(FORK_TASK_PARAM, forkTasksParameter); - super.input(FORK_TASK_INPUT_PARAM, forkTasksInputsParameter); - } - - DynamicFork(WorkflowTask workflowTask) { - super(workflowTask); - String nameOfParamForForkTask = workflowTask.getDynamicForkTasksParam(); - String nameOfParamForForkTaskInput = workflowTask.getDynamicForkTasksInputParamName(); - this.forkTasksParameter = - (String) workflowTask.getInputParameters().get(nameOfParamForForkTask); - this.forkTasksInputsParameter = - (String) workflowTask.getInputParameters().get(nameOfParamForForkTaskInput); - } - - public Join getJoin() { - return join; - } - - public String getForkTasksParameter() { - return forkTasksParameter; - } - - public String getForkTasksInputsParameter() { - return forkTasksInputsParameter; - } - - @Override - public void updateWorkflowTask(WorkflowTask task) { - task.setDynamicForkTasksParam("forkedTasks"); - task.setDynamicForkTasksInputParamName("forkedTasksInputs"); - } - - @Override - protected List getChildrenTasks() { - List tasks = new ArrayList<>(); - tasks.addAll(join.getWorkflowDefTasks()); - return tasks; - } - - @Override - protected List getParentTasks() { - if (forkPrepareTask != null) { - return List.of(forkPrepareTask.toWorkflowTask()); - } - return List.of(); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DynamicForkInput.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DynamicForkInput.java deleted file mode 100644 index d715f82f9..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DynamicForkInput.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.List; -import java.util.Map; - -public class DynamicForkInput { - - /** List of tasks to execute in parallel */ - private List> tasks; - - /** - * Input to the tasks. Key is the reference name of the task and value is an Object that is sent - * as input to the task - */ - private Map inputs; - - public DynamicForkInput(List> tasks, Map inputs) { - this.tasks = tasks; - this.inputs = inputs; - } - - public DynamicForkInput() {} - - public List> getTasks() { - return tasks; - } - - public void setTasks(List> tasks) { - this.tasks = tasks; - } - - public Map getInputs() { - return inputs; - } - - public void setInputs(Map inputs) { - this.inputs = inputs; - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Event.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Event.java deleted file mode 100644 index 4911a635d..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Event.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -import com.google.common.base.Strings; - -/** Task to publish Events to external queuing systems like SQS, NATS, AMQP etc. */ -public class Event extends Task { - - private static final String SINK_PARAMETER = "sink"; - - /** - * @param taskReferenceName Unique reference name within the workflow - * @param eventSink qualified name of the event sink where the message is published. Using the - * format sink_type:location e.g. sqs:sqs_queue_name, amqp_queue:queue_name, - * amqp_exchange:queue_name, nats:queue_name - */ - public Event(String taskReferenceName, String eventSink) { - super(taskReferenceName, TaskType.EVENT); - if (Strings.isNullOrEmpty(eventSink)) { - throw new AssertionError("Null/Empty eventSink"); - } - super.input(SINK_PARAMETER, eventSink); - } - - Event(WorkflowTask workflowTask) { - super(workflowTask); - } - - public String getSink() { - return (String) getInput().get(SINK_PARAMETER); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/ForkJoin.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/ForkJoin.java deleted file mode 100644 index 239c935ac..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/ForkJoin.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -/** ForkJoin task */ -public class ForkJoin extends Task { - - private Join join; - - private Task[][] forkedTasks; - - /** - * execute task specified in the forkedTasks parameter in parallel. - * - *

forkedTask is a two-dimensional list that executes the outermost list in parallel and list - * within that is executed sequentially. - * - *

e.g. [[task1, task2],[task3, task4],[task5]] are executed as: - * - *

-     *                    ---------------
-     *                    |     fork    |
-     *                    ---------------
-     *                    |       |     |
-     *                    |       |     |
-     *                  task1  task3  task5
-     *                  task2  task4    |
-     *                    |      |      |
-     *                 ---------------------
-     *                 |       join        |
-     *                 ---------------------
-     * 
- * - *

This method automatically adds a join that waits for all the *last* tasks in the fork - * (e.g. task2, task4 and task5 in the above example) to be completed.* - * - *

Use join method @see {@link ForkJoin#joinOn(String...)} to override this behavior (note: - * not a common scenario) - * - * @param taskReferenceName unique task reference name - * @param forkedTasks List of tasks to be executed in parallel - */ - public ForkJoin(String taskReferenceName, Task[]... forkedTasks) { - super(taskReferenceName, TaskType.FORK_JOIN); - this.forkedTasks = forkedTasks; - } - - ForkJoin(WorkflowTask workflowTask) { - super(workflowTask); - int size = workflowTask.getForkTasks().size(); - this.forkedTasks = new Task[size][]; - int i = 0; - for (List forkTasks : workflowTask.getForkTasks()) { - Task[] tasks = new Task[forkTasks.size()]; - for (int j = 0; j < forkTasks.size(); j++) { - WorkflowTask forkWorkflowTask = forkTasks.get(j); - Task task = TaskRegistry.getTask(forkWorkflowTask); - tasks[j] = task; - } - this.forkedTasks[i++] = tasks; - } - } - - public ForkJoin joinOn(String... joinOn) { - this.join = new Join(getTaskReferenceName() + "_join", joinOn); - return this; - } - - @Override - protected List getChildrenTasks() { - WorkflowTask fork = toWorkflowTask(); - - WorkflowTask joinWorkflowTask = null; - if (this.join != null) { - List joinTasks = this.join.getWorkflowDefTasks(); - joinWorkflowTask = joinTasks.get(0); - } else { - joinWorkflowTask = new WorkflowTask(); - joinWorkflowTask.setWorkflowTaskType(TaskType.JOIN); - joinWorkflowTask.setTaskReferenceName(getTaskReferenceName() + "_join"); - joinWorkflowTask.setName(joinWorkflowTask.getTaskReferenceName()); - joinWorkflowTask.setJoinOn(fork.getJoinOn()); - } - return Arrays.asList(joinWorkflowTask); - } - - @Override - public void updateWorkflowTask(WorkflowTask fork) { - List joinOnTaskRefNames = new ArrayList<>(); - List> forkTasks = new ArrayList<>(); - - for (Task[] forkedTaskList : forkedTasks) { - List forkedWorkflowTasks = new ArrayList<>(); - for (Task baseWorkflowTask : forkedTaskList) { - forkedWorkflowTasks.addAll(baseWorkflowTask.getWorkflowDefTasks()); - } - forkTasks.add(forkedWorkflowTasks); - joinOnTaskRefNames.add( - forkedWorkflowTasks.get(forkedWorkflowTasks.size() - 1).getTaskReferenceName()); - } - if (this.join != null) { - fork.setJoinOn(List.of(this.join.getJoinOn())); - } else { - fork.setJoinOn(joinOnTaskRefNames); - } - - fork.setForkTasks(forkTasks); - } - - public Task[][] getForkedTasks() { - return forkedTasks; - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Http.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Http.java deleted file mode 100644 index 06c4ff9fa..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Http.java +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.*; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.sdk.workflow.utils.ObjectMapperProvider; - -import com.fasterxml.jackson.databind.ObjectMapper; - -/** Wait task */ -public class Http extends Task { - - private static final Logger LOGGER = LoggerFactory.getLogger(Http.class); - - private static final String INPUT_PARAM = "http_request"; - - private ObjectMapper objectMapper = new ObjectMapperProvider().getObjectMapper(); - - private Input httpRequest; - - public Http(String taskReferenceName) { - super(taskReferenceName, TaskType.HTTP); - this.httpRequest = new Input(); - this.httpRequest.method = Input.HttpMethod.GET; - super.input(INPUT_PARAM, httpRequest); - } - - Http(WorkflowTask workflowTask) { - super(workflowTask); - - Object inputRequest = workflowTask.getInputParameters().get(INPUT_PARAM); - if (inputRequest != null) { - try { - this.httpRequest = objectMapper.convertValue(inputRequest, Input.class); - } catch (Exception e) { - LOGGER.error("Error while trying to convert input request " + e.getMessage(), e); - } - } - } - - public Http input(Input httpRequest) { - this.httpRequest = httpRequest; - return this; - } - - public Http url(String url) { - this.httpRequest.setUri(url); - return this; - } - - public Http method(Input.HttpMethod method) { - this.httpRequest.setMethod(method); - return this; - } - - public Http headers(Map headers) { - this.httpRequest.setHeaders(headers); - return this; - } - - public Http body(Object body) { - this.httpRequest.setBody(body); - return this; - } - - public Http readTimeout(int readTimeout) { - this.httpRequest.setReadTimeOut(readTimeout); - return this; - } - - public Input getHttpRequest() { - return httpRequest; - } - - @Override - protected void updateWorkflowTask(WorkflowTask workflowTask) { - workflowTask.getInputParameters().put(INPUT_PARAM, httpRequest); - } - - public static class Input { - public enum HttpMethod { - PUT, - POST, - GET, - DELETE, - OPTIONS, - HEAD - } - - private HttpMethod method; // PUT, POST, GET, DELETE, OPTIONS, HEAD - private String vipAddress; - private String appName; - private Map headers = new HashMap<>(); - private String uri; - private Object body; - private String accept = "application/json"; - private String contentType = "application/json"; - private Integer connectionTimeOut; - private Integer readTimeOut; - - /** - * @return the method - */ - public HttpMethod getMethod() { - return method; - } - - /** - * @param method the method to set - */ - public void setMethod(HttpMethod method) { - this.method = method; - } - - /** - * @return the headers - */ - public Map getHeaders() { - return headers; - } - - /** - * @param headers the headers to set - */ - public void setHeaders(Map headers) { - this.headers = headers; - } - - /** - * @return the body - */ - public Object getBody() { - return body; - } - - /** - * @param body the body to set - */ - public void setBody(Object body) { - this.body = body; - } - - /** - * @return the uri - */ - public String getUri() { - return uri; - } - - /** - * @param uri the uri to set - */ - public void setUri(String uri) { - this.uri = uri; - } - - /** - * @return the vipAddress - */ - public String getVipAddress() { - return vipAddress; - } - - /** - * @param vipAddress the vipAddress to set - */ - public void setVipAddress(String vipAddress) { - this.vipAddress = vipAddress; - } - - /** - * @return the accept - */ - public String getAccept() { - return accept; - } - - /** - * @param accept the accept to set - */ - public void setAccept(String accept) { - this.accept = accept; - } - - /** - * @return the MIME content type to use for the request - */ - public String getContentType() { - return contentType; - } - - /** - * @param contentType the MIME content type to set - */ - public void setContentType(String contentType) { - this.contentType = contentType; - } - - public String getAppName() { - return appName; - } - - public void setAppName(String appName) { - this.appName = appName; - } - - /** - * @return the connectionTimeOut - */ - public Integer getConnectionTimeOut() { - return connectionTimeOut; - } - - /** - * @return the readTimeOut - */ - public Integer getReadTimeOut() { - return readTimeOut; - } - - public void setConnectionTimeOut(Integer connectionTimeOut) { - this.connectionTimeOut = connectionTimeOut; - } - - public void setReadTimeOut(Integer readTimeOut) { - this.readTimeOut = readTimeOut; - } - - @Override - public String toString() { - return "Input{" - + "method=" - + method - + ", vipAddress='" - + vipAddress - + '\'' - + ", appName='" - + appName - + '\'' - + ", headers=" - + headers - + ", uri='" - + uri - + '\'' - + ", body=" - + body - + ", accept='" - + accept - + '\'' - + ", contentType='" - + contentType - + '\'' - + ", connectionTimeOut=" - + connectionTimeOut - + ", readTimeOut=" - + readTimeOut - + '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Input input = (Input) o; - return method == input.method - && Objects.equals(vipAddress, input.vipAddress) - && Objects.equals(appName, input.appName) - && Objects.equals(headers, input.headers) - && Objects.equals(uri, input.uri) - && Objects.equals(body, input.body) - && Objects.equals(accept, input.accept) - && Objects.equals(contentType, input.contentType) - && Objects.equals(connectionTimeOut, input.connectionTimeOut) - && Objects.equals(readTimeOut, input.readTimeOut); - } - - @Override - public int hashCode() { - return Objects.hash( - method, - vipAddress, - appName, - headers, - uri, - body, - accept, - contentType, - connectionTimeOut, - readTimeOut); - } - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/JQ.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/JQ.java deleted file mode 100644 index 9121d539d..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/JQ.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -import com.google.common.base.Strings; - -/** - * JQ Transformation task See https://stedolan.github.io/jq/ for how to form the queries to parse - * JSON payloads - */ -public class JQ extends Task { - - private static final String QUERY_EXPRESSION_PARAMETER = "queryExpression"; - - public JQ(String taskReferenceName, String queryExpression) { - super(taskReferenceName, TaskType.JSON_JQ_TRANSFORM); - if (Strings.isNullOrEmpty(queryExpression)) { - throw new AssertionError("Null/Empty queryExpression"); - } - super.input(QUERY_EXPRESSION_PARAMETER, queryExpression); - } - - JQ(WorkflowTask workflowTask) { - super(workflowTask); - } - - public String getQueryExpression() { - return (String) getInput().get(QUERY_EXPRESSION_PARAMETER); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Javascript.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Javascript.java deleted file mode 100644 index d6d4af2ba..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Javascript.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.io.IOException; -import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; - -import javax.script.Bindings; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; - -import org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.sdk.workflow.def.ValidationError; - -import com.google.common.base.Strings; - -/** - * JQ Transformation task See https://stedolan.github.io/jq/ for how to form the queries to parse - * JSON payloads - */ -public class Javascript extends Task { - - private static final Logger LOGGER = LoggerFactory.getLogger(Javascript.class); - - private static final String EXPRESSION_PARAMETER = "expression"; - - private static final String EVALUATOR_TYPE_PARAMETER = "evaluatorType"; - - private static final String ENGINE = "nashorn"; - - /** - * Javascript tasks are executed on the Conductor server without having to write worker code - * - *

Use {@link Javascript#validate()} method to validate the javascript to ensure the script - * is valid. Set environment variable CONDUCTOR_NASHORN_ES6_ENABLED=true for Nashorn ES6 support - * during validation. - * - * @param taskReferenceName - * @param script script to execute - */ - public Javascript(String taskReferenceName, String script) { - super(taskReferenceName, TaskType.INLINE); - if (Strings.isNullOrEmpty(script)) { - throw new AssertionError("Null/Empty script"); - } - super.input(EVALUATOR_TYPE_PARAMETER, "javascript"); - super.input(EXPRESSION_PARAMETER, script); - } - - /** - * Javascript tasks are executed on the Conductor server without having to write worker code - * - *

Use {@link Javascript#validate()} method to validate the javascript to ensure the script - * is valid. - * - * @param taskReferenceName - * @param stream stream to load the script file from - */ - public Javascript(String taskReferenceName, InputStream stream) { - super(taskReferenceName, TaskType.INLINE); - if (stream == null) { - throw new AssertionError("Stream is empty"); - } - super.input(EVALUATOR_TYPE_PARAMETER, "javascript"); - try { - String script = new String(stream.readAllBytes()); - super.input(EXPRESSION_PARAMETER, script); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - Javascript(WorkflowTask workflowTask) { - super(workflowTask); - } - - public String getExpression() { - return (String) getInput().get(EXPRESSION_PARAMETER); - } - - /** - * Validates the script. - * - * @return - */ - public Javascript validate() { - ScriptEngine scriptEngine; - if ("true".equalsIgnoreCase(System.getenv("CONDUCTOR_NASHORN_ES6_ENABLED"))) { - NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - scriptEngine = factory.getScriptEngine("--language=es6"); - } else { - scriptEngine = new ScriptEngineManager().getEngineByName("Nashorn"); - } - if (scriptEngine == null) { - LOGGER.error("missing " + ENGINE + " engine. Ensure you are running supported JVM"); - return this; - } - - try { - - Bindings bindings = scriptEngine.createBindings(); - bindings.put("$", new HashMap<>()); - scriptEngine.eval(getExpression(), bindings); - - } catch (ScriptException e) { - String message = e.getMessage(); - throw new ValidationError(message); - } - return this; - } - - /** - * Helper method to unit test your javascript. The method is not used for creating or executing - * workflow but is meant for testing only. - * - * @param input Input that against which the script will be executed - * @return Output of the script - */ - public Object test(Map input) { - - ScriptEngine scriptEngine; - if ("true".equalsIgnoreCase(System.getenv("CONDUCTOR_NASHORN_ES6_ENABLED"))) { - NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - scriptEngine = factory.getScriptEngine("--language=es6"); - } else { - scriptEngine = new ScriptEngineManager().getEngineByName("Nashorn"); - } - if (scriptEngine == null) { - LOGGER.error("missing " + ENGINE + " engine. Ensure you are running supported JVM"); - return this; - } - - try { - - Bindings bindings = scriptEngine.createBindings(); - bindings.put("$", input); - return scriptEngine.eval(getExpression(), bindings); - - } catch (ScriptException e) { - String message = e.getMessage(); - throw new ValidationError(message); - } - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Join.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Join.java deleted file mode 100644 index 2996d8582..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Join.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.Arrays; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -public class Join extends Task { - - private String[] joinOn; - - /** - * @param taskReferenceName - * @param joinOn List of task reference names to join on - */ - public Join(String taskReferenceName, String... joinOn) { - super(taskReferenceName, TaskType.JOIN); - this.joinOn = joinOn; - } - - Join(WorkflowTask workflowTask) { - super(workflowTask); - this.joinOn = workflowTask.getJoinOn().toArray(new String[0]); - } - - @Override - protected void updateWorkflowTask(WorkflowTask workflowTask) { - workflowTask.setJoinOn(Arrays.asList(joinOn)); - } - - public String[] getJoinOn() { - return joinOn; - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SetVariable.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SetVariable.java deleted file mode 100644 index c4260154a..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SetVariable.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.sdk.workflow.def.WorkflowBuilder; - -public class SetVariable extends Task { - /** - * Sets the value of the variable in workflow. Used for workflow state management. Workflow - * state is a Map that is initialized using @see {@link WorkflowBuilder#variables(Object)} - * - * @param taskReferenceName Use input methods to set the variable values - */ - public SetVariable(String taskReferenceName) { - super(taskReferenceName, TaskType.SET_VARIABLE); - } - - SetVariable(WorkflowTask workflowTask) { - super(workflowTask); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SimpleTask.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SimpleTask.java deleted file mode 100644 index 7cea277c3..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SimpleTask.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -/** Workflow task executed by a worker */ -public class SimpleTask extends Task { - - private TaskDef taskDef; - - public SimpleTask(String taskDefName, String taskReferenceName) { - super(taskReferenceName, TaskType.SIMPLE); - super.name(taskDefName); - } - - SimpleTask(WorkflowTask workflowTask) { - super(workflowTask); - this.taskDef = workflowTask.getTaskDefinition(); - } - - public TaskDef getTaskDef() { - return taskDef; - } - - public SimpleTask setTaskDef(TaskDef taskDef) { - this.taskDef = taskDef; - return this; - } - - @Override - protected void updateWorkflowTask(WorkflowTask workflowTask) { - workflowTask.setTaskDefinition(taskDef); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SubWorkflow.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SubWorkflow.java deleted file mode 100644 index 3707cfba5..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SubWorkflow.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.SubWorkflowParams; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.sdk.workflow.def.ConductorWorkflow; - -public class SubWorkflow extends Task { - - private ConductorWorkflow conductorWorkflow; - - private String workflowName; - - private Integer workflowVersion; - - /** - * Start a workflow as a sub-workflow - * - * @param taskReferenceName - * @param workflowName - * @param workflowVersion - */ - public SubWorkflow(String taskReferenceName, String workflowName, Integer workflowVersion) { - super(taskReferenceName, TaskType.SUB_WORKFLOW); - this.workflowName = workflowName; - this.workflowVersion = workflowVersion; - } - - /** - * Start a workflow as a sub-workflow - * - * @param taskReferenceName - * @param conductorWorkflow - */ - public SubWorkflow(String taskReferenceName, ConductorWorkflow conductorWorkflow) { - super(taskReferenceName, TaskType.SUB_WORKFLOW); - this.conductorWorkflow = conductorWorkflow; - } - - SubWorkflow(WorkflowTask workflowTask) { - super(workflowTask); - SubWorkflowParams subworkflowParam = workflowTask.getSubWorkflowParam(); - this.workflowName = subworkflowParam.getName(); - this.workflowVersion = subworkflowParam.getVersion(); - if (subworkflowParam.getWorkflowDef() != null) { - this.conductorWorkflow = - ConductorWorkflow.fromWorkflowDef(subworkflowParam.getWorkflowDef()); - } - } - - public ConductorWorkflow getConductorWorkflow() { - return conductorWorkflow; - } - - public String getWorkflowName() { - return workflowName; - } - - public int getWorkflowVersion() { - return workflowVersion; - } - - @Override - protected void updateWorkflowTask(WorkflowTask workflowTask) { - SubWorkflowParams subWorkflowParam = new SubWorkflowParams(); - - if (conductorWorkflow != null) { - subWorkflowParam.setWorkflowDef(conductorWorkflow.toWorkflowDef()); - } else { - subWorkflowParam.setName(workflowName); - subWorkflowParam.setVersion(workflowVersion); - } - workflowTask.setSubWorkflowParam(subWorkflowParam); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Switch.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Switch.java deleted file mode 100644 index bcff758ff..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Switch.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.*; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -/** Switch Task */ -public class Switch extends Task { - - public static final String VALUE_PARAM_NAME = "value-param"; - - public static final String JAVASCRIPT_NAME = "javascript"; - - private String caseExpression; - - private boolean useJavascript; - - private List> defaultTasks = new ArrayList<>(); - - private Map>> branches = new HashMap<>(); - - /** - * Switch case (similar to if...then...else or switch in java language) - * - * @param taskReferenceName - * @param caseExpression An expression that outputs a string value to be used as case branches. - * Case expression can be a support value parameter e.g. ${workflow.input.key} or - * ${task.output.key} or a Javascript statement. - * @param useJavascript set to true if the caseExpression is a javascript statement - */ - public Switch(String taskReferenceName, String caseExpression, boolean useJavascript) { - super(taskReferenceName, TaskType.SWITCH); - this.caseExpression = caseExpression; - this.useJavascript = useJavascript; - } - - /** - * Switch case (similar to if...then...else or switch in java language) - * - * @param taskReferenceName - * @param caseExpression - */ - public Switch(String taskReferenceName, String caseExpression) { - super(taskReferenceName, TaskType.SWITCH); - this.caseExpression = caseExpression; - this.useJavascript = false; - } - - Switch(WorkflowTask workflowTask) { - super(workflowTask); - Map> decisions = workflowTask.getDecisionCases(); - - decisions.entrySet().stream() - .forEach( - branch -> { - String branchName = branch.getKey(); - List branchWorkflowTasks = branch.getValue(); - List> branchTasks = new ArrayList<>(); - for (WorkflowTask branchWorkflowTask : branchWorkflowTasks) { - branchTasks.add(TaskRegistry.getTask(branchWorkflowTask)); - } - this.branches.put(branchName, branchTasks); - }); - - List defaultCases = workflowTask.getDefaultCase(); - for (WorkflowTask defaultCase : defaultCases) { - this.defaultTasks.add(TaskRegistry.getTask(defaultCase)); - } - } - - public Switch defaultCase(Task... tasks) { - defaultTasks = Arrays.asList(tasks); - return this; - } - - public Switch defaultCase(List> defaultTasks) { - this.defaultTasks = defaultTasks; - return this; - } - - public Switch decisionCases(Map>> branches) { - this.branches = branches; - return this; - } - - public Switch defaultCase(String... workerTasks) { - for (String workerTask : workerTasks) { - this.defaultTasks.add(new SimpleTask(workerTask, workerTask)); - } - return this; - } - - public Switch switchCase(String caseValue, Task... tasks) { - branches.put(caseValue, Arrays.asList(tasks)); - return this; - } - - public Switch switchCase(String caseValue, String... workerTasks) { - List> tasks = new ArrayList<>(workerTasks.length); - int i = 0; - for (String workerTask : workerTasks) { - tasks.add(new SimpleTask(workerTask, workerTask)); - } - branches.put(caseValue, tasks); - return this; - } - - public List> getDefaultTasks() { - return defaultTasks; - } - - public Map>> getBranches() { - return branches; - } - - @Override - public void updateWorkflowTask(WorkflowTask workflowTask) { - - if (useJavascript) { - workflowTask.setEvaluatorType(JAVASCRIPT_NAME); - workflowTask.setExpression(caseExpression); - - } else { - workflowTask.setEvaluatorType(VALUE_PARAM_NAME); - workflowTask.getInputParameters().put("switchCaseValue", caseExpression); - workflowTask.setExpression("switchCaseValue"); - } - - Map> decisionCases = new HashMap<>(); - branches.entrySet() - .forEach( - entry -> { - String decisionCase = entry.getKey(); - List> decisionTasks = entry.getValue(); - List decionTaskDefs = - new ArrayList<>(decisionTasks.size()); - for (Task decisionTask : decisionTasks) { - decionTaskDefs.addAll(decisionTask.getWorkflowDefTasks()); - } - decisionCases.put(decisionCase, decionTaskDefs); - }); - - workflowTask.setDecisionCases(decisionCases); - List defaultCaseTaskDefs = new ArrayList<>(defaultTasks.size()); - for (Task defaultTask : defaultTasks) { - defaultCaseTaskDefs.addAll(defaultTask.getWorkflowDefTasks()); - } - workflowTask.setDefaultCase(defaultCaseTaskDefs); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Task.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Task.java deleted file mode 100644 index 28618f234..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Task.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.*; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.sdk.workflow.utils.InputOutputGetter; -import com.netflix.conductor.sdk.workflow.utils.MapBuilder; -import com.netflix.conductor.sdk.workflow.utils.ObjectMapperProvider; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Strings; - -/** Workflow Task */ -public abstract class Task { - - private String name; - - private String description; - - private String taskReferenceName; - - private boolean optional; - - private int startDelay; - - private TaskType type; - - private Map input = new HashMap<>(); - - protected final ObjectMapper om = new ObjectMapperProvider().getObjectMapper(); - - public final InputOutputGetter taskInput; - - public final InputOutputGetter taskOutput; - - public Task(String taskReferenceName, TaskType type) { - if (Strings.isNullOrEmpty(taskReferenceName)) { - throw new AssertionError("taskReferenceName cannot be null"); - } - if (type == null) { - throw new AssertionError("type cannot be null"); - } - - this.name = taskReferenceName; - this.taskReferenceName = taskReferenceName; - this.type = type; - this.taskInput = new InputOutputGetter(taskReferenceName, InputOutputGetter.Field.input); - this.taskOutput = new InputOutputGetter(taskReferenceName, InputOutputGetter.Field.output); - } - - Task(WorkflowTask workflowTask) { - this(workflowTask.getTaskReferenceName(), TaskType.valueOf(workflowTask.getType())); - this.input = workflowTask.getInputParameters(); - this.description = workflowTask.getDescription(); - this.name = workflowTask.getName(); - } - - public T name(String name) { - this.name = name; - return (T) this; - } - - public T description(String description) { - this.description = description; - return (T) this; - } - - public T input(String key, boolean value) { - input.put(key, value); - return (T) this; - } - - public T input(String key, Object value) { - input.put(key, value); - return (T) this; - } - - public T input(String key, char value) { - input.put(key, value); - return (T) this; - } - - public T input(String key, InputOutputGetter value) { - input.put(key, value.getParent()); - return (T) this; - } - - public T input(InputOutputGetter value) { - return input("input", value); - } - - public T input(String key, String value) { - input.put(key, value); - return (T) this; - } - - public T input(String key, Number value) { - input.put(key, value); - return (T) this; - } - - public T input(String key, Map value) { - input.put(key, value); - return (T) this; - } - - public T input(Map map) { - input.putAll(map); - return (T) this; - } - - public T input(MapBuilder builder) { - input.putAll(builder.build()); - return (T) this; - } - - public T input(Object... keyValues) { - if (keyValues.length == 1) { - Object kv = keyValues[0]; - Map objectMap = om.convertValue(kv, Map.class); - input.putAll(objectMap); - return (T) this; - } - if (keyValues.length % 2 == 1) { - throw new IllegalArgumentException("Not all keys have value specified"); - } - for (int i = 0; i < keyValues.length; ) { - String key = keyValues[i].toString(); - Object value = keyValues[i + 1]; - input.put(key, value); - i += 2; - } - return (T) this; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getTaskReferenceName() { - return taskReferenceName; - } - - public void setTaskReferenceName(String taskReferenceName) { - this.taskReferenceName = taskReferenceName; - } - - public boolean isOptional() { - return optional; - } - - public void setOptional(boolean optional) { - this.optional = optional; - } - - public int getStartDelay() { - return startDelay; - } - - public void setStartDelay(int startDelay) { - this.startDelay = startDelay; - } - - public TaskType getType() { - return type; - } - - public String getDescription() { - return description; - } - - public Map getInput() { - return input; - } - - public final List getWorkflowDefTasks() { - List workflowTasks = new ArrayList<>(); - workflowTasks.addAll(getParentTasks()); - workflowTasks.add(toWorkflowTask()); - workflowTasks.addAll(getChildrenTasks()); - return workflowTasks; - } - - protected final WorkflowTask toWorkflowTask() { - WorkflowTask workflowTask = new WorkflowTask(); - workflowTask.setName(name); - workflowTask.setTaskReferenceName(taskReferenceName); - workflowTask.setWorkflowTaskType(type); - workflowTask.setDescription(description); - workflowTask.setInputParameters(input); - workflowTask.setStartDelay(startDelay); - workflowTask.setOptional(optional); - - // Let the sub-classes enrich the workflow task before returning back - updateWorkflowTask(workflowTask); - - return workflowTask; - } - - /** - * Override this method when the sub-class should update the default WorkflowTask generated - * using {@link #toWorkflowTask()} - * - * @param workflowTask - */ - protected void updateWorkflowTask(WorkflowTask workflowTask) {} - - /** - * Override this method when sub-classes will generate multiple workflow tasks. Used by tasks - * which have children tasks such as do_while, fork, etc. - * - * @return - */ - protected List getChildrenTasks() { - return List.of(); - } - - protected List getParentTasks() { - return List.of(); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/TaskRegistry.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/TaskRegistry.java deleted file mode 100644 index 2a404a7cc..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/TaskRegistry.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -public class TaskRegistry { - - private static final Logger LOGGER = LoggerFactory.getLogger(TaskRegistry.class); - - private static Map> taskTypeMap = new HashMap<>(); - - public static void register(String taskType, Class taskImplementation) { - taskTypeMap.put(taskType, taskImplementation); - } - - public static Task getTask(WorkflowTask workflowTask) { - Class clazz = taskTypeMap.get(workflowTask.getType()); - if (clazz == null) { - throw new UnsupportedOperationException( - "No support to convert " + workflowTask.getType()); - } - Task task = null; - try { - task = clazz.getDeclaredConstructor(WorkflowTask.class).newInstance(workflowTask); - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - return task; - } - return task; - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Terminate.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Terminate.java deleted file mode 100644 index fb7b3d0fd..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Terminate.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.util.HashMap; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; - -public class Terminate extends Task { - - private static final String TERMINATION_STATUS_PARAMETER = "terminationStatus"; - - private static final String TERMINATION_WORKFLOW_OUTPUT = "workflowOutput"; - - private static final String TERMINATION_REASON_PARAMETER = "terminationReason"; - - /** - * Terminate the workflow and mark it as FAILED - * - * @param taskReferenceName - * @param reason - */ - public Terminate(String taskReferenceName, String reason) { - this(taskReferenceName, Workflow.WorkflowStatus.FAILED, reason, new HashMap<>()); - } - - /** - * Terminate the workflow with a specific terminate status - * - * @param taskReferenceName - * @param terminationStatus - * @param reason - */ - public Terminate( - String taskReferenceName, Workflow.WorkflowStatus terminationStatus, String reason) { - this(taskReferenceName, terminationStatus, reason, new HashMap<>()); - } - - public Terminate( - String taskReferenceName, - Workflow.WorkflowStatus terminationStatus, - String reason, - Object workflowOutput) { - super(taskReferenceName, TaskType.TERMINATE); - - input(TERMINATION_STATUS_PARAMETER, terminationStatus.name()); - input(TERMINATION_WORKFLOW_OUTPUT, workflowOutput); - input(TERMINATION_REASON_PARAMETER, reason); - } - - Terminate(WorkflowTask workflowTask) { - super(workflowTask); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Wait.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Wait.java deleted file mode 100644 index c6f11ef01..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Wait.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def.tasks; - -import java.time.Duration; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; - -import javax.swing.*; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; - -/** Wait task */ -public class Wait extends Task { - - public static final String DURATION_INPUT = "duration"; - public static final String UNTIL_INPUT = "until"; - - public static final DateTimeFormatter dateTimeFormatter = - DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm z"); - - /** - * Wait until and external signal completes the task. The external signal can be either an API - * call (POST /api/task) to update the task status or an event coming from a supported external - * queue integration like SQS, Kafka, NATS, AMQP etc. - * - *


- * see - * https://netflix.github.io/conductor/reference-docs/wait-task for more details - * - * @param taskReferenceName - */ - public Wait(String taskReferenceName) { - super(taskReferenceName, TaskType.WAIT); - } - - public Wait(String taskReferenceName, Duration waitFor) { - super(taskReferenceName, TaskType.WAIT); - long seconds = waitFor.getSeconds(); - input(DURATION_INPUT, seconds + "s"); - } - - public Wait(String taskReferenceName, ZonedDateTime waitUntil) { - super(taskReferenceName, TaskType.WAIT); - String formattedDateTime = waitUntil.format(dateTimeFormatter); - input(UNTIL_INPUT, formattedDateTime); - } - - Wait(WorkflowTask workflowTask) { - super(workflowTask); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/WorkflowExecutor.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/WorkflowExecutor.java deleted file mode 100644 index d80d55928..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/WorkflowExecutor.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.executor; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.concurrent.*; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.conductor.client.http.MetadataClient; -import com.netflix.conductor.client.http.TaskClient; -import com.netflix.conductor.client.http.WorkflowClient; -import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.StartWorkflowRequest; -import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; -import com.netflix.conductor.sdk.workflow.def.ConductorWorkflow; -import com.netflix.conductor.sdk.workflow.def.tasks.*; -import com.netflix.conductor.sdk.workflow.executor.task.AnnotatedWorkerExecutor; -import com.netflix.conductor.sdk.workflow.utils.ObjectMapperProvider; - -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.sun.jersey.api.client.ClientHandler; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.ClientFilter; - -public class WorkflowExecutor { - - private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowExecutor.class); - - private final TypeReference> listOfTaskDefs = new TypeReference<>() {}; - - private Map> runningWorkflowFutures = - new ConcurrentHashMap<>(); - - private final ObjectMapper objectMapper = new ObjectMapperProvider().getObjectMapper(); - - private final TaskClient taskClient; - - private final WorkflowClient workflowClient; - - private final MetadataClient metadataClient; - - private final AnnotatedWorkerExecutor annotatedWorkerExecutor; - - private final ScheduledExecutorService scheduledWorkflowMonitor = - Executors.newSingleThreadScheduledExecutor(); - - static { - initTaskImplementations(); - } - - public static void initTaskImplementations() { - TaskRegistry.register(TaskType.DO_WHILE.name(), DoWhile.class); - TaskRegistry.register(TaskType.DYNAMIC.name(), Dynamic.class); - TaskRegistry.register(TaskType.FORK_JOIN_DYNAMIC.name(), DynamicFork.class); - TaskRegistry.register(TaskType.FORK_JOIN.name(), ForkJoin.class); - TaskRegistry.register(TaskType.HTTP.name(), Http.class); - TaskRegistry.register(TaskType.INLINE.name(), Javascript.class); - TaskRegistry.register(TaskType.JOIN.name(), Join.class); - TaskRegistry.register(TaskType.JSON_JQ_TRANSFORM.name(), JQ.class); - TaskRegistry.register(TaskType.SET_VARIABLE.name(), SetVariable.class); - TaskRegistry.register(TaskType.SIMPLE.name(), SimpleTask.class); - TaskRegistry.register(TaskType.SUB_WORKFLOW.name(), SubWorkflow.class); - TaskRegistry.register(TaskType.SWITCH.name(), Switch.class); - TaskRegistry.register(TaskType.TERMINATE.name(), Terminate.class); - TaskRegistry.register(TaskType.WAIT.name(), Wait.class); - TaskRegistry.register(TaskType.EVENT.name(), Event.class); - } - - public WorkflowExecutor(String apiServerURL) { - this(apiServerURL, 100); - } - - public WorkflowExecutor( - String apiServerURL, int pollingInterval, ClientFilter... clientFilter) { - - taskClient = new TaskClient(new DefaultClientConfig(), (ClientHandler) null, clientFilter); - taskClient.setRootURI(apiServerURL); - - workflowClient = - new WorkflowClient(new DefaultClientConfig(), (ClientHandler) null, clientFilter); - workflowClient.setRootURI(apiServerURL); - - metadataClient = - new MetadataClient(new DefaultClientConfig(), (ClientHandler) null, clientFilter); - metadataClient.setRootURI(apiServerURL); - - annotatedWorkerExecutor = new AnnotatedWorkerExecutor(taskClient, pollingInterval); - scheduledWorkflowMonitor.scheduleAtFixedRate( - () -> { - for (Map.Entry> entry : - runningWorkflowFutures.entrySet()) { - String workflowId = entry.getKey(); - CompletableFuture future = entry.getValue(); - Workflow workflow = workflowClient.getWorkflow(workflowId, true); - if (workflow.getStatus().isTerminal()) { - future.complete(workflow); - runningWorkflowFutures.remove(workflowId); - } - } - }, - 100, - 100, - TimeUnit.MILLISECONDS); - } - - public WorkflowExecutor( - TaskClient taskClient, - WorkflowClient workflowClient, - MetadataClient metadataClient, - int pollingInterval) { - - this.taskClient = taskClient; - this.workflowClient = workflowClient; - this.metadataClient = metadataClient; - annotatedWorkerExecutor = new AnnotatedWorkerExecutor(taskClient, pollingInterval); - scheduledWorkflowMonitor.scheduleAtFixedRate( - () -> { - for (Map.Entry> entry : - runningWorkflowFutures.entrySet()) { - String workflowId = entry.getKey(); - CompletableFuture future = entry.getValue(); - Workflow workflow = workflowClient.getWorkflow(workflowId, true); - if (workflow.getStatus().isTerminal()) { - future.complete(workflow); - runningWorkflowFutures.remove(workflowId); - } - } - }, - 100, - 100, - TimeUnit.MILLISECONDS); - } - - public void initWorkers(String packagesToScan) { - annotatedWorkerExecutor.initWorkers(packagesToScan); - } - - public CompletableFuture executeWorkflow(String name, Integer version, Object input) { - CompletableFuture future = new CompletableFuture<>(); - Map inputMap = objectMapper.convertValue(input, Map.class); - - StartWorkflowRequest request = new StartWorkflowRequest(); - request.setInput(inputMap); - request.setName(name); - request.setVersion(version); - - String workflowId = workflowClient.startWorkflow(request); - runningWorkflowFutures.put(workflowId, future); - return future; - } - - public CompletableFuture executeWorkflow( - ConductorWorkflow conductorWorkflow, Object input) { - - CompletableFuture future = new CompletableFuture<>(); - - Map inputMap = objectMapper.convertValue(input, Map.class); - - StartWorkflowRequest request = new StartWorkflowRequest(); - request.setInput(inputMap); - request.setName(conductorWorkflow.getName()); - request.setVersion(conductorWorkflow.getVersion()); - request.setWorkflowDef(conductorWorkflow.toWorkflowDef()); - - String workflowId = workflowClient.startWorkflow(request); - runningWorkflowFutures.put(workflowId, future); - - return future; - } - - public void loadTaskDefs(String resourcePath) throws IOException { - InputStream resource = WorkflowExecutor.class.getResourceAsStream(resourcePath); - if (resource != null) { - List taskDefs = objectMapper.readValue(resource, listOfTaskDefs); - loadMetadata(taskDefs); - } - } - - public void loadWorkflowDefs(String resourcePath) throws IOException { - InputStream resource = WorkflowExecutor.class.getResourceAsStream(resourcePath); - if (resource != null) { - WorkflowDef workflowDef = objectMapper.readValue(resource, WorkflowDef.class); - loadMetadata(workflowDef); - } - } - - public void loadMetadata(WorkflowDef workflowDef) { - metadataClient.registerWorkflowDef(workflowDef); - } - - public void loadMetadata(List taskDefs) { - metadataClient.registerTaskDefs(taskDefs); - } - - public void shutdown() { - scheduledWorkflowMonitor.shutdown(); - annotatedWorkerExecutor.shutdown(); - } - - public boolean registerWorkflow(WorkflowDef workflowDef, boolean overwrite) { - try { - if (overwrite) { - metadataClient.updateWorkflowDefs(Arrays.asList(workflowDef)); - } else { - metadataClient.registerWorkflowDef(workflowDef); - } - return true; - } catch (Exception e) { - LOGGER.error(e.getMessage(), e); - return false; - } - } - - public MetadataClient getMetadataClient() { - return metadataClient; - } - - public TaskClient getTaskClient() { - return taskClient; - } - - public WorkflowClient getWorkflowClient() { - return workflowClient; - } - - public void addBean(Object bean) { - annotatedWorkerExecutor.addBean(bean); - } - - public void registerModule(Module module) { - annotatedWorkerExecutor.registerModule(module); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorker.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorker.java deleted file mode 100644 index 57a3a8241..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorker.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.executor.task; - -import java.lang.annotation.Annotation; -import java.lang.reflect.*; -import java.util.*; - -import com.netflix.conductor.client.worker.Worker; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.TaskResult; -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.sdk.workflow.def.tasks.DynamicFork; -import com.netflix.conductor.sdk.workflow.def.tasks.DynamicForkInput; -import com.netflix.conductor.sdk.workflow.task.InputParam; -import com.netflix.conductor.sdk.workflow.task.OutputParam; -import com.netflix.conductor.sdk.workflow.utils.ObjectMapperProvider; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.ObjectMapper; - -public class AnnotatedWorker implements Worker { - - private String name; - - private Method workerMethod; - - private Object obj; - - private ObjectMapper om = new ObjectMapperProvider().getObjectMapper(); - - private int pollingInterval = 100; - - private Set failedStatuses = - Set.of(TaskResult.Status.FAILED, TaskResult.Status.FAILED_WITH_TERMINAL_ERROR); - - public AnnotatedWorker(String name, Method workerMethod, Object obj) { - this.name = name; - this.workerMethod = workerMethod; - this.obj = obj; - om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } - - void registerModule(Module module) { - om.registerModule(module); - } - - @Override - public String getTaskDefName() { - return name; - } - - @Override - public TaskResult execute(Task task) { - TaskResult result = null; - try { - TaskContext context = TaskContext.set(task); - Object[] parameters = getInvocationParameters(task); - Object invocationResult = workerMethod.invoke(obj, parameters); - result = setValue(invocationResult, context.getTaskResult()); - if (!failedStatuses.contains(result.getStatus()) - && result.getCallbackAfterSeconds() > 0) { - result.setStatus(TaskResult.Status.IN_PROGRESS); - } - } catch (InvocationTargetException invocationTargetException) { - if (result == null) { - result = new TaskResult(task); - } - Throwable e = invocationTargetException.getCause(); - e.printStackTrace(); - if (e instanceof NonRetryableException) { - result.setStatus(TaskResult.Status.FAILED_WITH_TERMINAL_ERROR); - } else { - result.setStatus(TaskResult.Status.FAILED); - } - - result.setReasonForIncompletion(e.getMessage()); - StringBuilder stackTrace = new StringBuilder(); - for (StackTraceElement stackTraceElement : e.getStackTrace()) { - String className = stackTraceElement.getClassName(); - if (className.startsWith("jdk.") - || className.startsWith(AnnotatedWorker.class.getName())) { - break; - } - stackTrace.append(stackTraceElement); - stackTrace.append("\n"); - } - result.log(stackTrace.toString()); - } catch (Exception e) { - throw new RuntimeException(e); - } - - return result; - } - - private Object[] getInvocationParameters(Task task) { - Class[] parameterTypes = workerMethod.getParameterTypes(); - Parameter[] parameters = workerMethod.getParameters(); - - if (parameterTypes.length == 1 && parameterTypes[0].equals(Task.class)) { - return new Object[] {task}; - } else if (parameterTypes.length == 1 && parameterTypes[0].equals(Map.class)) { - return new Object[] {task.getInputData()}; - } - - return getParameters(task, parameterTypes, parameters); - } - - private Object[] getParameters(Task task, Class[] parameterTypes, Parameter[] parameters) { - Annotation[][] parameterAnnotations = workerMethod.getParameterAnnotations(); - Object[] values = new Object[parameterTypes.length]; - for (int i = 0; i < parameterTypes.length; i++) { - Annotation[] paramAnnotation = parameterAnnotations[i]; - if (paramAnnotation != null && paramAnnotation.length > 0) { - Type type = parameters[i].getParameterizedType(); - Class parameterType = parameterTypes[i]; - values[i] = getInputValue(task, parameterType, type, paramAnnotation); - } else { - values[i] = om.convertValue(task.getInputData(), parameterTypes[i]); - } - } - - return values; - } - - private Object getInputValue( - Task task, Class parameterType, Type type, Annotation[] paramAnnotation) { - InputParam ip = findInputParamAnnotation(paramAnnotation); - - if (ip == null) { - return om.convertValue(task.getInputData(), parameterType); - } - - final String name = ip.value(); - final Object value = task.getInputData().get(name); - if (value == null) { - return null; - } - - if (List.class.isAssignableFrom(parameterType)) { - List list = om.convertValue(value, List.class); - if (type instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) type; - Class typeOfParameter = (Class) parameterizedType.getActualTypeArguments()[0]; - List parameterizedList = new ArrayList<>(); - for (Object item : list) { - parameterizedList.add(om.convertValue(item, typeOfParameter)); - } - - return parameterizedList; - } else { - return list; - } - } else { - return om.convertValue(value, parameterType); - } - } - - private static InputParam findInputParamAnnotation(Annotation[] paramAnnotation) { - return (InputParam) - Arrays.stream(paramAnnotation) - .filter(ann -> ann.annotationType().equals(InputParam.class)) - .findFirst() - .orElse(null); - } - - private TaskResult setValue(Object invocationResult, TaskResult result) { - - if (invocationResult == null) { - result.setStatus(TaskResult.Status.COMPLETED); - return result; - } - - OutputParam opAnnotation = - workerMethod.getAnnotatedReturnType().getAnnotation(OutputParam.class); - if (opAnnotation != null) { - - String name = opAnnotation.value(); - result.getOutputData().put(name, invocationResult); - result.setStatus(TaskResult.Status.COMPLETED); - return result; - - } else if (invocationResult instanceof TaskResult) { - - return (TaskResult) invocationResult; - - } else if (invocationResult instanceof Map) { - Map resultAsMap = (Map) invocationResult; - result.getOutputData().putAll(resultAsMap); - result.setStatus(TaskResult.Status.COMPLETED); - return result; - } else if (invocationResult instanceof String - || invocationResult instanceof Number - || invocationResult instanceof Boolean) { - result.getOutputData().put("result", invocationResult); - result.setStatus(TaskResult.Status.COMPLETED); - return result; - } else if (invocationResult instanceof List) { - - List resultAsList = om.convertValue(invocationResult, List.class); - result.getOutputData().put("result", resultAsList); - result.setStatus(TaskResult.Status.COMPLETED); - return result; - - } else if (invocationResult instanceof DynamicForkInput) { - DynamicForkInput forkInput = (DynamicForkInput) invocationResult; - List> tasks = forkInput.getTasks(); - List workflowTasks = new ArrayList<>(); - for (com.netflix.conductor.sdk.workflow.def.tasks.Task sdkTask : tasks) { - workflowTasks.addAll(sdkTask.getWorkflowDefTasks()); - } - result.getOutputData().put(DynamicFork.FORK_TASK_PARAM, workflowTasks); - result.getOutputData().put(DynamicFork.FORK_TASK_INPUT_PARAM, forkInput.getInputs()); - result.setStatus(TaskResult.Status.COMPLETED); - return result; - - } else { - Map resultAsMap = om.convertValue(invocationResult, Map.class); - result.getOutputData().putAll(resultAsMap); - result.setStatus(TaskResult.Status.COMPLETED); - return result; - } - } - - public void setPollingInterval(int pollingInterval) { - System.out.println( - "Setting the polling interval for " + getTaskDefName() + ", to " + pollingInterval); - this.pollingInterval = pollingInterval; - } - - @Override - public int getPollingInterval() { - System.out.println("Sending the polling interval to " + pollingInterval); - return pollingInterval; - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorkerExecutor.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorkerExecutor.java deleted file mode 100644 index fe237f867..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorkerExecutor.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.executor.task; - -import java.lang.reflect.Method; -import java.util.*; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.conductor.client.automator.TaskRunnerConfigurer; -import com.netflix.conductor.client.http.TaskClient; -import com.netflix.conductor.client.worker.Worker; -import com.netflix.conductor.sdk.workflow.task.WorkerTask; - -import com.fasterxml.jackson.databind.Module; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Strings; -import com.google.common.reflect.ClassPath; - -public class AnnotatedWorkerExecutor { - - private static final Logger LOGGER = LoggerFactory.getLogger(AnnotatedWorkerExecutor.class); - - private TaskClient taskClient; - - private TaskRunnerConfigurer taskRunner; - - private List executors = new ArrayList<>(); - - private Map workerExecutors = new HashMap<>(); - - private Map workerToThreadCount = new HashMap<>(); - - private Map workerToPollingInterval = new HashMap<>(); - - private Map workerDomains = new HashMap<>(); - - private Map workerClassObjs = new HashMap<>(); - - private static Set scannedPackages = new HashSet<>(); - - private WorkerConfiguration workerConfiguration; - - private Set modules = new HashSet<>(); - - public AnnotatedWorkerExecutor(TaskClient taskClient) { - this.taskClient = taskClient; - this.workerConfiguration = new WorkerConfiguration(); - } - - public AnnotatedWorkerExecutor(TaskClient taskClient, int pollingIntervalInMillis) { - this.taskClient = taskClient; - this.workerConfiguration = new WorkerConfiguration(pollingIntervalInMillis); - } - - public AnnotatedWorkerExecutor(TaskClient taskClient, WorkerConfiguration workerConfiguration) { - this.taskClient = taskClient; - this.workerConfiguration = workerConfiguration; - } - - /** - * Finds any worker implementation and starts polling for tasks - * - * @param basePackage list of packages - comma separated - to scan for annotated worker - * implementation - */ - public synchronized void initWorkers(String basePackage) { - scanWorkers(basePackage); - startPolling(); - } - - /** Shuts down the workers */ - public void shutdown() { - if (taskRunner != null) { - taskRunner.shutdown(); - } - } - - private void scanWorkers(String basePackage) { - try { - if (scannedPackages.contains(basePackage)) { - // skip - LOGGER.info("Package {} already scanned and will skip", basePackage); - return; - } - // Add here so to avoid infinite recursion where a class in the package contains the - // code to init workers - scannedPackages.add(basePackage); - List packagesToScan = new ArrayList<>(); - if (basePackage != null) { - String[] packages = basePackage.split(","); - Collections.addAll(packagesToScan, packages); - } - - LOGGER.info("packages to scan {}", packagesToScan); - - long s = System.currentTimeMillis(); - ClassPath.from(AnnotatedWorkerExecutor.class.getClassLoader()) - .getAllClasses() - .forEach( - classMeta -> { - String name = classMeta.getName(); - if (!includePackage(packagesToScan, name)) { - return; - } - try { - Class clazz = classMeta.load(); - Object obj = clazz.getConstructor().newInstance(); - addBean(obj); - } catch (Throwable t) { - // trace because many classes won't have a default no-args - // constructor and will fail - LOGGER.trace( - "Caught exception while loading and scanning class {}", - t.getMessage()); - } - }); - LOGGER.info( - "Took {} ms to scan all the classes, loading {} tasks", - (System.currentTimeMillis() - s), - workerExecutors.size()); - - } catch (Exception e) { - LOGGER.error("Error while scanning for workers: ", e); - } - } - - private boolean includePackage(List packagesToScan, String name) { - for (String scanPkg : packagesToScan) { - if (name.startsWith(scanPkg)) return true; - } - return false; - } - - public void addBean(Object bean) { - Class clazz = bean.getClass(); - for (Method method : clazz.getMethods()) { - WorkerTask annotation = method.getAnnotation(WorkerTask.class); - if (annotation == null) { - continue; - } - addMethod(annotation, method, bean); - } - } - - private void addMethod(WorkerTask annotation, Method method, Object bean) { - String name = annotation.value(); - - int threadCount = workerConfiguration.getThreadCount(name); - if (threadCount == 0) { - threadCount = annotation.threadCount(); - } - workerToThreadCount.put(name, threadCount); - - int pollingInterval = workerConfiguration.getPollingInterval(name); - if (pollingInterval == 0) { - pollingInterval = annotation.pollingInterval(); - } - workerToPollingInterval.put(name, pollingInterval); - - String domain = workerConfiguration.getDomain(name); - if (Strings.isNullOrEmpty(domain)) { - domain = annotation.domain(); - } - if (!Strings.isNullOrEmpty(domain)) { - workerDomains.put(name, domain); - } - - workerClassObjs.put(name, bean); - workerExecutors.put(name, method); - LOGGER.info( - "Adding worker for task {}, method {} with threadCount {} and polling interval set to {} ms", - name, - method, - threadCount, - pollingInterval); - } - - public void startPolling() { - workerExecutors.forEach( - (taskName, method) -> { - Object obj = workerClassObjs.get(taskName); - AnnotatedWorker executor = new AnnotatedWorker(taskName, method, obj); - for (Module module : modules) { - executor.registerModule(module); - } - executor.setPollingInterval(workerToPollingInterval.get(taskName)); - executors.add(executor); - }); - - if (executors.isEmpty()) { - return; - } - - LOGGER.info("Starting workers with threadCount {}", workerToThreadCount); - LOGGER.info("Worker domains {}", workerDomains); - - taskRunner = - new TaskRunnerConfigurer.Builder(taskClient, executors) - .withTaskThreadCount(workerToThreadCount) - .withTaskToDomain(workerDomains) - .build(); - - taskRunner.init(); - } - - @VisibleForTesting - List getExecutors() { - return executors; - } - - @VisibleForTesting - TaskRunnerConfigurer getTaskRunner() { - return taskRunner; - } - - public void registerModule(Module module) { - modules.add(module); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/DynamicForkWorker.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/DynamicForkWorker.java deleted file mode 100644 index 0ba1d6114..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/DynamicForkWorker.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.executor.task; - -import java.lang.reflect.Method; -import java.util.Map; -import java.util.function.Function; - -import com.netflix.conductor.client.worker.Worker; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.metadata.tasks.TaskResult; -import com.netflix.conductor.sdk.workflow.def.tasks.DynamicFork; -import com.netflix.conductor.sdk.workflow.def.tasks.DynamicForkInput; -import com.netflix.conductor.sdk.workflow.task.InputParam; -import com.netflix.conductor.sdk.workflow.utils.ObjectMapperProvider; - -import com.fasterxml.jackson.databind.ObjectMapper; - -public class DynamicForkWorker implements Worker { - - private final int pollingInterval; - - private final Function workerMethod; - - private final String name; - - private ObjectMapper objectMapper = new ObjectMapperProvider().getObjectMapper(); - - public DynamicForkWorker( - String name, Function workerMethod, int pollingInterval) { - this.name = name; - this.workerMethod = workerMethod; - this.pollingInterval = pollingInterval; - } - - @Override - public String getTaskDefName() { - return name; - } - - @Override - public TaskResult execute(Task task) { - TaskResult result = new TaskResult(task); - try { - - Object parameter = getInvocationParameters(this.workerMethod, task); - DynamicForkInput output = this.workerMethod.apply(parameter); - result.getOutputData().put(DynamicFork.FORK_TASK_PARAM, output.getTasks()); - result.getOutputData().put(DynamicFork.FORK_TASK_INPUT_PARAM, output.getInputs()); - result.setStatus(TaskResult.Status.COMPLETED); - - } catch (Exception e) { - throw new RuntimeException(e); - } - return result; - } - - @Override - public int getPollingInterval() { - return pollingInterval; - } - - private Object getInvocationParameters(Function function, Task task) { - InputParam annotation = null; - Class parameterType = null; - for (Method method : function.getClass().getDeclaredMethods()) { - if (method.getReturnType().equals(DynamicForkInput.class)) { - annotation = method.getParameters()[0].getAnnotation(InputParam.class); - parameterType = method.getParameters()[0].getType(); - } - } - - if (parameterType.equals(Task.class)) { - return task; - } else if (parameterType.equals(Map.class)) { - return task.getInputData(); - } - if (annotation != null) { - String name = annotation.value(); - Object value = task.getInputData().get(name); - return objectMapper.convertValue(value, parameterType); - } - return objectMapper.convertValue(task.getInputData(), parameterType); - } - - public static void main(String[] args) { - Function fn = - new Function() { - @Override - public DynamicForkInput apply(@InputParam("a") TaskDef s) { - return null; - } - }; - - for (Method method : fn.getClass().getDeclaredMethods()) { - if (method.getReturnType().equals(DynamicForkInput.class)) { - System.out.println( - "\n\n-->method: " - + method - + ", input: " - + method.getParameters()[0].getType()); - System.out.println("I take input as " + method.getParameters()[0].getType()); - InputParam annotation = method.getParameters()[0].getAnnotation(InputParam.class); - System.out.println("I have annotation " + annotation); - } - } - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/NonRetryableException.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/NonRetryableException.java deleted file mode 100644 index 61b70fdc7..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/NonRetryableException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2023 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.executor.task; - -/** - * Runtime exception indicating the non-retriable error with the task execution. If thrown, the task - * will fail with FAILED_WITH_TERMINAL_ERROR and will not kick off retries. - */ -public class NonRetryableException extends RuntimeException { - - public NonRetryableException(String message) { - super(message); - } - - public NonRetryableException(String message, Throwable cause) { - super(message, cause); - } - - public NonRetryableException(Throwable cause) { - super(cause); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/TaskContext.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/TaskContext.java deleted file mode 100644 index f78d13e50..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/TaskContext.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2023 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.executor.task; - -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.TaskResult; - -/** Context for the task */ -public class TaskContext { - - public static final ThreadLocal TASK_CONTEXT_INHERITABLE_THREAD_LOCAL = - InheritableThreadLocal.withInitial(() -> null); - - public TaskContext(Task task, TaskResult taskResult) { - this.task = task; - this.taskResult = taskResult; - } - - public static TaskContext get() { - return TASK_CONTEXT_INHERITABLE_THREAD_LOCAL.get(); - } - - public static TaskContext set(Task task) { - TaskResult result = new TaskResult(task); - TaskContext context = new TaskContext(task, result); - TASK_CONTEXT_INHERITABLE_THREAD_LOCAL.set(context); - return context; - } - - private final Task task; - - private final TaskResult taskResult; - - public String getWorkflowInstanceId() { - return task.getWorkflowInstanceId(); - } - - public String getTaskId() { - return task.getTaskId(); - } - - public int getRetryCount() { - return task.getRetryCount(); - } - - public int getPollCount() { - return task.getPollCount(); - } - - public long getCallbackAfterSeconds() { - return task.getCallbackAfterSeconds(); - } - - public void addLog(String log) { - this.taskResult.log(log); - } - - public Task getTask() { - return task; - } - - public TaskResult getTaskResult() { - return taskResult; - } - - public void setCallbackAfter(int seconds) { - this.taskResult.setCallbackAfterSeconds(seconds); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/WorkerConfiguration.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/WorkerConfiguration.java deleted file mode 100644 index 45a615773..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/task/WorkerConfiguration.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2023 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.executor.task; - -public class WorkerConfiguration { - - private int defaultPollingInterval = 0; - - public WorkerConfiguration(int defaultPollingInterval) { - this.defaultPollingInterval = defaultPollingInterval; - } - - public WorkerConfiguration() {} - - public int getPollingInterval(String taskName) { - return defaultPollingInterval; - } - - public int getThreadCount(String taskName) { - return 0; - } - - public String getDomain(String taskName) { - return null; - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/InputParam.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/InputParam.java deleted file mode 100644 index 2afa8bc42..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/InputParam.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.task; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.PARAMETER) -public @interface InputParam { - String value(); - - boolean required() default false; -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/OutputParam.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/OutputParam.java deleted file mode 100644 index 3c1251317..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/OutputParam.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.task; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE_USE) -public @interface OutputParam { - String value(); -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/WorkerTask.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/WorkerTask.java deleted file mode 100644 index f60783124..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/task/WorkerTask.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.task; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** Identifies a simple worker task. */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD}) -public @interface WorkerTask { - String value(); - - // No. of threads to use for executing the task - int threadCount() default 1; - - int pollingInterval() default 100; - - String domain() default ""; -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/InputOutputGetter.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/InputOutputGetter.java deleted file mode 100644 index 4e8e34832..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/InputOutputGetter.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.utils; - -import com.fasterxml.jackson.annotation.JsonIgnore; - -public class InputOutputGetter { - - public enum Field { - input, - output - } - - public static final class Map { - private final String parent; - - public Map(String parent) { - this.parent = parent; - } - - public String get(String key) { - return parent + "." + key + "}"; - } - - public Map map(String key) { - return new Map(parent + "." + key); - } - - public List list(String key) { - return new List(parent + "." + key); - } - - @Override - public String toString() { - return parent + "}"; - } - } - - public static final class List { - - private final String parent; - - public List(String parent) { - this.parent = parent; - } - - public List list(String key) { - return new List(parent + "." + key); - } - - public Map map(String key) { - return new Map(parent + "." + key); - } - - public String get(String key, int index) { - return parent + "." + key + "[" + index + "]}"; - } - - public String get(int index) { - return parent + "[" + index + "]}"; - } - - @Override - public String toString() { - return parent + "}"; - } - } - - private final String name; - - private final Field field; - - public InputOutputGetter(String name, Field field) { - this.name = name; - this.field = field; - } - - public String get(String key) { - return "${" + name + "." + field + "." + key + "}"; - } - - public String getParent() { - return "${" + name + "." + field + "}"; - } - - @JsonIgnore - public Map map(String key) { - return new Map("${" + name + "." + field + "." + key); - } - - @JsonIgnore - public List list(String key) { - return new List("${" + name + "." + field + "." + key); - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/MapBuilder.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/MapBuilder.java deleted file mode 100644 index 3882324b4..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/MapBuilder.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.utils; - -import java.util.HashMap; -import java.util.Map; - -public class MapBuilder { - private Map map = new HashMap<>(); - - public MapBuilder add(String key, String value) { - map.put(key, value); - return this; - } - - public MapBuilder add(String key, Number value) { - map.put(key, value); - return this; - } - - public MapBuilder add(String key, MapBuilder value) { - map.put(key, value.build()); - return this; - } - - public Map build() { - return map; - } -} diff --git a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/ObjectMapperProvider.java b/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/ObjectMapperProvider.java deleted file mode 100644 index 1721c8236..000000000 --- a/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/utils/ObjectMapperProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.utils; - -import com.netflix.conductor.common.jackson.JsonProtoModule; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; - -public class ObjectMapperProvider { - - public ObjectMapper getObjectMapper() { - final ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false); - objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false); - objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); - - objectMapper.setDefaultPropertyInclusion( - JsonInclude.Value.construct( - JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_EMPTY)); - objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); - // objectMapper.setSerializationInclusion(JsonInclude.Include.); - - objectMapper.registerModule(new JsonProtoModule()); - return objectMapper; - } -} diff --git a/java-sdk/src/main/resources/test-server.properties b/java-sdk/src/main/resources/test-server.properties deleted file mode 100644 index 900b554d3..000000000 --- a/java-sdk/src/main/resources/test-server.properties +++ /dev/null @@ -1,5 +0,0 @@ -conductor.db.type=memory -conductor.indexing.enabled=false -conductor.workflow-repair-service.enabled=false -loadSample=true -conductor.system-task-workers.enabled=false \ No newline at end of file diff --git a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/TaskConversionsTests.java b/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/TaskConversionsTests.java deleted file mode 100644 index 9804f1a43..000000000 --- a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/TaskConversionsTests.java +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def; - -import java.time.Duration; -import java.time.ZonedDateTime; -import java.time.temporal.ChronoUnit; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.Test; - -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; -import com.netflix.conductor.sdk.workflow.def.tasks.*; -import com.netflix.conductor.sdk.workflow.executor.WorkflowExecutor; - -import static org.junit.jupiter.api.Assertions.*; - -public class TaskConversionsTests { - - static { - WorkflowExecutor.initTaskImplementations(); - } - - @Test - public void testSimpleTaskConversion() { - SimpleTask simpleTask = new SimpleTask("task_name", "task_ref_name"); - - Map map = new HashMap<>(); - map.put("key11", "value11"); - map.put("key12", 100); - - simpleTask.input("key1", "value"); - simpleTask.input("key2", 42); - simpleTask.input("key3", true); - simpleTask.input("key4", map); - - WorkflowTask workflowTask = simpleTask.getWorkflowDefTasks().get(0); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue(fromWorkflowTask instanceof SimpleTask); - SimpleTask simpleTaskFromWorkflowTask = (SimpleTask) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(simpleTask.getName(), fromWorkflowTask.getName()); - assertEquals(simpleTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(simpleTask.getTaskDef(), simpleTaskFromWorkflowTask.getTaskDef()); - assertEquals(simpleTask.getType(), simpleTaskFromWorkflowTask.getType()); - assertEquals(simpleTask.getStartDelay(), simpleTaskFromWorkflowTask.getStartDelay()); - assertEquals(simpleTask.getInput(), simpleTaskFromWorkflowTask.getInput()); - } - - @Test - public void testDynamicTaskCoversion() { - Dynamic dynamicTask = new Dynamic("task_name", "task_ref_name"); - - WorkflowTask workflowTask = dynamicTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters().get(Dynamic.TASK_NAME_INPUT_PARAM)); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue(fromWorkflowTask instanceof Dynamic); - Dynamic taskFromWorkflowTask = (Dynamic) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(dynamicTask.getName(), fromWorkflowTask.getName()); - assertEquals(dynamicTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(dynamicTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(dynamicTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(dynamicTask.getInput(), taskFromWorkflowTask.getInput()); - } - - @Test - public void testForkTaskConversion() { - SimpleTask task1 = new SimpleTask("task1", "task1"); - SimpleTask task2 = new SimpleTask("task2", "task2"); - SimpleTask task3 = new SimpleTask("task3", "task3"); - - ForkJoin forkTask = - new ForkJoin("task_ref_name", new Task[] {task1}, new Task[] {task2, task3}); - - WorkflowTask workflowTask = forkTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getForkTasks()); - assertFalse(workflowTask.getForkTasks().isEmpty()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue(fromWorkflowTask instanceof ForkJoin); - ForkJoin taskFromWorkflowTask = (ForkJoin) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(forkTask.getName(), fromWorkflowTask.getName()); - assertEquals(forkTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(forkTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(forkTask.getInput(), taskFromWorkflowTask.getInput()); - - assertEquals( - forkTask.getForkedTasks().length, taskFromWorkflowTask.getForkedTasks().length); - for (int i = 0; i < forkTask.getForkedTasks().length; i++) { - assertEquals( - forkTask.getForkedTasks()[i].length, - taskFromWorkflowTask.getForkedTasks()[i].length); - for (int j = 0; j < forkTask.getForkedTasks()[i].length; j++) { - assertEquals( - forkTask.getForkedTasks()[i][j].getTaskReferenceName(), - taskFromWorkflowTask.getForkedTasks()[i][j].getTaskReferenceName()); - - assertEquals( - forkTask.getForkedTasks()[i][j].getName(), - taskFromWorkflowTask.getForkedTasks()[i][j].getName()); - - assertEquals( - forkTask.getForkedTasks()[i][j].getType(), - taskFromWorkflowTask.getForkedTasks()[i][j].getType()); - } - } - } - - @Test - public void testDynamicForkTaskCoversion() { - DynamicFork dynamicTask = new DynamicFork("task_ref_name", "forkTasks", "forkTaskInputs"); - - WorkflowTask workflowTask = dynamicTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue(fromWorkflowTask instanceof DynamicFork); - DynamicFork taskFromWorkflowTask = (DynamicFork) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(dynamicTask.getName(), fromWorkflowTask.getName()); - assertEquals(dynamicTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(dynamicTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(dynamicTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(dynamicTask.getInput(), taskFromWorkflowTask.getInput()); - assertEquals( - dynamicTask.getForkTasksParameter(), taskFromWorkflowTask.getForkTasksParameter()); - assertEquals( - dynamicTask.getForkTasksInputsParameter(), - taskFromWorkflowTask.getForkTasksInputsParameter()); - } - - @Test - public void testDoWhileConversion() { - SimpleTask task1 = new SimpleTask("task_name", "task_ref_name"); - SimpleTask task2 = new SimpleTask("task_name", "task_ref_name"); - - DoWhile doWhileTask = new DoWhile("task_ref_name", 2, task1, task2); - - WorkflowTask workflowTask = doWhileTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue(fromWorkflowTask instanceof DoWhile); - DoWhile taskFromWorkflowTask = (DoWhile) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(doWhileTask.getName(), fromWorkflowTask.getName()); - assertEquals(doWhileTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(doWhileTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(doWhileTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(doWhileTask.getInput(), taskFromWorkflowTask.getInput()); - - assertEquals(doWhileTask.getLoopCondition(), taskFromWorkflowTask.getLoopCondition()); - assertEquals( - doWhileTask.getLoopTasks().stream() - .map(task -> task.getTaskReferenceName()) - .sorted() - .collect(Collectors.toSet()), - taskFromWorkflowTask.getLoopTasks().stream() - .map(task -> task.getTaskReferenceName()) - .sorted() - .collect(Collectors.toSet())); - } - - @Test - public void testJoin() { - - Join joinTask = new Join("task_ref_name", "task1", "task2"); - - WorkflowTask workflowTask = joinTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - assertNotNull(workflowTask.getJoinOn()); - assertTrue(!workflowTask.getJoinOn().isEmpty()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue( - fromWorkflowTask instanceof Join, - "task is not of type Join, but of type " + fromWorkflowTask.getClass().getName()); - Join taskFromWorkflowTask = (Join) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(joinTask.getName(), fromWorkflowTask.getName()); - assertEquals(joinTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(joinTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(joinTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(joinTask.getInput(), taskFromWorkflowTask.getInput()); - - assertEquals(joinTask.getJoinOn().length, taskFromWorkflowTask.getJoinOn().length); - assertEquals( - Arrays.asList(joinTask.getJoinOn()).stream().sorted().collect(Collectors.toSet()), - Arrays.asList(taskFromWorkflowTask.getJoinOn()).stream() - .sorted() - .collect(Collectors.toSet())); - } - - @Test - public void testEvent() { - - Event eventTask = new Event("task_ref_name", "sqs:queue11"); - - WorkflowTask workflowTask = eventTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue( - fromWorkflowTask instanceof Event, - "task is not of type Event, but of type " + fromWorkflowTask.getClass().getName()); - Event taskFromWorkflowTask = (Event) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(eventTask.getName(), fromWorkflowTask.getName()); - assertEquals(eventTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(eventTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(eventTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(eventTask.getInput(), taskFromWorkflowTask.getInput()); - assertEquals(eventTask.getSink(), taskFromWorkflowTask.getSink()); - } - - @Test - public void testSetVariableConversion() { - - SetVariable setVariableTask = new SetVariable("task_ref_name"); - - WorkflowTask workflowTask = setVariableTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue( - fromWorkflowTask instanceof SetVariable, - "task is not of type SetVariable, but of type " - + fromWorkflowTask.getClass().getName()); - SetVariable taskFromWorkflowTask = (SetVariable) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(setVariableTask.getName(), fromWorkflowTask.getName()); - assertEquals( - setVariableTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(setVariableTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(setVariableTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(setVariableTask.getInput(), taskFromWorkflowTask.getInput()); - } - - @Test - public void testSubWorkflowConversion() { - - SubWorkflow subWorkflowTask = new SubWorkflow("task_ref_name", "sub_flow", 2); - - WorkflowTask workflowTask = subWorkflowTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue( - fromWorkflowTask instanceof SubWorkflow, - "task is not of type SubWorkflow, but of type " - + fromWorkflowTask.getClass().getName()); - SubWorkflow taskFromWorkflowTask = (SubWorkflow) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(subWorkflowTask.getName(), fromWorkflowTask.getName()); - assertEquals( - subWorkflowTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(subWorkflowTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(subWorkflowTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(subWorkflowTask.getInput(), taskFromWorkflowTask.getInput()); - assertEquals(subWorkflowTask.getWorkflowName(), taskFromWorkflowTask.getWorkflowName()); - assertEquals( - subWorkflowTask.getWorkflowVersion(), taskFromWorkflowTask.getWorkflowVersion()); - } - - @Test - public void testSwitchConversion() { - - SimpleTask task1 = new SimpleTask("task_name", "task_ref_name1"); - SimpleTask task2 = new SimpleTask("task_name", "task_ref_name2"); - SimpleTask task3 = new SimpleTask("task_name", "task_ref_name3"); - - Switch decision = new Switch("switch", "${workflow.input.zip"); - decision.switchCase("caseA", task1); - decision.switchCase("caseB", task2, task3); - - decision.defaultCase( - new Terminate("terminate", Workflow.WorkflowStatus.FAILED, "", new HashMap<>())); - - WorkflowTask workflowTask = decision.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue( - fromWorkflowTask instanceof Switch, - "task is not of type Switch, but of type " + fromWorkflowTask.getClass().getName()); - Switch taskFromWorkflowTask = (Switch) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(decision.getName(), fromWorkflowTask.getName()); - assertEquals(decision.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(decision.getType(), taskFromWorkflowTask.getType()); - assertEquals(decision.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(decision.getInput(), taskFromWorkflowTask.getInput()); - // TODO: ADD CASES FOR DEFAULT CASE - assertEquals(decision.getBranches().keySet(), taskFromWorkflowTask.getBranches().keySet()); - assertEquals( - decision.getBranches().values().stream() - .map( - tasks -> - tasks.stream() - .map(Task::getTaskReferenceName) - .collect(Collectors.toSet())) - .collect(Collectors.toSet()), - taskFromWorkflowTask.getBranches().values().stream() - .map( - tasks -> - tasks.stream() - .map(Task::getTaskReferenceName) - .collect(Collectors.toSet())) - .collect(Collectors.toSet())); - assertEquals(decision.getBranches().size(), taskFromWorkflowTask.getBranches().size()); - } - - @Test - public void testTerminateConversion() { - - Terminate terminateTask = - new Terminate("terminate", Workflow.WorkflowStatus.FAILED, "", new HashMap<>()); - - WorkflowTask workflowTask = terminateTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue( - fromWorkflowTask instanceof Terminate, - "task is not of type Terminate, but of type " - + fromWorkflowTask.getClass().getName()); - Terminate taskFromWorkflowTask = (Terminate) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(terminateTask.getName(), fromWorkflowTask.getName()); - assertEquals(terminateTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(terminateTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(terminateTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(terminateTask.getInput(), taskFromWorkflowTask.getInput()); - } - - @Test - public void testWaitConversion() { - - Wait waitTask = new Wait("terminate"); - - WorkflowTask workflowTask = waitTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue( - fromWorkflowTask instanceof Wait, - "task is not of type Wait, but of type " + fromWorkflowTask.getClass().getName()); - Wait taskFromWorkflowTask = (Wait) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(waitTask.getName(), fromWorkflowTask.getName()); - assertEquals(waitTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(waitTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(waitTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(waitTask.getInput(), taskFromWorkflowTask.getInput()); - - // Wait for 10 seconds - waitTask = new Wait("wait_for_10_seconds", Duration.of(10, ChronoUnit.SECONDS)); - workflowTask = waitTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - assertEquals("10s", workflowTask.getInputParameters().get(Wait.DURATION_INPUT)); - - // Wait for 10 minutes - waitTask = new Wait("wait_for_10_seconds", Duration.of(10, ChronoUnit.MINUTES)); - workflowTask = waitTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - assertEquals("600s", workflowTask.getInputParameters().get(Wait.DURATION_INPUT)); - - // Wait till next week some time - ZonedDateTime nextWeek = ZonedDateTime.now().plusDays(7); - String formattedDateTime = Wait.dateTimeFormatter.format(nextWeek); - waitTask = new Wait("wait_till_next_week", nextWeek); - workflowTask = waitTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - assertEquals(formattedDateTime, workflowTask.getInputParameters().get(Wait.UNTIL_INPUT)); - } - - @Test - public void testHttpConverter() { - - Http httpTask = new Http("terminate"); - Http.Input input = new Http.Input(); - input.setUri("http://example.com"); - input.setMethod(Http.Input.HttpMethod.POST); - input.setBody("Hello World"); - input.setReadTimeOut(100); - Map headers = new HashMap<>(); - headers.put("X-AUTHORIZATION", "my_api_key"); - input.setHeaders(headers); - - httpTask.input(input); - - WorkflowTask workflowTask = httpTask.getWorkflowDefTasks().get(0); - assertNotNull(workflowTask.getInputParameters()); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue( - fromWorkflowTask instanceof Http, - "task is not of type Http, but of type " + fromWorkflowTask.getClass().getName()); - Http taskFromWorkflowTask = (Http) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(httpTask.getName(), fromWorkflowTask.getName()); - assertEquals(httpTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(httpTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(httpTask.getStartDelay(), taskFromWorkflowTask.getStartDelay()); - assertEquals(httpTask.getInput(), taskFromWorkflowTask.getInput()); - assertEquals(httpTask.getHttpRequest(), taskFromWorkflowTask.getHttpRequest()); - - System.out.println(httpTask.getInput()); - System.out.println(taskFromWorkflowTask.getInput()); - } - - @Test - public void testJQTaskConversion() { - JQ jqTask = new JQ("task_name", "{ key3: (.key1.value1 + .key2.value2) }"); - - Map map = new HashMap<>(); - map.put("key11", "value11"); - map.put("key12", 100); - - jqTask.input("key1", "value"); - jqTask.input("key2", 42); - jqTask.input("key3", true); - jqTask.input("key4", map); - - WorkflowTask workflowTask = jqTask.getWorkflowDefTasks().get(0); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue(fromWorkflowTask instanceof JQ, "Found the instance " + fromWorkflowTask); - JQ taskFromWorkflowTask = (JQ) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(jqTask.getName(), fromWorkflowTask.getName()); - assertEquals(jqTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(jqTask.getQueryExpression(), taskFromWorkflowTask.getQueryExpression()); - assertEquals(jqTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(jqTask.getInput(), taskFromWorkflowTask.getInput()); - } - - @Test - public void testInlineTaskConversion() { - - Javascript inlineTask = - new Javascript( - "task_name", - "function e() { if ($.value == 1){return {\"result\": true}} else { return {\"result\": false}}} e();"); - inlineTask.validate(); - - Map map = new HashMap<>(); - map.put("key11", "value11"); - map.put("key12", 100); - - inlineTask.input("key1", "value"); - inlineTask.input("key2", 42); - inlineTask.input("key3", true); - inlineTask.input("key4", map); - - WorkflowTask workflowTask = inlineTask.getWorkflowDefTasks().get(0); - - Task fromWorkflowTask = TaskRegistry.getTask(workflowTask); - assertTrue( - fromWorkflowTask instanceof Javascript, "Found the instance " + fromWorkflowTask); - Javascript taskFromWorkflowTask = (Javascript) fromWorkflowTask; - - assertNotNull(fromWorkflowTask); - assertEquals(inlineTask.getName(), fromWorkflowTask.getName()); - assertEquals(inlineTask.getTaskReferenceName(), fromWorkflowTask.getTaskReferenceName()); - assertEquals(inlineTask.getExpression(), taskFromWorkflowTask.getExpression()); - assertEquals(inlineTask.getType(), taskFromWorkflowTask.getType()); - assertEquals(inlineTask.getInput(), taskFromWorkflowTask.getInput()); - } - - @Test - public void testJavascriptValidation() { - // This script has errors - Javascript inlineTask = - new Javascript( - "task_name", - "function e() { if ($.value ==> 1){return {\"result\": true}} else { return {\"result\": false}}} e();"); - boolean failed = false; - try { - inlineTask.validate(); - } catch (ValidationError ve) { - failed = true; - } - - assertTrue(failed); - - // This script does NOT have errors - inlineTask = - new Javascript( - "task_name", - "function e() { if ($.value == 1){return {\"result\": true}} else { return {\"result\": false}}} e();"); - failed = false; - try { - inlineTask.validate(); - } catch (ValidationError ve) { - failed = true; - } - - assertFalse(failed); - } -} diff --git a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowCreationTests.java b/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowCreationTests.java deleted file mode 100644 index 90822697f..000000000 --- a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowCreationTests.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.netflix.conductor.common.metadata.tasks.TaskType; -import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; -import com.netflix.conductor.sdk.testing.WorkflowTestRunner; -import com.netflix.conductor.sdk.workflow.def.tasks.*; -import com.netflix.conductor.sdk.workflow.executor.WorkflowExecutor; -import com.netflix.conductor.sdk.workflow.task.InputParam; -import com.netflix.conductor.sdk.workflow.task.OutputParam; -import com.netflix.conductor.sdk.workflow.task.WorkerTask; -import com.netflix.conductor.sdk.workflow.testing.TestWorkflowInput; - -import static org.junit.jupiter.api.Assertions.*; - -@Disabled -public class WorkflowCreationTests { - - private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowCreationTests.class); - - private static WorkflowExecutor executor; - - private static WorkflowTestRunner runner; - - @BeforeAll - public static void init() throws IOException { - runner = new WorkflowTestRunner(8080, "3.7.3"); - runner.init("com.netflix.conductor.sdk"); - executor = runner.getWorkflowExecutor(); - } - - @AfterAll - public static void cleanUp() { - runner.shutdown(); - } - - @WorkerTask("get_user_info") - public @OutputParam("zipCode") String getZipCode(@InputParam("name") String userName) { - return "95014"; - } - - @WorkerTask("task2") - public @OutputParam("greetings") String task2() { - return "Hello World"; - } - - @WorkerTask("task3") - public @OutputParam("greetings") String task3() { - return "Hello World-3"; - } - - @WorkerTask("fork_gen") - public DynamicForkInput generateDynamicFork() { - DynamicForkInput forks = new DynamicForkInput(); - Map inputs = new HashMap<>(); - forks.setInputs(inputs); - List> tasks = new ArrayList<>(); - forks.setTasks(tasks); - - for (int i = 0; i < 3; i++) { - SimpleTask task = new SimpleTask("task2", "fork_task_" + i); - tasks.add(task); - HashMap taskInput = new HashMap<>(); - taskInput.put("key", "value"); - taskInput.put("key2", 101); - inputs.put(task.getTaskReferenceName(), taskInput); - } - return forks; - } - - private ConductorWorkflow registerTestWorkflow() - throws InterruptedException { - InputStream script = getClass().getResourceAsStream("/script.js"); - SimpleTask getUserInfo = new SimpleTask("get_user_info", "get_user_info"); - getUserInfo.input("name", ConductorWorkflow.input.get("name")); - - SimpleTask sendToCupertino = new SimpleTask("task2", "cupertino"); - SimpleTask sendToNYC = new SimpleTask("task2", "nyc"); - - int len = 4; - Task[][] parallelTasks = new Task[len][1]; - for (int i = 0; i < len; i++) { - parallelTasks[i][0] = new SimpleTask("task2", "task_parallel_" + i); - } - - WorkflowBuilder builder = new WorkflowBuilder<>(executor); - TestWorkflowInput defaultInput = new TestWorkflowInput(); - defaultInput.setName("defaultName"); - - builder.name("sdk_workflow_example") - .version(1) - .ownerEmail("hello@example.com") - .description("Example Workflow") - .restartable(true) - .variables(new WorkflowState()) - .timeoutPolicy(WorkflowDef.TimeoutPolicy.TIME_OUT_WF, 100) - .defaultInput(defaultInput) - .add(new Javascript("js", script)) - .add(new ForkJoin("parallel", parallelTasks)) - .add(getUserInfo) - .add( - new Switch("decide2", "${workflow.input.zipCode}") - .switchCase("95014", sendToCupertino) - .switchCase("10121", sendToNYC)) - // .add(new SubWorkflow("subflow", "sub_workflow_example", 5)) - .add(new SimpleTask("task2", "task222")) - .add(new DynamicFork("dynamic_fork", new SimpleTask("fork_gen", "fork_gen"))); - - ConductorWorkflow workflow = builder.build(); - boolean registered = workflow.registerWorkflow(true, true); - assertTrue(registered); - - return workflow; - } - - @Test - public void verifyCreatedWorkflow() throws Exception { - ConductorWorkflow conductorWorkflow = registerTestWorkflow(); - WorkflowDef def = conductorWorkflow.toWorkflowDef(); - assertNotNull(def); - assertTrue( - def.getTasks() - .get(def.getTasks().size() - 2) - .getType() - .equals(TaskType.TASK_TYPE_FORK_JOIN_DYNAMIC)); - assertTrue( - def.getTasks() - .get(def.getTasks().size() - 1) - .getType() - .equals(TaskType.TASK_TYPE_JOIN)); - } - - @Test - public void verifyInlineWorkflowExecution() throws ValidationError { - TestWorkflowInput workflowInput = new TestWorkflowInput("username", "10121", "US"); - try { - Workflow run = registerTestWorkflow().execute(workflowInput).get(10, TimeUnit.SECONDS); - assertEquals( - Workflow.WorkflowStatus.COMPLETED, - run.getStatus(), - run.getReasonForIncompletion()); - } catch (Exception e) { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - @Test - public void testWorkflowExecutionByName() throws ExecutionException, InterruptedException { - - // Register the workflow first - registerTestWorkflow(); - - TestWorkflowInput input = new TestWorkflowInput("username", "10121", "US"); - - ConductorWorkflow conductorWorkflow = - new ConductorWorkflow(executor) - .from("sdk_workflow_example", null); - - CompletableFuture execution = conductorWorkflow.execute(input); - try { - execution.get(10, TimeUnit.SECONDS); - } catch (Exception e) { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - @Test - public void verifyWorkflowExecutionFailsIfNotExists() - throws ExecutionException, InterruptedException { - - // Register the workflow first - registerTestWorkflow(); - - TestWorkflowInput input = new TestWorkflowInput("username", "10121", "US"); - - try { - ConductorWorkflow conductorWorkflow = - new ConductorWorkflow(executor) - .from("non_existent_workflow", null); - conductorWorkflow.execute(input); - fail("execution should have failed"); - } catch (Exception e) { - } - } -} diff --git a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowDefTaskTests.java b/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowDefTaskTests.java deleted file mode 100644 index 31218f129..000000000 --- a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowDefTaskTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def; - -import org.junit.jupiter.api.Test; - -import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.sdk.workflow.def.tasks.*; -import com.netflix.conductor.sdk.workflow.executor.WorkflowExecutor; - -import static org.junit.jupiter.api.Assertions.*; - -public class WorkflowDefTaskTests { - - static { - WorkflowExecutor.initTaskImplementations(); - } - - @Test - public void testWorkflowDefTaskWithStartDelay() { - SimpleTask simpleTask = new SimpleTask("task_name", "task_ref_name"); - int startDelay = 5; - - simpleTask.setStartDelay(startDelay); - - WorkflowTask workflowTask = simpleTask.getWorkflowDefTasks().get(0); - - assertEquals(simpleTask.getStartDelay(), workflowTask.getStartDelay()); - assertEquals(startDelay, simpleTask.getStartDelay()); - assertEquals(startDelay, workflowTask.getStartDelay()); - } - - @Test - public void testWorkflowDefTaskWithOptionalEnabled() { - SimpleTask simpleTask = new SimpleTask("task_name", "task_ref_name"); - - simpleTask.setOptional(true); - - WorkflowTask workflowTask = simpleTask.getWorkflowDefTasks().get(0); - - assertEquals(simpleTask.getStartDelay(), workflowTask.getStartDelay()); - assertEquals(true, simpleTask.isOptional()); - assertEquals(true, workflowTask.isOptional()); - } -} diff --git a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowState.java b/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowState.java deleted file mode 100644 index 05dce8080..000000000 --- a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/def/WorkflowState.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.def; - -public class WorkflowState { - - private boolean paymentCompleted; - - private int timeTaken; - - public boolean isPaymentCompleted() { - return paymentCompleted; - } - - public void setPaymentCompleted(boolean paymentCompleted) { - this.paymentCompleted = paymentCompleted; - } - - public int getTimeTaken() { - return timeTaken; - } - - public void setTimeTaken(int timeTaken) { - this.timeTaken = timeTaken; - } -} diff --git a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorkerTests.java b/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorkerTests.java deleted file mode 100644 index 84111ebb0..000000000 --- a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/executor/task/AnnotatedWorkerTests.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.executor.task; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import com.netflix.conductor.client.automator.TaskRunnerConfigurer; -import com.netflix.conductor.client.http.TaskClient; -import com.netflix.conductor.client.worker.Worker; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.sdk.workflow.task.InputParam; -import com.netflix.conductor.sdk.workflow.task.OutputParam; -import com.netflix.conductor.sdk.workflow.task.WorkerTask; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; - -public class AnnotatedWorkerTests { - - static class Car { - String brand; - - String getBrand() { - return brand; - } - - void setBrand(String brand) { - this.brand = brand; - } - } - - static class Bike { - String brand; - - String getBrand() { - return brand; - } - - void setBrand(String brand) { - this.brand = brand; - } - } - - static class CarWorker { - @WorkerTask("test_1") - public @OutputParam("result") List doWork(@InputParam("input") List input) { - return input; - } - } - - @Test - @DisplayName("it should handle null values when InputParam is a List") - void nullListAsInputParam() throws NoSuchMethodException { - var worker = new CarWorker(); - var annotatedWorker = - new AnnotatedWorker( - "test_1", worker.getClass().getMethod("doWork", List.class), worker); - - var task = new Task(); - task.setStatus(Task.Status.IN_PROGRESS); - - var result0 = annotatedWorker.execute(task); - var outputData = result0.getOutputData(); - assertNull(outputData.get("result")); - } - - @Test - @DisplayName("it should handle an empty List as InputParam") - void emptyListAsInputParam() throws NoSuchMethodException { - var worker = new CarWorker(); - var annotatedWorker = - new AnnotatedWorker( - "test_1", worker.getClass().getMethod("doWork", List.class), worker); - - var task = new Task(); - task.setStatus(Task.Status.IN_PROGRESS); - task.setInputData(Map.of("input", List.of())); - - var result0 = annotatedWorker.execute(task); - var outputData = result0.getOutputData(); - - @SuppressWarnings("unchecked") - List result = (List) outputData.get("result"); - assertTrue(result.isEmpty()); - } - - @Test - @DisplayName("it should handle a non empty List as InputParam") - void nonEmptyListAsInputParam() throws NoSuchMethodException { - var worker = new CarWorker(); - var annotatedWorker = - new AnnotatedWorker( - "test_1", worker.getClass().getMethod("doWork", List.class), worker); - - var task = new Task(); - task.setStatus(Task.Status.IN_PROGRESS); - task.setInputData(Map.of("input", List.of(Map.of("brand", "BMW")))); - - var result0 = annotatedWorker.execute(task); - var outputData = result0.getOutputData(); - - @SuppressWarnings("unchecked") - List result = (List) outputData.get("result"); - assertEquals(1, result.size()); - - Car car = result.get(0); - assertEquals("BMW", car.getBrand()); - } - - @SuppressWarnings("rawtypes") - static class RawListInput { - @WorkerTask("test_1") - public @OutputParam("result") List doWork(@InputParam("input") List input) { - return input; - } - } - - @Test - @DisplayName("it should handle a Raw List Type as InputParam") - void rawListAsInputParam() throws NoSuchMethodException { - var worker = new RawListInput(); - var annotatedWorker = - new AnnotatedWorker( - "test_1", worker.getClass().getMethod("doWork", List.class), worker); - - var task = new Task(); - task.setStatus(Task.Status.IN_PROGRESS); - task.setInputData(Map.of("input", List.of(Map.of("brand", "BMW")))); - - var result0 = annotatedWorker.execute(task); - var outputData = result0.getOutputData(); - assertEquals(task.getInputData().get("input"), outputData.get("result")); - } - - static class MapInput { - @WorkerTask("test_1") - public @OutputParam("result") Map doWork(Map input) { - return input; - } - } - - @Test - @DisplayName("it should accept a not annotated Map as input") - void mapAsInputParam() throws NoSuchMethodException { - var worker = new MapInput(); - var annotatedWorker = - new AnnotatedWorker( - "test_1", worker.getClass().getMethod("doWork", Map.class), worker); - - var task = new Task(); - task.setStatus(Task.Status.IN_PROGRESS); - task.setInputData(Map.of("input", List.of(Map.of("brand", "BMW")))); - - var result0 = annotatedWorker.execute(task); - var outputData = result0.getOutputData(); - assertEquals(task.getInputData(), outputData.get("result")); - } - - static class TaskInput { - @WorkerTask("test_1") - public @OutputParam("result") Task doWork(Task input) { - return input; - } - } - - @Test - @DisplayName("it should accept a Task as input") - void taskAsInputParam() throws NoSuchMethodException { - var task = new Task(); - task.setStatus(Task.Status.IN_PROGRESS); - task.setTaskId(UUID.randomUUID().toString()); - task.setInputData(Map.of("input", List.of(Map.of("brand", "BMW")))); - - var worker = new TaskInput(); - var annotatedWorker = - new AnnotatedWorker( - "test_1", worker.getClass().getMethod("doWork", Task.class), worker); - - var result0 = annotatedWorker.execute(task); - var outputData = result0.getOutputData(); - var result = (Task) outputData.get("result"); - assertEquals(result.getTaskId(), task.getTaskId()); - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.PARAMETER) - public @interface AnotherAnnotation {} - - static class AnotherAnnotationInput { - @WorkerTask("test_2") - public @OutputParam("result") Bike doWork(@AnotherAnnotation Bike input) { - return input; - } - } - - @Test - @DisplayName( - "it should convert to the correct type even if there's no @InputParam and parameters are annotated with other annotations") - void annotatedWithAnotherAnnotation() throws NoSuchMethodException { - var worker = new AnotherAnnotationInput(); - var annotatedWorker = - new AnnotatedWorker( - "test_1", worker.getClass().getMethod("doWork", Bike.class), worker); - - var task = new Task(); - task.setStatus(Task.Status.IN_PROGRESS); - task.setTaskId(UUID.randomUUID().toString()); - task.setInputData(Map.of("brand", "Trek")); - - var result0 = annotatedWorker.execute(task); - var outputData = result0.getOutputData(); - var bike = (Bike) outputData.get("result"); - assertEquals("Trek", bike.getBrand()); - } - - static class MultipleInputParams { - @WorkerTask(value = "test_1", threadCount = 3, pollingInterval = 333) - public Map doWork( - @InputParam("bike") Bike bike, @InputParam("car") Car car) { - return Map.of("bike", bike, "car", car); - } - } - - @Test - @DisplayName("it should handle multiple input params") - void multipleInputParams() throws NoSuchMethodException { - var worker = new MultipleInputParams(); - var annotatedWorker = - new AnnotatedWorker( - "test_1", - worker.getClass().getMethod("doWork", Bike.class, Car.class), - worker); - - var task = new Task(); - task.setStatus(Task.Status.IN_PROGRESS); - task.setTaskId(UUID.randomUUID().toString()); - task.setInputData(Map.of("bike", Map.of("brand", "Trek"), "car", Map.of("brand", "BMW"))); - - var result0 = annotatedWorker.execute(task); - var outputData = result0.getOutputData(); - - var bike = (Bike) outputData.get("bike"); - assertEquals("Trek", bike.getBrand()); - - var car = (Car) outputData.get("car"); - assertEquals("BMW", car.getBrand()); - } - - @Test - @DisplayName("it should honor the polling interval from annotations and config") - void pollingIntervalTest() throws NoSuchMethodException { - var config = new TestWorkerConfig(); - - var worker = new MultipleInputParams(); - - AnnotatedWorkerExecutor annotatedWorkerExecutor = - new AnnotatedWorkerExecutor(mock(TaskClient.class)); - annotatedWorkerExecutor.addBean(worker); - annotatedWorkerExecutor.startPolling(); - List workers = annotatedWorkerExecutor.getExecutors(); - assertNotNull(workers); - assertEquals(1, workers.size()); - Worker taskWorker = workers.get(0); - assertEquals(333, taskWorker.getPollingInterval()); - - var worker2 = new AnotherAnnotationInput(); - annotatedWorkerExecutor = new AnnotatedWorkerExecutor(mock(TaskClient.class)); - annotatedWorkerExecutor.addBean(worker2); - annotatedWorkerExecutor.startPolling(); - workers = annotatedWorkerExecutor.getExecutors(); - assertNotNull(workers); - assertEquals(1, workers.size()); - taskWorker = workers.get(0); - assertEquals(100, taskWorker.getPollingInterval()); - - config.setPollingInterval("test_2", 123); - annotatedWorkerExecutor = new AnnotatedWorkerExecutor(mock(TaskClient.class), config); - annotatedWorkerExecutor.addBean(worker2); - annotatedWorkerExecutor.startPolling(); - workers = annotatedWorkerExecutor.getExecutors(); - assertNotNull(workers); - assertEquals(1, workers.size()); - taskWorker = workers.get(0); - assertEquals(123, taskWorker.getPollingInterval()); - } - - @Test - @DisplayName("it should honor the polling interval from annotations and config") - void threadCountTest() throws NoSuchMethodException { - var config = new TestWorkerConfig(); - - var worker = new MultipleInputParams(); - var worker2 = new AnotherAnnotationInput(); - - AnnotatedWorkerExecutor annotatedWorkerExecutor = - new AnnotatedWorkerExecutor(mock(TaskClient.class), config); - annotatedWorkerExecutor.addBean(worker); - annotatedWorkerExecutor.addBean(worker2); - - annotatedWorkerExecutor.startPolling(); - TaskRunnerConfigurer runner = annotatedWorkerExecutor.getTaskRunner(); - assertNotNull(runner); - Map taskThreadCount = runner.getTaskThreadCount(); - - assertNotNull(taskThreadCount); - assertEquals(3, taskThreadCount.get("test_1")); - assertEquals(1, taskThreadCount.get("test_2")); - - annotatedWorkerExecutor.shutdown(); - config.setThreadCount("test_2", 2); - annotatedWorkerExecutor = new AnnotatedWorkerExecutor(mock(TaskClient.class), config); - annotatedWorkerExecutor.addBean(worker); - annotatedWorkerExecutor.addBean(worker2); - - annotatedWorkerExecutor.startPolling(); - runner = annotatedWorkerExecutor.getTaskRunner(); - - taskThreadCount = runner.getTaskThreadCount(); - - assertNotNull(taskThreadCount); - assertEquals(3, taskThreadCount.get("test_1")); - assertEquals(2, taskThreadCount.get("test_2")); - } -} diff --git a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/executor/task/TestWorkerConfig.java b/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/executor/task/TestWorkerConfig.java deleted file mode 100644 index 93ebd6989..000000000 --- a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/executor/task/TestWorkerConfig.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2023 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.executor.task; - -import java.util.HashMap; -import java.util.Map; - -public class TestWorkerConfig extends WorkerConfiguration { - - private Map pollingIntervals = new HashMap<>(); - - private Map threadCounts = new HashMap<>(); - - @Override - public int getPollingInterval(String taskName) { - return pollingIntervals.getOrDefault(taskName, 0); - } - - public void setPollingInterval(String taskName, int interval) { - pollingIntervals.put(taskName, interval); - } - - public void setThreadCount(String taskName, int threadCount) { - threadCounts.put(taskName, threadCount); - } - - @Override - public int getThreadCount(String taskName) { - return threadCounts.getOrDefault(taskName, 0); - } -} diff --git a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/Task1Input.java b/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/Task1Input.java deleted file mode 100644 index 0f7996e00..000000000 --- a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/Task1Input.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.testing; - -public class Task1Input { - - private int mod; - - private int oddEven; - - public int getMod() { - return mod; - } - - public void setMod(int mod) { - this.mod = mod; - } - - public int getOddEven() { - return oddEven; - } - - public void setOddEven(int oddEven) { - this.oddEven = oddEven; - } - - @Override - public String toString() { - return "Task1Input{" + "mod=" + mod + ", oddEven=" + oddEven + '}'; - } -} diff --git a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/TestWorkflowInput.java b/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/TestWorkflowInput.java deleted file mode 100644 index 62716e161..000000000 --- a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/TestWorkflowInput.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2022 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.testing; - -public class TestWorkflowInput { - - private String name; - - private String zipCode; - - private String countryCode; - - public TestWorkflowInput(String name, String zipCode, String countryCode) { - this.name = name; - this.zipCode = zipCode; - this.countryCode = countryCode; - } - - public TestWorkflowInput() {} - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getZipCode() { - return zipCode; - } - - public void setZipCode(String zipCode) { - this.zipCode = zipCode; - } - - public String getCountryCode() { - return countryCode; - } - - public void setCountryCode(String countryCode) { - this.countryCode = countryCode; - } -} diff --git a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/WorkflowTestFrameworkTests.java b/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/WorkflowTestFrameworkTests.java deleted file mode 100644 index 4518ea83c..000000000 --- a/java-sdk/src/test/java/com/netflix/conductor/sdk/workflow/testing/WorkflowTestFrameworkTests.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2021 Conductor Authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the - * specific language governing permissions and limitations under the License. - */ -package com.netflix.conductor.sdk.workflow.testing; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.TaskResult; -import com.netflix.conductor.common.run.Workflow; -import com.netflix.conductor.sdk.testing.WorkflowTestRunner; -import com.netflix.conductor.sdk.workflow.executor.WorkflowExecutor; -import com.netflix.conductor.sdk.workflow.task.InputParam; -import com.netflix.conductor.sdk.workflow.task.OutputParam; -import com.netflix.conductor.sdk.workflow.task.WorkerTask; - -import static org.junit.jupiter.api.Assertions.*; - -public class WorkflowTestFrameworkTests { - - private static WorkflowTestRunner testRunner; - - private static WorkflowExecutor executor; - - @BeforeAll - public static void init() throws IOException { - testRunner = new WorkflowTestRunner(8080, "3.7.3"); - testRunner.init("com.netflix.conductor.sdk.workflow.testing"); - - executor = testRunner.getWorkflowExecutor(); - executor.loadTaskDefs("/tasks.json"); - executor.loadWorkflowDefs("/simple_workflow.json"); - } - - @AfterAll - public static void cleanUp() { - testRunner.shutdown(); - } - - @Test - public void testDynamicTaskExecuted() throws Exception { - - Map input = new HashMap<>(); - input.put("task2Name", "task_2"); - input.put("mod", "1"); - input.put("oddEven", "12"); - input.put("number", 0); - - // Start the workflow and wait for it to complete - Workflow workflow = executor.executeWorkflow("Decision_TaskExample", 1, input).get(); - - assertNotNull(workflow); - assertEquals(Workflow.WorkflowStatus.COMPLETED, workflow.getStatus()); - assertNotNull(workflow.getOutput()); - assertNotNull(workflow.getTasks()); - assertFalse(workflow.getTasks().isEmpty()); - assertTrue( - workflow.getTasks().stream() - .anyMatch(task -> task.getTaskDefName().equals("task_6"))); - - // task_2's implementation fails at the first try, so we should have to instances of task_2 - // execution - // 2 executions of task_2 should be present - assertEquals( - 2, - workflow.getTasks().stream() - .filter(task -> task.getTaskDefName().equals("task_2")) - .count()); - List task2Executions = - workflow.getTasks().stream() - .filter(task -> task.getTaskDefName().equals("task_2")) - .collect(Collectors.toList()); - assertNotNull(task2Executions); - assertEquals(2, task2Executions.size()); - - // First instance would have failed and second succeeded. - assertEquals(Task.Status.FAILED, task2Executions.get(0).getStatus()); - assertEquals(Task.Status.COMPLETED, task2Executions.get(1).getStatus()); - - // task10's output - assertEquals(100, workflow.getOutput().get("c")); - } - - @Test - public void testWorkflowFailure() throws Exception { - - Map input = new HashMap<>(); - // task2Name is missing which will cause workflow to fail - input.put("mod", "1"); - input.put("oddEven", "12"); - input.put("number", 0); - - // we are missing task2Name parameter which is required to wire up dynamictask - // The workflow should fail as we are not passing it as input - Workflow workflow = executor.executeWorkflow("Decision_TaskExample", 1, input).get(); - assertNotNull(workflow); - assertEquals(Workflow.WorkflowStatus.FAILED, workflow.getStatus()); - assertNotNull(workflow.getReasonForIncompletion()); - } - - @WorkerTask("task_1") - public Map task1(Task1Input input) { - Map result = new HashMap<>(); - result.put("input", input); - return result; - } - - @WorkerTask("task_2") - public TaskResult task2(Task task) { - if (task.getRetryCount() < 1) { - task.setStatus(Task.Status.FAILED); - task.setReasonForIncompletion("try again"); - return new TaskResult(task); - } - - task.setStatus(Task.Status.COMPLETED); - return new TaskResult(task); - } - - @WorkerTask("task_6") - public TaskResult task6(Task task) { - task.setStatus(Task.Status.COMPLETED); - return new TaskResult(task); - } - - @WorkerTask("task_10") - public TaskResult task10(Task task) { - task.setStatus(Task.Status.COMPLETED); - task.getOutputData().put("a", "b"); - task.getOutputData().put("c", 100); - task.getOutputData().put("x", false); - return new TaskResult(task); - } - - @WorkerTask("task_8") - public TaskResult task8(Task task) { - task.setStatus(Task.Status.COMPLETED); - return new TaskResult(task); - } - - @WorkerTask("task_5") - public TaskResult task5(Task task) { - task.setStatus(Task.Status.COMPLETED); - return new TaskResult(task); - } - - @WorkerTask("task_3") - public @OutputParam("z1") String task3(@InputParam("taskToExecute") String p1) { - return "output of task3, p1=" + p1; - } - - @WorkerTask("task_30") - public Map task30(Task task) { - Map output = new HashMap<>(); - output.put("v1", "b"); - output.put("v2", Arrays.asList("one", "two", 3)); - output.put("v3", 5); - return output; - } - - @WorkerTask("task_31") - public Map task31(Task task) { - Map output = new HashMap<>(); - output.put("a1", "b"); - output.put("a2", Arrays.asList("one", "two", 3)); - output.put("a3", 5); - return output; - } - - @WorkerTask("HTTP") - public Map http(Task task) { - Map output = new HashMap<>(); - output.put("a1", "b"); - output.put("a2", Arrays.asList("one", "two", 3)); - output.put("a3", 5); - return output; - } - - @WorkerTask("EVENT") - public Map event(Task task) { - Map output = new HashMap<>(); - output.put("a1", "b"); - output.put("a2", Arrays.asList("one", "two", 3)); - output.put("a3", 5); - return output; - } -} diff --git a/java-sdk/src/test/resources/application-integrationtest.properties b/java-sdk/src/test/resources/application-integrationtest.properties deleted file mode 100644 index efb46697d..000000000 --- a/java-sdk/src/test/resources/application-integrationtest.properties +++ /dev/null @@ -1,55 +0,0 @@ -# -# /* -# * Copyright 2023 Conductor authors -# *

-# * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with -# * the License. You may obtain a copy of the License at -# *

-# * http://www.apache.org/licenses/LICENSE-2.0 -# *

-# * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on -# * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the -# * specific language governing permissions and limitations under the License. -# */ -# - -conductor.db.type=memory -# disable trying to connect to redis and use in-memory -conductor.queue.type=xxx -conductor.workflow-execution-lock.type=local_only -conductor.external-payload-storage.type=mock -conductor.indexing.enabled=false - -conductor.app.stack=test -conductor.app.appId=conductor - -conductor.app.workflow-offset-timeout=30s - -conductor.system-task-workers.enabled=false -conductor.app.system-task-worker-callback-duration=0 - -conductor.app.event-message-indexing-enabled=true -conductor.app.event-execution-indexing-enabled=true - -conductor.workflow-reconciler.enabled=true -conductor.workflow-repair-service.enabled=false - -conductor.app.workflow-execution-lock-enabled=false - -conductor.app.workflow-input-payload-size-threshold=10KB -conductor.app.max-workflow-input-payload-size-threshold=10240KB -conductor.app.workflow-output-payload-size-threshold=10KB -conductor.app.max-workflow-output-payload-size-threshold=10240KB -conductor.app.task-input-payload-size-threshold=10KB -conductor.app.max-task-input-payload-size-threshold=10240KB -conductor.app.task-output-payload-size-threshold=10KB -conductor.app.max-task-output-payload-size-threshold=10240KB -conductor.app.max-workflow-variables-payload-size-threshold=2KB - -conductor.redis.availability-zone=us-east-1c -conductor.redis.data-center-region=us-east-1 -conductor.redis.workflow-namespace-prefix=integration-test -conductor.redis.queue-namespace-prefix=integtest - -conductor.elasticsearch.index-prefix=conductor -conductor.elasticsearch.cluster-health-color=yellow diff --git a/java-sdk/src/test/resources/log4j2.xml b/java-sdk/src/test/resources/log4j2.xml deleted file mode 100644 index a35b65824..000000000 --- a/java-sdk/src/test/resources/log4j2.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/java-sdk/src/test/resources/script.js b/java-sdk/src/test/resources/script.js deleted file mode 100644 index af6d42c43..000000000 --- a/java-sdk/src/test/resources/script.js +++ /dev/null @@ -1,11 +0,0 @@ -function e() { - if ($.value > 1){ - return { - "key": "value", - "key2": 42 - }; - } else { - return {}; - } -} -e(); \ No newline at end of file diff --git a/java-sdk/src/test/resources/simple_workflow.json b/java-sdk/src/test/resources/simple_workflow.json deleted file mode 100644 index cc8a78051..000000000 --- a/java-sdk/src/test/resources/simple_workflow.json +++ /dev/null @@ -1,151 +0,0 @@ -{ - "createTime": 1635491472393, - "updateTime": 1635356450472, - "name": "Decision_TaskExample", - "description": "Decision_TaskExample", - "version": 1, - "tasks": [ - { - "name": "decision_task", - "taskReferenceName": "decision_task", - "inputParameters": { - "case_value_param": "${workflow.input.number}" - }, - "type": "DECISION", - "caseValueParam": "case_value_param", - "decisionCases": { - "0": [ - { - "name": "task_5", - "taskReferenceName": "task_5", - "inputParameters": {}, - "type": "SIMPLE", - "decisionCases": {}, - "defaultCase": [], - "forkTasks": [], - "startDelay": 0, - "joinOn": [], - "optional": false, - "defaultExclusiveJoinTask": [], - "asyncComplete": false, - "loopOver": [] - }, - { - "name": "dyntask", - "taskReferenceName": "task_2", - "inputParameters": { - "taskToExecute":"${workflow.input.task2Name}" - }, - "type": "DYNAMIC", - "dynamicTaskNameParam":"taskToExecute", - "decisionCases": {}, - "defaultCase": [], - "forkTasks": [], - "startDelay": 0, - "joinOn": [], - "optional": false, - "defaultExclusiveJoinTask": [], - "asyncComplete": false, - "loopOver": [] - }, - { - "name": "task_6", - "taskReferenceName": "task_6", - "inputParameters": {}, - "type": "SIMPLE", - "decisionCases": {}, - "defaultCase": [], - "forkTasks": [], - "startDelay": 0, - "joinOn": [], - "optional": false, - "defaultExclusiveJoinTask": [], - "asyncComplete": false, - "loopOver": [] - } - ], - "1": [ - { - "name": "task_8", - "taskReferenceName": "task_8", - "inputParameters": {}, - "type": "SIMPLE", - "decisionCases": {}, - "defaultCase": [], - "forkTasks": [], - "startDelay": 0, - "joinOn": [], - "optional": false, - "defaultExclusiveJoinTask": [], - "asyncComplete": false, - "loopOver": [] - }, - { - "name": "task_10", - "taskReferenceName": "task_10", - "inputParameters": {}, - "type": "SIMPLE", - "decisionCases": {}, - "defaultCase": [], - "forkTasks": [], - "startDelay": 0, - "joinOn": [], - "optional": false, - "defaultExclusiveJoinTask": [], - "asyncComplete": false, - "loopOver": [] - } - ] - }, - "defaultCase": [ - { - "name": "task_8", - "taskReferenceName": "task_8_default", - "inputParameters": {}, - "type": "SIMPLE", - "decisionCases": {}, - "defaultCase": [], - "forkTasks": [], - "startDelay": 0, - "joinOn": [], - "optional": false, - "defaultExclusiveJoinTask": [], - "asyncComplete": false, - "loopOver": [] - } - ], - "forkTasks": [], - "startDelay": 0, - "joinOn": [], - "optional": false, - "defaultExclusiveJoinTask": [], - "asyncComplete": false, - "loopOver": [] - }, - { - "name": "task_10", - "taskReferenceName": "task_10_last", - "inputParameters": {}, - "type": "SIMPLE", - "decisionCases": {}, - "defaultCase": [], - "forkTasks": [], - "startDelay": 0, - "joinOn": [], - "optional": false, - "defaultExclusiveJoinTask": [], - "asyncComplete": false, - "loopOver": [] - } - ], - "inputParameters": [], - "outputParameters": {}, - "schemaVersion": 2, - "restartable": true, - "workflowStatusListenerEnabled": true, - "ownerEmail": "abc@example.com", - "timeoutPolicy": "ALERT_ONLY", - "timeoutSeconds": 0, - "variables": {}, - "inputTemplate": {} -} \ No newline at end of file diff --git a/java-sdk/src/test/resources/tasks.json b/java-sdk/src/test/resources/tasks.json deleted file mode 100644 index b60881d08..000000000 --- a/java-sdk/src/test/resources/tasks.json +++ /dev/null @@ -1,1252 +0,0 @@ -[ - { - "createTime": 1635656118884, - "createdBy": "", - "name": "task_38", - "description": "task_38", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 1, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635638846956, - "createdBy": "", - "name": "encode", - "retryCount": 3, - "timeoutSeconds": 1200, - "inputKeys": [ - "fileLocation" - ], - "outputKeys": [ - "encodeLocation" - ], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 1, - "responseTimeoutSeconds": 1200, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 50, - "rateLimitFrequencyInSeconds": 60, - "ownerEmail": "encode_admin@test.com", - "pollTimeoutSeconds": 1200 - }, - { - "createTime": 1635656118436, - "createdBy": "", - "name": "task_8", - "description": "task_8", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 1, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118873, - "createdBy": "", - "name": "task_37", - "description": "task_37", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 1, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118460, - "createdBy": "", - "name": "task_9", - "description": "task_9", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 1, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118390, - "createdBy": "", - "name": "task_6", - "description": "task_6", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 1, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118861, - "createdBy": "", - "name": "task_36", - "description": "task_36", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635638847017, - "createdBy": "", - "name": "collect_payment_task", - "description": "collect_payment_task", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118847, - "createdBy": "", - "name": "task_35", - "description": "task_35", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118422, - "createdBy": "", - "name": "task_7", - "description": "task_7", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118835, - "createdBy": "", - "name": "task_34", - "description": "task_34", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118349, - "createdBy": "", - "name": "task_4", - "description": "task_4", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118819, - "createdBy": "", - "name": "task_33", - "description": "task_33", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118371, - "createdBy": "", - "name": "task_5", - "description": "task_5", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118808, - "createdBy": "", - "name": "task_32", - "description": "task_32", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118302, - "createdBy": "", - "name": "task_2", - "description": "task_2", - "retryCount": 3, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 1, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118797, - "createdBy": "", - "name": "task_31", - "description": "task_31", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118323, - "createdBy": "", - "name": "task_3", - "description": "task_3", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118228, - "createdBy": "", - "name": "task_0", - "description": "task_0", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118775, - "createdBy": "", - "name": "task_30", - "description": "task_30", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118267, - "createdBy": "", - "name": "task_1", - "description": "task_1", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635638847161, - "createdBy": "", - "name": "BookHotels", - "retryCount": 3, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "ui@example.com" - }, - { - "createTime": 1635638847170, - "createdBy": "", - "name": "deploy", - "retryCount": 3, - "timeoutSeconds": 1200, - "inputKeys": [ - "fileLocation" - ], - "outputKeys": [ - "deployLocation" - ], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 600, - "responseTimeoutSeconds": 1200, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 50, - "rateLimitFrequencyInSeconds": 60, - "ownerEmail": "encode_admin@test.com", - "pollTimeoutSeconds": 1200 - }, - { - "createTime": 1635763310960, - "createdBy": "", - "name": "ship_via_dhl", - "retryCount": 3, - "timeoutSeconds": 600, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 300, - "responseTimeoutSeconds": 300, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 2, - "ownerEmail": "abc@example.com", - "pollTimeoutSeconds": 1200 - }, - { - "createTime": 1635638847180, - "createdBy": "", - "name": "StartBooking", - "retryCount": 3, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "ui@example.com" - }, - { - "createTime": 1635434088645, - "createdBy": "", - "name": "Read_Name", - "retryCount": 1, - "timeoutSeconds": 600, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 300, - "responseTimeoutSeconds": 300, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 1, - "rateLimitFrequencyInSeconds": 60, - "ownerEmail": "abc@example.com", - "pollTimeoutSeconds": 1200 - }, - { - "createTime": 1635638847189, - "createdBy": "", - "name": "book_flight_task", - "description": "book_flight_task", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635638847198, - "createdBy": "", - "name": "book_car_task", - "description": "book_car_task", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118758, - "createdBy": "", - "name": "task_29", - "description": "task_29", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118747, - "createdBy": "", - "name": "task_28", - "description": "task_28", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635278952348, - "createdBy": "", - "name": "ship_via_ups", - "retryCount": 3, - "timeoutSeconds": 600, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 300, - "responseTimeoutSeconds": 300, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 2, - "ownerEmail": "abc@example.com", - "pollTimeoutSeconds": 1200 - }, - { - "createTime": 1635638847226, - "createdBy": "", - "name": "image_convert_resize", - "retryCount": 3, - "timeoutSeconds": 1200, - "inputKeys": [ - "fileLocation", - "outputFormat", - "outputWidth", - "outputHeight", - "maintainAspectRatio" - ], - "outputKeys": [ - "fileLocation" - ], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 600, - "responseTimeoutSeconds": 1200, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 50, - "rateLimitFrequencyInSeconds": 60, - "ownerEmail": "test@example.com", - "pollTimeoutSeconds": 3600 - }, - { - "createTime": 1635638847238, - "createdBy": "", - "name": "deposit_money", - "description": "deposit_money", - "retryCount": 5, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 10, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118912, - "createdBy": "", - "name": "search_elasticsearch", - "description": "search_elasticsearch", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118900, - "createdBy": "", - "name": "task_39", - "description": "task_39", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118586, - "createdBy": "", - "name": "task_16", - "description": "task_16", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635278952330, - "createdBy": "", - "name": "shipping_info", - "retryCount": 1, - "timeoutSeconds": 600, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 300, - "responseTimeoutSeconds": 300, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 2, - "ownerEmail": "abc@example.com", - "pollTimeoutSeconds": 1200 - }, - { - "createTime": 1635656118567, - "createdBy": "", - "name": "task_15", - "description": "task_15", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118545, - "createdBy": "", - "name": "task_14", - "description": "task_14", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118528, - "createdBy": "", - "name": "task_13", - "description": "task_13", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118513, - "createdBy": "", - "name": "task_12", - "description": "task_12", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635638847312, - "createdBy": "", - "name": "withdraw_money", - "description": "withdraw_money", - "retryCount": 5, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 10, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118495, - "createdBy": "", - "name": "task_11", - "description": "task_11", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118480, - "createdBy": "", - "name": "task_10", - "description": "task_10", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "updateTime": 1636574526469, - "createdBy": "user", - "updatedBy": "", - "name": "sample_task_name_1", - "description": "This is a sample task for demo", - "retryCount": 3, - "timeoutSeconds": 30, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 5, - "responseTimeoutSeconds": 10, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1636051623273, - "createdBy": "", - "name": "order_details", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 60, - "ownerEmail": "abc@example.com" - }, - { - "createTime": 1635638847343, - "createdBy": "", - "name": "CompleteFlightBooking", - "retryCount": 3, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "ui@example.com" - }, - { - "createTime": 1635278952339, - "createdBy": "", - "name": "ship_via_fedex", - "retryCount": 3, - "timeoutSeconds": 600, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 300, - "responseTimeoutSeconds": 300, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 2, - "ownerEmail": "abc@example.com", - "pollTimeoutSeconds": 1200 - }, - { - "createTime": 1635638847353, - "createdBy": "", - "name": "map_state_codes", - "retryCount": 3, - "timeoutSeconds": 300, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 10, - "responseTimeoutSeconds": 180, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@gmail.com" - }, - { - "createTime": 1635638847362, - "createdBy": "", - "name": "compute_median_top_states", - "retryCount": 3, - "timeoutSeconds": 300, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 10, - "responseTimeoutSeconds": 180, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@gmail.com" - }, - { - "createTime": 1635638847374, - "createdBy": "", - "name": "scaleS3Image", - "retryCount": 3, - "timeoutSeconds": 300, - "inputKeys": [ - "inputBucketName", - "inputKeyName", - "scalingFactor", - "outputBucketName", - "outputKeyName" - ], - "outputKeys": [ - "response" - ], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 10, - "responseTimeoutSeconds": 180, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "conductor@example.com" - }, - { - "createTime": 1635656118736, - "createdBy": "", - "name": "task_27", - "description": "task_27", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118725, - "createdBy": "", - "name": "task_26", - "description": "task_26", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118713, - "createdBy": "", - "name": "task_25", - "description": "task_25", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118700, - "createdBy": "", - "name": "task_24", - "description": "task_24", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635878631466, - "createdBy": "", - "name": "task_23", - "retryCount": 1, - "timeoutSeconds": 600, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 600, - "responseTimeoutSeconds": 300, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 50, - "rateLimitFrequencyInSeconds": 60, - "pollTimeoutSeconds": 600, - "ownerEmail": "test@example.com" - }, - { - "createTime": 1635878631456, - "createdBy": "", - "name": "task_22", - "retryCount": 1, - "timeoutSeconds": 600, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 600, - "responseTimeoutSeconds": 300, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 50, - "rateLimitFrequencyInSeconds": 60, - "pollTimeoutSeconds": 600, - "ownerEmail": "test@example.com" - }, - { - "createTime": 1635638847436, - "createdBy": "", - "name": "send_email_task", - "description": "send_email_task", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118658, - "createdBy": "", - "name": "task_21", - "description": "task_21", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635638847459, - "createdBy": "", - "name": "image_multiple_convert_resize", - "retryCount": 3, - "timeoutSeconds": 1200, - "inputKeys": [ - "fileLocation", - "outputFormats", - "outputSizes", - "maintainAspectRatio" - ], - "outputKeys": [ - "dynamicTasks", - "dynamicTasksInput" - ], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 600, - "responseTimeoutSeconds": 1200, - "concurrentExecLimit": 100, - "inputTemplate": {}, - "rateLimitPerFrequency": 50, - "rateLimitFrequencyInSeconds": 60, - "ownerEmail": "exampl@example.com", - "pollTimeoutSeconds": 3600 - }, - { - "createTime": 1635656118644, - "createdBy": "", - "name": "task_20", - "description": "task_20", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635638847477, - "createdBy": "", - "name": "simple_worker", - "retryCount": 3, - "timeoutSeconds": 300, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 10, - "responseTimeoutSeconds": 180, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@gmail.com" - }, - { - "createTime": 1635638847486, - "createdBy": "", - "name": "book_hotel_task", - "description": "book_hotel_task", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 1200, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635638847495, - "createdBy": "", - "name": "watermarkS3Image", - "retryCount": 3, - "timeoutSeconds": 300, - "inputKeys": [ - "inputBucketName", - "inputKeyName", - "watermarkBucketName", - "watermarkKeyName", - "outputBucketName", - "outputKeyName" - ], - "outputKeys": [ - "response" - ], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 10, - "responseTimeoutSeconds": 180, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "conductor@example.com" - }, - { - "createTime": 1635656118631, - "createdBy": "", - "name": "task_19", - "description": "task_19", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118616, - "createdBy": "", - "name": "task_18", - "description": "task_18", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - }, - { - "createTime": 1635656118601, - "createdBy": "", - "name": "task_17", - "description": "task_17", - "retryCount": 1, - "timeoutSeconds": 0, - "inputKeys": [], - "outputKeys": [], - "timeoutPolicy": "TIME_OUT_WF", - "retryLogic": "FIXED", - "retryDelaySeconds": 60, - "responseTimeoutSeconds": 3600, - "inputTemplate": {}, - "rateLimitPerFrequency": 0, - "rateLimitFrequencyInSeconds": 1, - "ownerEmail": "example@email.com" - } -] \ No newline at end of file diff --git a/java-sdk/testing_framework.md b/java-sdk/testing_framework.md deleted file mode 100644 index 601ee2d84..000000000 --- a/java-sdk/testing_framework.md +++ /dev/null @@ -1,74 +0,0 @@ -# Unit Testing Framework for Workflows - -The framework allows you to test the workflow definitions against a specific version of Conductor server. - -The unit tests allow the following: -1. **Input/Output Wiring**: Ensure the tasks are wired up correctly. -2. **Parameter check**: Workflow behavior with missing mandatory parameters is expected (fail if required). -3. **Task Failure behavior**: Ensure the task definitions have the right number of retries etc. - For example, if the task is not idempotent, it does not get retried. -4. **Branch Testing**: Given a specific input, ensure the workflow executes a specific branch of the fork/decision. - -The local test server is self-contained with no additional dependencies required and stores all the data -in memory. Once the test completes, the server is terminated and all the data is wiped out. - -## Unit Testing Frameworks -The unit testing framework is agnostic to the framework you use for testing and can be easily integrated into -JUnit, Spock and other testing frameworks being used. - -## Setting Up Local Server for Testing​ - -```java -//Setup method code - should be called once per the test lifecycle -//e.g. @BeforeClass in JUnit - -//Download the published conductor server version 3.5.2 -//Start the local server at port 8096 -testRunner = new WorkflowTestRunner(8096, "3.5.2"); - -//Scan the packages for task workers -testRunner.init("com.netflix.conductor.testing.workflows"); - -//Get the executor instance used for loading workflows -executor = testRunner.getWorkflowExecutor(); -``` - -Clean up method: -```java -//Clean up method code -- place in a clean up method e.g. @AfterClass in Junit - -//Shutdown local workers and servers and clean up any local resources in use. -testRunner.shutdown(); -``` - -Loading workflows from JSON files for testing: -```java -executor.loadTaskDefs("/tasks.json"); -executor.loadWorkflowDefs("/simple_workflow.json"); -``` - -## Sample test code that starts a workflow and verifies its execution - -```java -GetInsuranceQuote getQuote = new GetInsuranceQuote(); -getQuote.setName("personA"); -getQuote.setAmount(1000000.0); -getQuote.setZipCode("10121"); - -// Start the workflow and wait for it to complete -CompletableFuture workflowFuture = executor.executeWorkflow("InsuranceQuoteWorkflow", 1, getQuote); - -//Wait for the workflow execution to complete -Workflow workflow = workflowFuture.get(); - -//Assertions -assertNotNull(workflow); -assertEquals(Workflow.WorkflowStatus.COMPLETED, workflow.getStatus()); -assertNotNull(workflow.getOutput()); -assertNotNull(workflow.getTasks()); -assertFalse(workflow.getTasks().isEmpty()); -assertTrue(workflow.getTasks().stream().anyMatch(task -> task.getTaskDefName().equals("task_6"))); -``` - - - diff --git a/java-sdk/worker_sdk.md b/java-sdk/worker_sdk.md deleted file mode 100644 index 36a498568..000000000 --- a/java-sdk/worker_sdk.md +++ /dev/null @@ -1,117 +0,0 @@ -# Worker SDK -Worker SDK makes it easy to write Conductor workers which are strongly typed with specific inputs and outputs. - -Annotations for the worker methods: - -* `@WorkerTask` - When annotated, convert a method to a Conductor worker. -* `@InputParam` - Name of the input parameter to bind to from the task's input. -* `@OutputParam` - Name of the output key of the task's output. - -Please note inputs and outputs to a task in Conductor are JSON documents. - - -**Examples** - -Create a worker named `task1` that gets Task as input and produces TaskResult as output. -```java -@WorkerTask("task1") - public TaskResult task1(Task task) { - task.setStatus(Task.Status.COMPLETED); - return new TaskResult(task); - } -``` - -Create a worker named `task2` that takes the `name` as a String input and produces an output `return "Hello, " + name` - -```java -@WorkerTask("task2") -public @OutputParam("greetings") String task2(@InputParam("name") String name) { - return "Hello, " + name; -} -``` -Example Task Input/Output - -Input: -```json -{ - "name": "conductor" -} -``` - -Output: -```json -{ - "greetings": "Hello, conductor" -} -``` -A worker that takes complex java type as input and produces the complex output: -```java -@WorkerTask("get_insurance_quote") - public InsuranceQuote getInsuranceQuote(GetInsuranceQuote quoteInput) { - InsuranceQuote quote = new InsuranceQuote(); - //Implementation - return quote; - } -``` - -Example Task Input/Output - -Input: -```json -{ - "name": "personA", - "zipCode": "10121", - "amount": 1000000 -} -``` - -Output: -```json -{ - "name": "personA", - "quotedPremium": 123.50, - "quotedAmount": 1000000 -} -``` - -## Managing Task Workers -Annotated Workers are managed by [WorkflowExecutor](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/executor/WorkflowExecutor.java) - -### Start Workers -```java -WorkflowExecutor executor = new WorkflowExecutor("http://server/api/"); -//List of packages (comma separated) to scan for annotated workers. -// Please note, the worker method MUST be public and the class in which they are defined -//MUST have a no-args constructor -executor.initWorkers("com.company.package1,com.company.package2"); -``` - -### Stop Workers -The code fragment to stop workers at shutdown of the application. -```java -executor.shutdown(); -``` - -### Unit Testing Workers -Workers implemented with the annotations are regular Java methods that can be unit tested with any testing framework. - -#### Mock Workers for Workflow Testing​ -Create a mock worker in a different package (e.g., test) and scan for these packages when loading up the workers for integration testing. - -See [Unit Testing Framework](testing_framework.md) for more details on testing. - -## Best Practices -In a typical production environment, you will have multiple workers across different machines/VMs/pods polling for the same task. -As with all Conductor workers, the following best practices apply: - -1. Workers should be stateless and should not maintain any state on the process they are running. -2. Ideally, workers should be idempotent. -3. The worker should follow the Single Responsibility Principle and do exactly one thing they are responsible for. -4. The worker should not embed any workflow logic - i.e., scheduling another worker, sending a message, etc. The Conductor has features to do this, making it possible to decouple your workflow logic from worker implementation. - - - - - - - diff --git a/java-sdk/workflow_sdk.md b/java-sdk/workflow_sdk.md deleted file mode 100644 index 60dc77a9e..000000000 --- a/java-sdk/workflow_sdk.md +++ /dev/null @@ -1,122 +0,0 @@ -# Workflow SDK -Workflow SDK provides fluent API to create workflows with strongly typed interfaces. - -## APIs -### ConductorWorkflow -[ConductorWorkflow](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/ConductorWorkflow.java) is the SDK representation of a Conductor workflow. - -#### Create a `ConductorWorkflow` Instance -```java -ConductorWorkflow conductorWorkflow = new WorkflowBuilder(executor) - .name("sdk_workflow_example") - .version(1) - .ownerEmail("hello@example.com") - .description("Example Workflow") - .timeoutPolicy(WorkflowDef.TimeoutPolicy.TIME_OUT_WF, 100) - .add(new SimpleTask("calculate_insurance_premium", "calculate_insurance_premium")) - .add(new SimpleTask("send_email", "send_email")) - .build(); -``` -### Working with Simple Worker Tasks -Use [SimpleTask](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SimpleTask.java) to add a simple task to a workflow. - -Example: -```java -... -builder.add(new SimpleTask("send_email", "send_email")) -... -``` -### Wiring Inputs to Task -Use `input` methods to configure the inputs to the task. - -See our doc on [task inputs](https://conductor.netflix.com/how-tos/Tasks/task-inputs.html) for more details. - -Example -```java -builder.add( - new SimpleTask("send_email", "send_email") - .input("email", "${workflow.input.email}") - .input("subject", "Your insurance quote for the amount ${generate_quote.output.amount}") -); -``` - -### Working with Operators -Each operator has its own class that can be added to the workflow builder. - -* [ForkJoin](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/ForkJoin.java) -* [Wait](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Wait.java) -* [Switch](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Switch.java) -* [DynamicFork](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DynamicFork.java) -* [DoWhile](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/DoWhile.java) -* [Join](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Join.java) -* [Dynamic](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Dynamic.java) -* [Terminate](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/Terminate.java) -* [SubWorkflow](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SubWorkflow.java) -* [SetVariable](https://github.com/conductor-oss/conductor/blob/main/java-sdk/src/main/java/com/netflix/conductor/sdk/workflow/def/tasks/SetVariable.java) - - -#### Register Workflow with Conductor Server -```java -//Returns true if the workflow is successfully created -//Reasons why this method will return false -//1. Network connectivity issue -//2. Workflow already exists with the specified name and version -//3. There are missing task definitions -boolean registered = workflow.registerWorkflow(); -``` -#### Overwrite Existing Workflow Definition​ -```java -boolean registered = workflow.registerWorkflow(true); -``` - -#### Overwrite existing workflow definitions & registering any missing task definitions -```java -boolean registered = workflow.registerWorkflow(true, true); -``` - -#### Create `ConductorWorkflow` based on the definition registered on the server - -```java -ConductorWorkflow conductorWorkflow = - new ConductorWorkflow(executor) - .from("sdk_workflow_example", 1); -``` - -#### Start Workflow Execution -Start the execution of the workflow based on the definition registered on the server. Use the register method to register a workflow on the server before executing. - -```java - -//Returns a completable future -CompletableFuture execution = conductorWorkflow.execute(input); - -//Wait for the workflow to complete -- useful if workflow completes within a reasonable amount of time -Workflow workflowRun = execution.get(); - -//Get the workflowId -String workflowId = workflowRun.getWorkflowId(); - -//Get the status of workflow execution -WorkflowStatus status = workflowRun.getStatus(); -``` -See [Workflow](https://github.com/conductor-oss/conductor/blob/main/common/src/main/java/com/netflix/conductor/common/run/Workflow.java) for more details on the Workflow object. - -#### Start Dynamic Workflow Execution -Dynamic workflows are executed by specifying the workflow definition along with the execution and do not require registering the workflow on the server before executing. - -##### Use cases for dynamic workflows -1. Each workflow run has a unique workflow definition -2. Workflows are defined based on the user data and cannot be modeled ahead of time statically - -```java -//1. Use WorkflowBuilder to create ConductorWorkflow. -//2. Execute using the definition created by SDK. -CompletableFuture execution = conductorWorkflow.executeDynamic(input); - -``` - - - - - - diff --git a/settings.gradle b/settings.gradle index 7ba5ffac4..a9188a0a7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -55,7 +55,6 @@ include 'rest' include 'grpc' include 'grpc-server' -include 'java-sdk' // community modules include 'workflow-event-listener'