From cd528e126ed36abedf38ac0eab07e18e1d476dad Mon Sep 17 00:00:00 2001 From: Anoop Panicker <34087882+apanicker-nflx@users.noreply.github.com> Date: Mon, 31 Jan 2022 15:46:34 -0800 Subject: [PATCH] Object model separation (#2702) * introduce a domain specific object model * service layer wip * core and contribs wip * remove repeated external storage access in state machine * cassandra module changes * redis persistence changes * mysql persistence changes * postgres persistence changes * redis concurrency limit module changes * updated IndexDAO APIs and corresponding ES implementations * more changes per indexDAO api * fix tests in es modules due to new contract * fix unit tests as per new models * rename objects and classes * fix integ tests --- build.gradle | 11 + .../config/CassandraConfiguration.java | 2 +- .../cassandra/config/CassandraProperties.java | 2 +- .../cassandra/dao/CassandraBaseDAO.java | 2 +- .../dao/CassandraEventHandlerDAO.java | 2 +- .../cassandra/dao/CassandraExecutionDAO.java | 83 +- .../cassandra/dao/CassandraMetadataDAO.java | 2 +- .../conductor/cassandra/util/Constants.java | 2 +- .../conductor/cassandra/util/Statements.java | 2 +- .../dao/CassandraEventHandlerDAOSpec.groovy | 22 +- .../dao/CassandraExecutionDAOSpec.groovy | 96 +-- .../dao/CassandraMetadataDAOSpec.groovy | 22 +- .../cassandra/dao/CassandraSpec.groovy | 41 +- .../cassandra/util/StatementsSpec.groovy | 21 +- .../conductor/client/http/TaskClient.java | 6 +- .../conductor/common/metadata/tasks/Task.java | 2 +- .../common/metadata/tasks/TaskResult.java | 2 +- .../conductor/common/run/Workflow.java | 2 +- .../contribs/dao/index/NoopIndexDAO.java | 14 +- .../dao/index/NoopIndexDAOConfiguration.java | 2 +- ...rchivingWithTTLWorkflowStatusListener.java | 14 +- ...rchivingWorkflowListenerConfiguration.java | 4 +- .../ArchivingWorkflowListenerProperties.java | 2 +- .../ArchivingWorkflowStatusListener.java | 10 +- .../ConductorQueueStatusPublisher.java | 18 +- ...ctorQueueStatusPublisherConfiguration.java | 6 +- ...nductorQueueStatusPublisherProperties.java | 2 +- .../queue/sqs/SQSObservableQueue.java | 2 +- .../config/SQSEventQueueConfiguration.java | 1 - .../contribs/storage/S3PayloadStorage.java | 6 +- .../storage/config/S3Configuration.java | 2 +- .../http/DefaultRestTemplateProvider.java | 2 +- .../contribs/tasks/http/HttpTask.java | 35 +- .../tasks/http/RestTemplateProvider.java | 2 +- .../contribs/tasks/json/JsonJqTransform.java | 14 +- .../tasks/kafka/KafkaProducerManager.java | 2 +- .../tasks/kafka/KafkaPublishTask.java | 22 +- .../ArchivingWorkflowStatusListenerTest.java | 14 +- .../sqs/DefaultEventQueueProcessorTest.java | 7 +- .../http/DefaultRestTemplateProviderTest.java | 2 +- .../contribs/tasks/http/HttpTaskTest.java | 685 ++++++++-------- .../tasks/json/JsonJqTransformTest.java | 18 +- .../tasks/kafka/KafkaPublishTaskTest.java | 52 +- .../netflix/conductor/annotations/Audit.java | 2 +- .../netflix/conductor/annotations/Trace.java | 2 +- .../core/LifecycleAwareComponent.java | 2 +- .../conductor/core/WorkflowContext.java | 4 +- .../ExecutionDAOFacade.java | 145 ++-- .../conductor/core/dal/ModelMapper.java | 192 +++++ .../core/events/ActionProcessor.java | 2 +- .../core/events/DefaultEventProcessor.java | 2 +- .../core/events/DefaultEventQueueManager.java | 3 +- .../core/events/EventQueueManager.java | 2 +- .../core/events/EventQueueProvider.java | 2 +- .../conductor/core/events/EventQueues.java | 2 +- .../core/events/ScriptEvaluator.java | 2 +- .../core/events/SimpleActionProcessor.java | 26 +- .../queue/ConductorEventQueueProvider.java | 3 +- .../queue/ConductorObservableQueue.java | 2 +- .../queue/DefaultEventQueueProcessor.java | 13 +- .../conductor/core/events/queue/Message.java | 2 +- .../core/events/queue/ObservableQueue.java | 2 +- .../core/exception/ApplicationException.java | 5 +- .../exception/TerminateWorkflowException.java | 23 +- .../execution/AsyncSystemTaskExecutor.java | 49 +- .../core/execution/DeciderService.java | 265 +++---- .../core/execution/WorkflowExecutor.java | 413 +++++----- .../core/execution/evaluators/Evaluator.java | 2 +- .../evaluators/JavascriptEvaluator.java | 3 +- .../evaluators/ValueParamEvaluator.java | 4 +- .../execution/mapper/DecisionTaskMapper.java | 31 +- .../execution/mapper/DoWhileTaskMapper.java | 31 +- .../execution/mapper/DynamicTaskMapper.java | 25 +- .../execution/mapper/EventTaskMapper.java | 14 +- .../mapper/ExclusiveJoinTaskMapper.java | 14 +- .../mapper/ForkJoinDynamicTaskMapper.java | 87 ++- .../execution/mapper/ForkJoinTaskMapper.java | 26 +- .../core/execution/mapper/HTTPTaskMapper.java | 37 +- .../execution/mapper/InlineTaskMapper.java | 27 +- .../core/execution/mapper/JoinTaskMapper.java | 22 +- .../mapper/JsonJQTransformTaskMapper.java | 21 +- .../mapper/KafkaPublishTaskMapper.java | 26 +- .../execution/mapper/LambdaTaskMapper.java | 21 +- .../mapper/SetVariableTaskMapper.java | 14 +- .../execution/mapper/SimpleTaskMapper.java | 20 +- .../mapper/SubWorkflowTaskMapper.java | 24 +- .../execution/mapper/SwitchTaskMapper.java | 31 +- .../core/execution/mapper/TaskMapper.java | 6 +- .../execution/mapper/TaskMapperContext.java | 12 +- .../execution/mapper/TerminateTaskMapper.java | 14 +- .../mapper/UserDefinedTaskMapper.java | 22 +- .../core/execution/mapper/WaitTaskMapper.java | 17 +- .../core/execution/tasks/Decision.java | 12 +- .../core/execution/tasks/DoWhile.java | 52 +- .../conductor/core/execution/tasks/Event.java | 24 +- .../core/execution/tasks/ExclusiveJoin.java | 22 +- .../core/execution/tasks/ExecutionConfig.java | 2 +- .../conductor/core/execution/tasks/Fork.java | 2 +- .../core/execution/tasks/Inline.java | 13 +- .../tasks/IsolatedTaskQueueProducer.java | 2 +- .../conductor/core/execution/tasks/Join.java | 18 +- .../core/execution/tasks/Lambda.java | 15 +- .../core/execution/tasks/SetVariable.java | 14 +- .../core/execution/tasks/SubWorkflow.java | 45 +- .../core/execution/tasks/Switch.java | 12 +- .../execution/tasks/SystemTaskRegistry.java | 2 +- .../execution/tasks/SystemTaskWorker.java | 2 +- .../tasks/SystemTaskWorkerCoordinator.java | 2 +- .../core/execution/tasks/Terminate.java | 13 +- .../conductor/core/execution/tasks/Wait.java | 18 +- .../execution/tasks/WorkflowSystemTask.java | 19 +- .../core/listener/WorkflowStatusListener.java | 16 +- .../listener/WorkflowStatusListenerStub.java | 10 +- .../core/metadata/MetadataMapperService.java | 10 +- .../reconciliation/WorkflowReconciler.java | 5 +- .../reconciliation/WorkflowRepairService.java | 37 +- .../core/reconciliation/WorkflowSweeper.java | 5 +- .../core/storage/DummyPayloadStorage.java | 2 +- .../com/netflix/conductor/core/sync/Lock.java | 6 +- .../netflix/conductor/core/sync/NoopLock.java | 2 +- .../utils/ExternalPayloadStorageUtils.java | 71 +- .../conductor/core/utils/IDGenerator.java | 2 +- .../conductor/core/utils/JsonUtils.java | 2 +- .../conductor/core/utils/ParametersUtils.java | 77 +- .../conductor/core/utils/QueueUtils.java | 11 +- .../conductor/core/utils/SemaphoreUtil.java | 2 +- .../netflix/conductor/core/utils/Utils.java | 4 +- .../dao/ConcurrentExecutionLimitDAO.java | 10 +- .../conductor/dao/EventHandlerDAO.java | 2 +- .../netflix/conductor/dao/ExecutionDAO.java | 40 +- .../com/netflix/conductor/dao/IndexDAO.java | 14 +- .../netflix/conductor/dao/MetadataDAO.java | 2 +- .../netflix/conductor/dao/PollDataDAO.java | 2 +- .../com/netflix/conductor/dao/QueueDAO.java | 2 +- .../conductor/dao/RateLimitingDAO.java | 10 +- .../netflix/conductor/metrics/Monitors.java | 18 +- .../conductor/metrics/WorkflowMonitor.java | 4 +- .../netflix/conductor/model/TaskModel.java | 735 ++++++++++++++++++ .../conductor/model/WorkflowModel.java | 448 +++++++++++ .../conductor/service/AdminService.java | 6 +- .../conductor/service/AdminServiceImpl.java | 7 +- .../conductor/service/EventService.java | 2 +- .../conductor/service/EventServiceImpl.java | 2 +- .../service/ExecutionLockService.java | 2 +- .../conductor/service/ExecutionService.java | 72 +- .../conductor/service/MetadataService.java | 2 +- .../service/MetadataServiceImpl.java | 3 +- .../conductor/service/TaskService.java | 2 +- .../conductor/service/TaskServiceImpl.java | 39 +- .../service/WorkflowBulkService.java | 2 +- .../service/WorkflowBulkServiceImpl.java | 2 +- .../conductor/service/WorkflowService.java | 2 +- .../service/WorkflowServiceImpl.java | 22 +- .../validations/ValidationContext.java | 2 +- .../WorkflowTaskTypeConstraint.java | 7 +- .../WorkflowTaskValidConstraint.java | 6 +- .../conductor/core/dal/ModelMapperSpec.groovy | 156 ++++ .../AsyncSystemTaskExecutorTest.groovy | 158 ++-- .../core/execution/tasks/EventSpec.groovy | 88 +-- .../IsolatedTaskQueueProducerSpec.groovy | 29 +- .../ExecutionDAOFacadeTest.java | 65 +- .../events/TestDefaultEventProcessor.java | 34 +- .../events/TestSimpleActionProcessor.java | 24 +- .../core/execution/TestDeciderOutcomes.java | 75 +- .../core/execution/TestDeciderService.java | 347 ++++----- .../core/execution/TestWorkflowExecutor.java | 731 ++++++++--------- .../execution/WorkflowSystemTaskStub.java | 11 +- .../mapper/DecisionTaskMapperTest.java | 18 +- .../mapper/DoWhileTaskMapperTest.java | 22 +- .../mapper/DynamicTaskMapperTest.java | 14 +- .../execution/mapper/EventTaskMapperTest.java | 14 +- .../mapper/ForkJoinDynamicTaskMapperTest.java | 46 +- .../mapper/ForkJoinTaskMapperTest.java | 20 +- .../execution/mapper/HTTPTaskMapperTest.java | 14 +- .../mapper/InlineTaskMapperTest.java | 14 +- .../execution/mapper/JoinTaskMapperTest.java | 14 +- .../mapper/JsonJQTransformTaskMapperTest.java | 14 +- .../mapper/KafkaPublishTaskMapperTest.java | 14 +- .../mapper/LambdaTaskMapperTest.java | 14 +- .../mapper/SetVariableTaskMapperTest.java | 10 +- .../mapper/SimpleTaskMapperTest.java | 12 +- .../mapper/SubWorkflowTaskMapperTest.java | 30 +- .../mapper/SwitchTaskMapperTest.java | 18 +- .../mapper/TerminateTaskMapperTest.java | 10 +- .../mapper/UserDefinedTaskMapperTest.java | 12 +- .../execution/mapper/WaitTaskMapperTest.java | 10 +- .../tasks/EventQueueResolutionTest.java | 31 +- .../core/execution/tasks/InlineTest.java | 31 +- .../core/execution/tasks/TestDoWhile.java | 65 +- .../core/execution/tasks/TestLambda.java | 20 +- .../core/execution/tasks/TestSubWorkflow.java | 108 +-- .../core/execution/tasks/TestTerminate.java | 54 +- .../TestWorkflowRepairService.java | 57 +- .../ExternalPayloadStorageUtilsTest.java | 34 +- .../conductor/dao/ExecutionDAOTest.java | 111 ++- .../service/ExecutionServiceTest.java | 67 +- .../es6/config/ElasticSearchConditions.java | 2 +- .../es6/config/ElasticSearchProperties.java | 2 +- .../config/ElasticSearchV6Configuration.java | 2 +- .../es6/dao/index/ElasticSearchDAOV6.java | 36 +- .../es6/dao/index/ElasticSearchRestDAOV6.java | 44 +- .../es6/dao/index/TestElasticSearchDAOV6.java | 79 +- .../index/TestElasticSearchDAOV6Batch.java | 45 +- .../dao/index/TestElasticSearchRestDAOV6.java | 110 ++- .../TestElasticSearchRestDAOV6Batch.java | 45 +- .../conductor/es6/utils/TestUtils.java | 20 +- .../src/test/resources/task_summary.json | 17 + .../src/test/resources/workflow.json | 77 -- .../src/test/resources/workflow_summary.json | 12 + .../es7/dao/index/ElasticSearchRestDAOV7.java | 45 +- .../dao/index/TestElasticSearchRestDAOV7.java | 137 ++-- .../TestElasticSearchRestDAOV7Batch.java | 44 +- .../conductor/es7/utils/TestUtils.java | 22 +- .../src/test/resources/task_summary.json | 17 + .../src/test/resources/workflow.json | 77 -- .../src/test/resources/workflow_summary.json | 12 + .../conductor/client/grpc/TaskClient.java | 2 +- .../mysql/config/MySQLConfiguration.java | 3 +- .../mysql/dao/MySQLExecutionDAO.java | 135 ++-- .../conductor/mysql/dao/MySQLMetadataDAO.java | 2 +- .../conductor/mysql/dao/MySQLQueueDAO.java | 2 +- .../mysql/dao/MySQLExecutionDAOTest.java | 8 +- .../config/PostgresConfiguration.java | 3 +- .../postgres/config/PostgresProperties.java | 2 +- .../postgres/dao/PostgresBaseDAO.java | 2 +- .../postgres/dao/PostgresExecutionDAO.java | 134 ++-- .../postgres/dao/PostgresMetadataDAO.java | 2 +- .../postgres/dao/PostgresQueueDAO.java | 2 +- .../dao/PostgresExecutionDAOTest.java | 10 +- .../postgres/dao/PostgresMetadataDAOTest.java | 2 +- .../postgres/dao/PostgresQueueDAOTest.java | 2 +- .../RedisConcurrentExecutionLimitDAO.java | 24 +- ...edisConcurrentExecutionLimitDAOSpec.groovy | 43 +- redis-lock/build.gradle | 1 - .../conductor/redis/dao/BaseDynoDAO.java | 2 +- .../conductor/redis/dao/DynoQueueDAO.java | 2 +- .../redis/dao/RedisEventHandlerDAO.java | 2 +- .../redis/dao/RedisExecutionDAO.java | 107 ++- .../conductor/redis/dao/RedisMetadataDAO.java | 2 +- .../conductor/redis/dao/RedisPollDataDAO.java | 2 +- .../redis/dao/RedisRateLimitingDAO.java | 24 +- .../dynoqueue/ConfigurationHostSupplier.java | 2 +- .../dynoqueue/LocalhostHostSupplier.java | 2 +- .../RedisQueuesShardingStrategyProvider.java | 2 +- .../redis/dao/RedisExecutionDAOTest.java | 11 +- .../redis/dao/RedisRateLimitDAOTest.java | 8 +- test-harness/build.gradle | 7 - .../AbstractResiliencySpecification.groovy | 2 +- .../test/integration/DecisionTaskSpec.groovy | 2 +- .../test/integration/DoWhileSpec.groovy | 4 +- .../integration/DynamicForkJoinSpec.groovy | 2 +- .../test/integration/EventTaskSpec.groovy | 2 +- .../test/integration/ExclusiveJoinSpec.groovy | 2 +- .../ExternalPayloadStorageSpec.groovy | 48 +- .../test/integration/ForkJoinSpec.groovy | 2 +- ...rchicalForkJoinSubworkflowRerunSpec.groovy | 2 +- ...hicalForkJoinSubworkflowRestartSpec.groovy | 2 +- ...rchicalForkJoinSubworkflowRetrySpec.groovy | 2 +- .../integration/JsonJQTransformSpec.groovy | 2 +- .../integration/KafkaPublishTaskSpec.groovy | 2 +- .../LambdaAndTerminateTaskSpec.groovy | 2 +- .../NestedForkJoinSubWorkflowSpec.groovy | 2 +- .../integration/SetVariableTaskSpec.groovy | 2 +- .../integration/SimpleWorkflowSpec.groovy | 10 +- .../integration/SubWorkflowRerunSpec.groovy | 2 +- .../integration/SubWorkflowRestartSpec.groovy | 2 +- .../integration/SubWorkflowRetrySpec.groovy | 2 +- .../test/integration/SubWorkflowSpec.groovy | 2 +- .../test/integration/SwitchTaskSpec.groovy | 2 +- .../test/integration/SystemTaskSpec.groovy | 2 +- .../integration/TaskLimitsWorkflowSpec.groovy | 5 +- .../test/integration/WaitTaskSpec.groovy | 2 +- .../WorkflowAndTaskConfigurationSpec.groovy | 12 +- .../resiliency/QueueResiliencySpec.groovy | 2 +- .../test/resiliency/TaskResiliencySpec.groovy | 2 +- .../test/util/WorkflowTestUtil.groovy | 41 +- ...orkflowStatusPublisherIntegrationTest.java | 8 +- .../conductor/test/utils/UserTask.java | 15 +- zookeeper-lock/build.gradle | 1 - 279 files changed, 5165 insertions(+), 4032 deletions(-) rename core/src/main/java/com/netflix/conductor/core/{orchestration => dal}/ExecutionDAOFacade.java (81%) create mode 100644 core/src/main/java/com/netflix/conductor/core/dal/ModelMapper.java create mode 100644 core/src/main/java/com/netflix/conductor/model/TaskModel.java create mode 100644 core/src/main/java/com/netflix/conductor/model/WorkflowModel.java create mode 100644 core/src/test/groovy/com/netflix/conductor/core/dal/ModelMapperSpec.groovy rename core/src/test/java/com/netflix/conductor/core/{orchestration => dal}/ExecutionDAOFacadeTest.java (78%) create mode 100644 es6-persistence/src/test/resources/task_summary.json delete mode 100644 es6-persistence/src/test/resources/workflow.json create mode 100644 es6-persistence/src/test/resources/workflow_summary.json create mode 100644 es7-persistence/src/test/resources/task_summary.json delete mode 100644 es7-persistence/src/test/resources/workflow.json create mode 100644 es7-persistence/src/test/resources/workflow_summary.json diff --git a/build.gradle b/build.gradle index b350de13e6..75ea80bdca 100644 --- a/build.gradle +++ b/build.gradle @@ -184,3 +184,14 @@ configure(allprojects - project(':conductor-grpc')) { } } } + +["cassandra-persistence", "core", "redis-concurrency-limit", "test-harness"].each { + configure(project(":conductor-$it")) { + spotless { + groovy { + importOrder('java', 'javax', 'org', 'com.netflix', '', '\\#com.netflix', '\\#') + licenseHeaderFile("$rootDir/licenseheader.txt") + } + } + } +} diff --git a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/config/CassandraConfiguration.java b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/config/CassandraConfiguration.java index 352e5cfec1..2d2725f3e3 100644 --- a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/config/CassandraConfiguration.java +++ b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/config/CassandraConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/config/CassandraProperties.java b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/config/CassandraProperties.java index 19286cad45..28d3eee972 100644 --- a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/config/CassandraProperties.java +++ b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/config/CassandraProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraBaseDAO.java b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraBaseDAO.java index 70664c1694..c576be8e91 100644 --- a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraBaseDAO.java +++ b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraBaseDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraEventHandlerDAO.java b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraEventHandlerDAO.java index ea0b12de9f..ce797cea9e 100644 --- a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraEventHandlerDAO.java +++ b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraEventHandlerDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraExecutionDAO.java b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraExecutionDAO.java index 74e2016da8..4341186d70 100644 --- a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraExecutionDAO.java +++ b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraExecutionDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -27,15 +27,15 @@ import com.netflix.conductor.cassandra.config.CassandraProperties; import com.netflix.conductor.cassandra.util.Statements; import com.netflix.conductor.common.metadata.events.EventExecution; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.utils.RetryUtil; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.exception.ApplicationException.Code; import com.netflix.conductor.dao.ConcurrentExecutionLimitDAO; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.datastax.driver.core.BatchStatement; import com.datastax.driver.core.PreparedStatement; @@ -56,7 +56,6 @@ import static com.netflix.conductor.cassandra.util.Constants.TOTAL_PARTITIONS_KEY; import static com.netflix.conductor.cassandra.util.Constants.TOTAL_TASKS_KEY; import static com.netflix.conductor.cassandra.util.Constants.WORKFLOW_ID_KEY; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.IN_PROGRESS; @Trace public class CassandraExecutionDAO extends CassandraBaseDAO @@ -172,11 +171,11 @@ public CassandraExecutionDAO( } @Override - public List getPendingTasksByWorkflow(String taskName, String workflowId) { - List tasks = getTasksForWorkflow(workflowId); + public List getPendingTasksByWorkflow(String taskName, String workflowId) { + List tasks = getTasksForWorkflow(workflowId); return tasks.stream() .filter(task -> taskName.equals(task.getTaskType())) - .filter(task -> IN_PROGRESS.equals(task.getStatus())) + .filter(task -> TaskModel.Status.IN_PROGRESS.equals(task.getStatus())) .collect(Collectors.toList()); } @@ -185,7 +184,7 @@ public List getPendingTasksByWorkflow(String taskName, String workflowId) * Conductor */ @Override - public List getTasks(String taskType, String startKey, int count) { + public List getTasks(String taskType, String startKey, int count) { throw new UnsupportedOperationException( "This method is not implemented in CassandraExecutionDAO. Please use ExecutionDAOFacade instead."); } @@ -198,7 +197,7 @@ public List getTasks(String taskType, String startKey, int count) { * @param tasks tasks to be created */ @Override - public List createTasks(List tasks) { + public List createTasks(List tasks) { validateTasks(tasks); String workflowId = tasks.get(0).getWorkflowInstanceId(); try { @@ -259,7 +258,7 @@ public List createTasks(List tasks) { } @Override - public void updateTask(Task task) { + public void updateTask(TaskModel task) { try { // TODO: calculate the shard number the task belongs to String taskPayload = toJson(task); @@ -276,7 +275,7 @@ public void updateTask(Task task) { && task.getTaskDefinition().get().concurrencyLimit() > 0) { if (task.getStatus().isTerminal()) { removeTaskFromLimit(task); - } else if (task.getStatus() == IN_PROGRESS) { + } else if (task.getStatus() == TaskModel.Status.IN_PROGRESS) { addTaskToLimit(task); } } @@ -296,7 +295,7 @@ public void updateTask(Task task) { * Conductor */ @Override - public boolean exceedsLimit(Task task) { + public boolean exceedsLimit(TaskModel task) { Optional taskDefinition = task.getTaskDefinition(); if (taskDefinition.isEmpty()) { return false; @@ -342,7 +341,7 @@ public boolean exceedsLimit(Task task) { @Override public boolean removeTask(String taskId) { - Task task = getTask(taskId); + TaskModel task = getTask(taskId); if (task == null) { LOGGER.warn("No such task found by id {}", taskId); return false; @@ -351,7 +350,7 @@ public boolean removeTask(String taskId) { } @Override - public Task getTask(String taskId) { + public TaskModel getTask(String taskId) { try { String workflowId = lookupWorkflowIdFromTaskId(taskId); if (workflowId == null) { @@ -366,7 +365,8 @@ public Task getTask(String taskId) { return Optional.ofNullable(resultSet.one()) .map( row -> { - Task task = readValue(row.getString(PAYLOAD_KEY), Task.class); + TaskModel task = + readValue(row.getString(PAYLOAD_KEY), TaskModel.class); recordCassandraDaoRequests( "getTask", task.getTaskType(), task.getWorkflowType()); recordCassandraDaoPayloadSize( @@ -388,7 +388,7 @@ public Task getTask(String taskId) { } @Override - public List getTasks(List taskIds) { + public List getTasks(List taskIds) { Preconditions.checkNotNull(taskIds); Preconditions.checkArgument(taskIds.size() > 0, "Task ids list cannot be empty"); String workflowId = lookupWorkflowIdFromTaskId(taskIds.get(0)); @@ -405,20 +405,20 @@ public List getTasks(List taskIds) { * Conductor */ @Override - public List getPendingTasksForTaskType(String taskType) { + public List getPendingTasksForTaskType(String taskType) { throw new UnsupportedOperationException( "This method is not implemented in CassandraExecutionDAO. Please use ExecutionDAOFacade instead."); } @Override - public List getTasksForWorkflow(String workflowId) { + public List getTasksForWorkflow(String workflowId) { return getWorkflow(workflowId, true).getTasks(); } @Override - public String createWorkflow(Workflow workflow) { + public String createWorkflow(WorkflowModel workflow) { try { - List tasks = workflow.getTasks(); + List tasks = workflow.getTasks(); workflow.setTasks(new LinkedList<>()); String payload = toJson(workflow); @@ -441,9 +441,9 @@ public String createWorkflow(Workflow workflow) { } @Override - public String updateWorkflow(Workflow workflow) { + public String updateWorkflow(WorkflowModel workflow) { try { - List tasks = workflow.getTasks(); + List tasks = workflow.getTasks(); workflow.setTasks(new LinkedList<>()); String payload = toJson(workflow); recordCassandraDaoRequests("updateWorkflow", "n/a", workflow.getWorkflowName()); @@ -465,7 +465,7 @@ public String updateWorkflow(Workflow workflow) { @Override public boolean removeWorkflow(String workflowId) { - Workflow workflow = getWorkflow(workflowId, true); + WorkflowModel workflow = getWorkflow(workflowId, true); boolean removed = false; // TODO: calculate number of shards and iterate if (workflow != null) { @@ -508,13 +508,13 @@ public void removeFromPendingWorkflow(String workflowType, String workflowId) { } @Override - public Workflow getWorkflow(String workflowId) { + public WorkflowModel getWorkflow(String workflowId) { return getWorkflow(workflowId, true); } @Override - public Workflow getWorkflow(String workflowId, boolean includeTasks) { - Workflow workflow = null; + public WorkflowModel getWorkflow(String workflowId, boolean includeTasks) { + WorkflowModel workflow = null; try { ResultSet resultSet; if (includeTasks) { @@ -522,7 +522,7 @@ public Workflow getWorkflow(String workflowId, boolean includeTasks) { session.execute( selectWorkflowWithTasksStatement.bind( UUID.fromString(workflowId), DEFAULT_SHARD_ID)); - List tasks = new ArrayList<>(); + List tasks = new ArrayList<>(); List rows = resultSet.all(); if (rows.size() == 0) { @@ -532,9 +532,9 @@ public Workflow getWorkflow(String workflowId, boolean includeTasks) { for (Row row : rows) { String entityKey = row.getString(ENTITY_KEY); if (ENTITY_TYPE_WORKFLOW.equals(entityKey)) { - workflow = readValue(row.getString(PAYLOAD_KEY), Workflow.class); + workflow = readValue(row.getString(PAYLOAD_KEY), WorkflowModel.class); } else if (ENTITY_TYPE_TASK.equals(entityKey)) { - Task task = readValue(row.getString(PAYLOAD_KEY), Task.class); + TaskModel task = readValue(row.getString(PAYLOAD_KEY), TaskModel.class); tasks.add(task); } else { throw new ApplicationException( @@ -547,7 +547,7 @@ public Workflow getWorkflow(String workflowId, boolean includeTasks) { if (workflow != null) { recordCassandraDaoRequests("getWorkflow", "n/a", workflow.getWorkflowName()); - tasks.sort(Comparator.comparingInt(Task::getSeq)); + tasks.sort(Comparator.comparingInt(TaskModel::getSeq)); workflow.setTasks(tasks); } } else { @@ -557,10 +557,10 @@ public Workflow getWorkflow(String workflowId, boolean includeTasks) { Optional.ofNullable(resultSet.one()) .map( row -> { - Workflow wf = + WorkflowModel wf = readValue( row.getString(PAYLOAD_KEY), - Workflow.class); + WorkflowModel.class); recordCassandraDaoRequests( "getWorkflow", "n/a", wf.getWorkflowName()); return wf; @@ -598,7 +598,7 @@ public List getRunningWorkflowIds(String workflowName, int version) { * Conductor */ @Override - public List getPendingWorkflowsByType(String workflowName, int version) { + public List getPendingWorkflowsByType(String workflowName, int version) { throw new UnsupportedOperationException( "This method is not implemented in CassandraExecutionDAO. Please use ExecutionDAOFacade instead."); } @@ -628,7 +628,8 @@ public long getInProgressTaskCount(String taskDefName) { * Conductor */ @Override - public List getWorkflowsByType(String workflowName, Long startTime, Long endTime) { + public List getWorkflowsByType( + String workflowName, Long startTime, Long endTime) { throw new UnsupportedOperationException( "This method is not implemented in CassandraExecutionDAO. Please use ExecutionDAOFacade instead."); } @@ -638,7 +639,7 @@ public List getWorkflowsByType(String workflowName, Long startTime, Lo * Conductor */ @Override - public List getWorkflowsByCorrelationId( + public List getWorkflowsByCorrelationId( String workflowName, String correlationId, boolean includeTasks) { throw new UnsupportedOperationException( "This method is not implemented in CassandraExecutionDAO. Please use ExecutionDAOFacade instead."); @@ -741,7 +742,7 @@ List getEventExecutions( } @Override - public void addTaskToLimit(Task task) { + public void addTaskToLimit(TaskModel task) { try { recordCassandraDaoRequests( "addTaskToLimit", task.getTaskType(), task.getWorkflowType()); @@ -770,7 +771,7 @@ public void addTaskToLimit(Task task) { } @Override - public void removeTaskFromLimit(Task task) { + public void removeTaskFromLimit(TaskModel task) { try { recordCassandraDaoRequests( "removeTaskFromLimit", task.getTaskType(), task.getWorkflowType()); @@ -797,7 +798,7 @@ public void removeTaskFromLimit(Task task) { } } - private boolean removeTask(Task task) { + private boolean removeTask(TaskModel task) { // TODO: calculate shard number based on seq and maxTasksPerShard try { // get total tasks for this workflow @@ -834,7 +835,7 @@ private boolean removeTask(Task task) { } } - private void removeTaskLookup(Task task) { + private void removeTaskLookup(TaskModel task) { try { recordCassandraDaoRequests( "removeTaskLookup", task.getTaskType(), task.getWorkflowType()); @@ -854,7 +855,7 @@ private void removeTaskLookup(Task task) { } @VisibleForTesting - void validateTasks(List tasks) { + void validateTasks(List tasks) { Preconditions.checkNotNull(tasks, "Tasks object cannot be null"); Preconditions.checkArgument(!tasks.isEmpty(), "Tasks object cannot be empty"); tasks.forEach( @@ -868,7 +869,7 @@ void validateTasks(List tasks) { }); String workflowId = tasks.get(0).getWorkflowInstanceId(); - Optional optionalTask = + Optional optionalTask = tasks.stream() .filter(task -> !workflowId.equals(task.getWorkflowInstanceId())) .findAny(); diff --git a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraMetadataDAO.java b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraMetadataDAO.java index a9f9fe44c0..10bbe2dd51 100644 --- a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraMetadataDAO.java +++ b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/dao/CassandraMetadataDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/util/Constants.java b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/util/Constants.java index f5eb9f7dfe..473c23132c 100644 --- a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/util/Constants.java +++ b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/util/Constants.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/util/Statements.java b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/util/Statements.java index 5c538c41e7..a6ea122538 100644 --- a/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/util/Statements.java +++ b/cassandra-persistence/src/main/java/com/netflix/conductor/cassandra/util/Statements.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraEventHandlerDAOSpec.groovy b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraEventHandlerDAOSpec.groovy index 912d36c65c..214f3722de 100644 --- a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraEventHandlerDAOSpec.groovy +++ b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraEventHandlerDAOSpec.groovy @@ -1,20 +1,20 @@ /* - * Copyright 2021 Netflix, Inc. - *

- * 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. + * Copyright 2022 Netflix, Inc. + *

+ * 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.cassandra.dao import com.netflix.conductor.common.metadata.events.EventExecution import com.netflix.conductor.common.metadata.events.EventHandler + import spock.lang.Subject class CassandraEventHandlerDAOSpec extends CassandraSpec { diff --git a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraExecutionDAOSpec.groovy b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraExecutionDAOSpec.groovy index 11727500ae..2a3b81c390 100644 --- a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraExecutionDAOSpec.groovy +++ b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraExecutionDAOSpec.groovy @@ -1,26 +1,26 @@ /* - * Copyright 2021 Netflix, Inc. - *

- * 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. + * Copyright 2022 Netflix, Inc. + *

+ * 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.cassandra.dao import com.netflix.conductor.common.metadata.events.EventExecution -import com.netflix.conductor.common.metadata.tasks.Task import com.netflix.conductor.common.metadata.tasks.TaskDef 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.core.exception.ApplicationException import com.netflix.conductor.core.utils.IDGenerator +import com.netflix.conductor.model.TaskModel +import com.netflix.conductor.model.WorkflowModel + import spock.lang.Subject import static com.netflix.conductor.common.metadata.events.EventExecution.Status.COMPLETED @@ -40,8 +40,8 @@ class CassandraExecutionDAOSpec extends CassandraSpec { def tasks = [] // create tasks for a workflow and add to list - Task task1 = new Task(workflowInstanceId: 'uuid', taskId: 'task1id', referenceTaskName: 'task1') - Task task2 = new Task(workflowInstanceId: 'uuid', taskId: 'task2id', referenceTaskName: 'task2') + TaskModel task1 = new TaskModel(workflowInstanceId: 'uuid', taskId: 'task1id', referenceTaskName: 'task1') + TaskModel task2 = new TaskModel(workflowInstanceId: 'uuid', taskId: 'task2id', referenceTaskName: 'task2') tasks << task1 << task2 when: @@ -52,7 +52,7 @@ class CassandraExecutionDAOSpec extends CassandraSpec { and: // add a task from a different workflow to the list - Task task3 = new Task(workflowInstanceId: 'other-uuid', taskId: 'task3id', referenceTaskName: 'task3') + TaskModel task3 = new TaskModel(workflowInstanceId: 'other-uuid', taskId: 'task3id', referenceTaskName: 'task3') tasks << task3 when: @@ -69,11 +69,11 @@ class CassandraExecutionDAOSpec extends CassandraSpec { WorkflowDef workflowDef = new WorkflowDef() workflowDef.name = "def1" workflowDef.setVersion(1) - Workflow workflow = new Workflow() + WorkflowModel workflow = new WorkflowModel() workflow.setWorkflowDefinition(workflowDef) workflow.setWorkflowId(workflowId) workflow.setInput(new HashMap<>()) - workflow.setStatus(Workflow.WorkflowStatus.RUNNING) + workflow.setStatus(WorkflowModel.Status.RUNNING) workflow.setCreateTime(System.currentTimeMillis()) when: @@ -85,14 +85,14 @@ class CassandraExecutionDAOSpec extends CassandraSpec { when: // read the workflow from the datastore - Workflow found = executionDAO.getWorkflow(workflowId) + WorkflowModel found = executionDAO.getWorkflow(workflowId) then: workflow == found and: // update the workflow - workflow.setStatus(Workflow.WorkflowStatus.COMPLETED) + workflow.setStatus(WorkflowModel.Status.COMPLETED) executionDAO.updateWorkflow(workflow) when: @@ -120,18 +120,18 @@ class CassandraExecutionDAOSpec extends CassandraSpec { given: 'we create a workflow' String workflowId = IDGenerator.generate() WorkflowDef workflowDef = new WorkflowDef(name: 'def1', version: 1) - Workflow workflow = new Workflow(workflowDefinition: workflowDef, workflowId: workflowId, input: new HashMap(), status: Workflow.WorkflowStatus.RUNNING, createTime: System.currentTimeMillis()) + WorkflowModel workflow = new WorkflowModel(workflowDefinition: workflowDef, workflowId: workflowId, input: new HashMap(), status: WorkflowModel.Status.RUNNING, createTime: System.currentTimeMillis()) executionDAO.createWorkflow(workflow) and: 'create tasks for this workflow' - Task task1 = new Task(workflowInstanceId: workflowId, taskType: 'task1', referenceTaskName: 'task1', status: Task.Status.SCHEDULED, taskId: IDGenerator.generate()) - Task task2 = new Task(workflowInstanceId: workflowId, taskType: 'task2', referenceTaskName: 'task2', status: Task.Status.SCHEDULED, taskId: IDGenerator.generate()) - Task task3 = new Task(workflowInstanceId: workflowId, taskType: 'task3', referenceTaskName: 'task3', status: Task.Status.SCHEDULED, taskId: IDGenerator.generate()) + TaskModel task1 = new TaskModel(workflowInstanceId: workflowId, taskType: 'task1', referenceTaskName: 'task1', status: TaskModel.Status.SCHEDULED, taskId: IDGenerator.generate()) + TaskModel task2 = new TaskModel(workflowInstanceId: workflowId, taskType: 'task2', referenceTaskName: 'task2', status: TaskModel.Status.SCHEDULED, taskId: IDGenerator.generate()) + TaskModel task3 = new TaskModel(workflowInstanceId: workflowId, taskType: 'task3', referenceTaskName: 'task3', status: TaskModel.Status.SCHEDULED, taskId: IDGenerator.generate()) def taskList = [task1, task2, task3] when: 'add the tasks to the datastore' - List tasks = executionDAO.createTasks(taskList) + List tasks = executionDAO.createTasks(taskList) then: tasks != null @@ -177,7 +177,7 @@ class CassandraExecutionDAOSpec extends CassandraSpec { fetchedTasks != null && fetchedTasks.size() == 3 when: 'read workflow with tasks' - Workflow found = executionDAO.getWorkflow(workflowId, true) + WorkflowModel found = executionDAO.getWorkflow(workflowId, true) then: found != null @@ -192,21 +192,21 @@ class CassandraExecutionDAOSpec extends CassandraSpec { given: 'we create a workflow' String workflowId = IDGenerator.generate() WorkflowDef workflowDef = new WorkflowDef(name: 'def1', version: 1) - Workflow workflow = new Workflow(workflowDefinition: workflowDef, workflowId: workflowId, input: new HashMap(), status: Workflow.WorkflowStatus.RUNNING, createTime: System.currentTimeMillis()) + WorkflowModel workflow = new WorkflowModel(workflowDefinition: workflowDef, workflowId: workflowId, input: new HashMap(), status: WorkflowModel.Status.RUNNING, createTime: System.currentTimeMillis()) executionDAO.createWorkflow(workflow) and: 'create tasks for this workflow' - Task task1 = new Task(workflowInstanceId: workflowId, taskType: 'task1', referenceTaskName: 'task1', status: Task.Status.SCHEDULED, taskId: IDGenerator.generate()) - Task task2 = new Task(workflowInstanceId: workflowId, taskType: 'task2', referenceTaskName: 'task2', status: Task.Status.SCHEDULED, taskId: IDGenerator.generate()) - Task task3 = new Task(workflowInstanceId: workflowId, taskType: 'task3', referenceTaskName: 'task3', status: Task.Status.SCHEDULED, taskId: IDGenerator.generate()) + TaskModel task1 = new TaskModel(workflowInstanceId: workflowId, taskType: 'task1', referenceTaskName: 'task1', status: TaskModel.Status.SCHEDULED, taskId: IDGenerator.generate()) + TaskModel task2 = new TaskModel(workflowInstanceId: workflowId, taskType: 'task2', referenceTaskName: 'task2', status: TaskModel.Status.SCHEDULED, taskId: IDGenerator.generate()) + TaskModel task3 = new TaskModel(workflowInstanceId: workflowId, taskType: 'task3', referenceTaskName: 'task3', status: TaskModel.Status.SCHEDULED, taskId: IDGenerator.generate()) and: 'add the tasks to the datastore' executionDAO.createTasks([task1, task2, task3]) and: 'change the status of those tasks' - task1.setStatus(Task.Status.IN_PROGRESS) - task2.setStatus(Task.Status.COMPLETED) - task3.setStatus(Task.Status.FAILED) + task1.setStatus(TaskModel.Status.IN_PROGRESS) + task2.setStatus(TaskModel.Status.COMPLETED) + task3.setStatus(TaskModel.Status.FAILED) when: 'update the tasks' executionDAO.updateTask(task1) @@ -214,12 +214,12 @@ class CassandraExecutionDAOSpec extends CassandraSpec { executionDAO.updateTask(task3) then: - executionDAO.getTask(task1.taskId).status == Task.Status.IN_PROGRESS - executionDAO.getTask(task2.taskId).status == Task.Status.COMPLETED - executionDAO.getTask(task3.taskId).status == Task.Status.FAILED + executionDAO.getTask(task1.taskId).status == TaskModel.Status.IN_PROGRESS + executionDAO.getTask(task2.taskId).status == TaskModel.Status.COMPLETED + executionDAO.getTask(task3.taskId).status == TaskModel.Status.FAILED when: 'get pending tasks for the workflow' - List pendingTasks = executionDAO.getPendingTasksByWorkflow(task1.getTaskType(), workflowId) + List pendingTasks = executionDAO.getPendingTasksByWorkflow(task1.getTaskType(), workflowId) then: pendingTasks != null && pendingTasks.size() == 1 @@ -230,13 +230,13 @@ class CassandraExecutionDAOSpec extends CassandraSpec { given: 'we create a workflow' String workflowId = IDGenerator.generate() WorkflowDef workflowDef = new WorkflowDef(name: 'def1', version: 1) - Workflow workflow = new Workflow(workflowDefinition: workflowDef, workflowId: workflowId, input: new HashMap(), status: Workflow.WorkflowStatus.RUNNING, createTime: System.currentTimeMillis()) + WorkflowModel workflow = new WorkflowModel(workflowDefinition: workflowDef, workflowId: workflowId, input: new HashMap(), status: WorkflowModel.Status.RUNNING, createTime: System.currentTimeMillis()) executionDAO.createWorkflow(workflow) and: 'create tasks for this workflow' - Task task1 = new Task(workflowInstanceId: workflowId, taskType: 'task1', referenceTaskName: 'task1', status: Task.Status.SCHEDULED, taskId: IDGenerator.generate()) - Task task2 = new Task(workflowInstanceId: workflowId, taskType: 'task2', referenceTaskName: 'task2', status: Task.Status.SCHEDULED, taskId: IDGenerator.generate()) - Task task3 = new Task(workflowInstanceId: workflowId, taskType: 'task3', referenceTaskName: 'task3', status: Task.Status.SCHEDULED, taskId: IDGenerator.generate()) + TaskModel task1 = new TaskModel(workflowInstanceId: workflowId, taskType: 'task1', referenceTaskName: 'task1', status: TaskModel.Status.SCHEDULED, taskId: IDGenerator.generate()) + TaskModel task2 = new TaskModel(workflowInstanceId: workflowId, taskType: 'task2', referenceTaskName: 'task2', status: TaskModel.Status.SCHEDULED, taskId: IDGenerator.generate()) + TaskModel task3 = new TaskModel(workflowInstanceId: workflowId, taskType: 'task3', referenceTaskName: 'task3', status: TaskModel.Status.SCHEDULED, taskId: IDGenerator.generate()) and: 'add the tasks to the datastore' executionDAO.createTasks([task1, task2, task3]) @@ -284,23 +284,23 @@ class CassandraExecutionDAOSpec extends CassandraSpec { WorkflowTask workflowTask = new WorkflowTask(taskDefinition: taskDef) workflowTask.setTaskDefinition(taskDef) - Task task = new Task() + TaskModel task = new TaskModel() task.taskDefName = taskDefName task.taskId = taskId task.workflowInstanceId = IDGenerator.generate() task.setWorkflowTask(workflowTask) task.setTaskType("test_task") task.setWorkflowType("test_workflow") - task.setStatus(Task.Status.SCHEDULED) + task.setStatus(TaskModel.Status.SCHEDULED) - Task newTask = new Task() + TaskModel newTask = new TaskModel() newTask.setTaskDefName(taskDefName) newTask.setTaskId(IDGenerator.generate()) newTask.setWorkflowInstanceId(IDGenerator.generate()) newTask.setWorkflowTask(workflowTask) newTask.setTaskType("test_task") newTask.setWorkflowType("test_workflow") - newTask.setStatus(Task.Status.SCHEDULED) + newTask.setStatus(TaskModel.Status.SCHEDULED) when: // no tasks are IN_PROGRESS executionDAO.addTaskToLimit(task) @@ -309,7 +309,7 @@ class CassandraExecutionDAOSpec extends CassandraSpec { !executionDAO.exceedsLimit(task) when: // set a task to IN_PROGRESS - task.setStatus(Task.Status.IN_PROGRESS) + task.setStatus(TaskModel.Status.IN_PROGRESS) executionDAO.addTaskToLimit(task) then: // same task is checked @@ -319,14 +319,14 @@ class CassandraExecutionDAOSpec extends CassandraSpec { executionDAO.exceedsLimit(newTask) when: // set IN_PROGRESS task to COMPLETED - task.setStatus(Task.Status.COMPLETED) + task.setStatus(TaskModel.Status.COMPLETED) executionDAO.removeTaskFromLimit(task) then: // check new task again !executionDAO.exceedsLimit(newTask) when: // set new task to IN_PROGRESS - newTask.setStatus(Task.Status.IN_PROGRESS) + newTask.setStatus(TaskModel.Status.IN_PROGRESS) executionDAO.addTaskToLimit(newTask) then: // check new task again diff --git a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraMetadataDAOSpec.groovy b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraMetadataDAOSpec.groovy index 27049c2c21..5c06efe550 100644 --- a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraMetadataDAOSpec.groovy +++ b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraMetadataDAOSpec.groovy @@ -1,20 +1,20 @@ /* - * Copyright 2021 Netflix, Inc. - *

- * 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. + * Copyright 2022 Netflix, Inc. + *

+ * 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.cassandra.dao import com.netflix.conductor.common.metadata.tasks.TaskDef import com.netflix.conductor.common.metadata.workflow.WorkflowDef + import spock.lang.Subject class CassandraMetadataDAOSpec extends CassandraSpec { diff --git a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraSpec.groovy b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraSpec.groovy index d9531f2b36..a5393210bb 100644 --- a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraSpec.groovy +++ b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/dao/CassandraSpec.groovy @@ -1,34 +1,35 @@ /* - * Copyright 2021 Netflix, Inc. - *

- * 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. + * Copyright 2022 Netflix, Inc. + *

+ * 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.cassandra.dao -import com.datastax.driver.core.ConsistencyLevel -import com.datastax.driver.core.Session -import com.fasterxml.jackson.databind.ObjectMapper -import com.netflix.conductor.cassandra.config.CassandraProperties -import com.netflix.conductor.cassandra.util.Statements -import com.netflix.conductor.common.config.TestObjectMapperConfiguration -import groovy.transform.PackageScope +import java.time.Duration + import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.ContextConfiguration import org.testcontainers.containers.CassandraContainer import org.testcontainers.spock.Testcontainers + +import com.netflix.conductor.cassandra.config.CassandraProperties +import com.netflix.conductor.cassandra.util.Statements +import com.netflix.conductor.common.config.TestObjectMapperConfiguration + +import com.datastax.driver.core.ConsistencyLevel +import com.datastax.driver.core.Session +import com.fasterxml.jackson.databind.ObjectMapper +import groovy.transform.PackageScope import spock.lang.Shared import spock.lang.Specification -import java.time.Duration - @ContextConfiguration(classes = [TestObjectMapperConfiguration.class]) @Testcontainers @PackageScope diff --git a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/util/StatementsSpec.groovy b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/util/StatementsSpec.groovy index f674688b9e..f826a36208 100644 --- a/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/util/StatementsSpec.groovy +++ b/cassandra-persistence/src/test/groovy/com/netflix/conductor/cassandra/util/StatementsSpec.groovy @@ -1,16 +1,15 @@ /* - * Copyright 2021 Netflix, Inc. - *

- * 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. + * Copyright 2022 Netflix, Inc. + *

+ * 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.cassandra.util import spock.lang.Specification diff --git a/client/src/main/java/com/netflix/conductor/client/http/TaskClient.java b/client/src/main/java/com/netflix/conductor/client/http/TaskClient.java index 3e7ca3699b..88700d2b83 100644 --- a/client/src/main/java/com/netflix/conductor/client/http/TaskClient.java +++ b/client/src/main/java/com/netflix/conductor/client/http/TaskClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -248,12 +248,12 @@ public void evaluateAndUploadLargePayload(TaskResult taskResult, String taskType MetricsContainer.recordTaskResultPayloadSize(taskType, taskResultSize); long payloadSizeThreshold = - conductorClientConfiguration.getTaskOutputPayloadThresholdKB() * 1024; + conductorClientConfiguration.getTaskOutputPayloadThresholdKB() * 1024L; if (taskResultSize > payloadSizeThreshold) { if (!conductorClientConfiguration.isExternalPayloadStorageEnabled() || taskResultSize > conductorClientConfiguration.getTaskOutputMaxPayloadThresholdKB() - * 1024) { + * 1024L) { taskResult.setReasonForIncompletion( String.format( "The TaskResult payload size: %d is greater than the permissible %d MB", diff --git a/common/src/main/java/com/netflix/conductor/common/metadata/tasks/Task.java b/common/src/main/java/com/netflix/conductor/common/metadata/tasks/Task.java index d2957f62b6..82a6a1af21 100644 --- a/common/src/main/java/com/netflix/conductor/common/metadata/tasks/Task.java +++ b/common/src/main/java/com/netflix/conductor/common/metadata/tasks/Task.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/common/src/main/java/com/netflix/conductor/common/metadata/tasks/TaskResult.java b/common/src/main/java/com/netflix/conductor/common/metadata/tasks/TaskResult.java index cf4e5c246c..d449176203 100644 --- a/common/src/main/java/com/netflix/conductor/common/metadata/tasks/TaskResult.java +++ b/common/src/main/java/com/netflix/conductor/common/metadata/tasks/TaskResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/common/src/main/java/com/netflix/conductor/common/run/Workflow.java b/common/src/main/java/com/netflix/conductor/common/run/Workflow.java index dc9d410820..946ab90ed4 100644 --- a/common/src/main/java/com/netflix/conductor/common/run/Workflow.java +++ b/common/src/main/java/com/netflix/conductor/common/run/Workflow.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/dao/index/NoopIndexDAO.java b/contribs/src/main/java/com/netflix/conductor/contribs/dao/index/NoopIndexDAO.java index dbbcfbd670..4b5f22c6b2 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/dao/index/NoopIndexDAO.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/dao/index/NoopIndexDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -17,10 +17,10 @@ import java.util.concurrent.CompletableFuture; import com.netflix.conductor.common.metadata.events.EventExecution; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.run.SearchResult; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.common.run.TaskSummary; +import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.dao.IndexDAO; @@ -34,18 +34,18 @@ public class NoopIndexDAO implements IndexDAO { public void setup() {} @Override - public void indexWorkflow(Workflow workflow) {} + public void indexWorkflow(WorkflowSummary workflowSummary) {} @Override - public CompletableFuture asyncIndexWorkflow(Workflow workflow) { + public CompletableFuture asyncIndexWorkflow(WorkflowSummary workflowSummary) { return CompletableFuture.completedFuture(null); } @Override - public void indexTask(Task task) {} + public void indexTask(TaskSummary taskSummary) {} @Override - public CompletableFuture asyncIndexTask(Task task) { + public CompletableFuture asyncIndexTask(TaskSummary taskSummary) { return CompletableFuture.completedFuture(null); } diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/dao/index/NoopIndexDAOConfiguration.java b/contribs/src/main/java/com/netflix/conductor/contribs/dao/index/NoopIndexDAOConfiguration.java index 0835d50d0d..b9feec8de2 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/dao/index/NoopIndexDAOConfiguration.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/dao/index/NoopIndexDAOConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWithTTLWorkflowStatusListener.java b/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWithTTLWorkflowStatusListener.java index e80bfcd2da..69b50d6a38 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWithTTLWorkflowStatusListener.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWithTTLWorkflowStatusListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -20,10 +20,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; import com.netflix.conductor.core.listener.WorkflowStatusListener; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.WorkflowModel; public class ArchivingWithTTLWorkflowStatusListener implements WorkflowStatusListener { @@ -75,7 +75,7 @@ public void shutdownExecutorService() { } @Override - public void onWorkflowCompleted(Workflow workflow) { + public void onWorkflowCompleted(WorkflowModel workflow) { LOGGER.info("Archiving workflow {} on completion ", workflow.getWorkflowId()); if (delayArchiveSeconds > 0) { scheduledThreadPoolExecutor.schedule( @@ -90,7 +90,7 @@ public void onWorkflowCompleted(Workflow workflow) { } @Override - public void onWorkflowTerminated(Workflow workflow) { + public void onWorkflowTerminated(WorkflowModel workflow) { LOGGER.info("Archiving workflow {} on termination", workflow.getWorkflowId()); if (delayArchiveSeconds > 0) { scheduledThreadPoolExecutor.schedule( @@ -108,10 +108,10 @@ private class DelayArchiveWorkflow implements Runnable { private final String workflowId; private final String workflowName; - private final Workflow.WorkflowStatus status; + private final WorkflowModel.Status status; private final ExecutionDAOFacade executionDAOFacade; - DelayArchiveWorkflow(Workflow workflow, ExecutionDAOFacade executionDAOFacade) { + DelayArchiveWorkflow(WorkflowModel workflow, ExecutionDAOFacade executionDAOFacade) { this.workflowId = workflow.getWorkflowId(); this.workflowName = workflow.getWorkflowName(); this.status = workflow.getStatus(); diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowListenerConfiguration.java b/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowListenerConfiguration.java index 482e63d739..c98c0c173b 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowListenerConfiguration.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowListenerConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -17,8 +17,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; import com.netflix.conductor.core.listener.WorkflowStatusListener; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; @Configuration @EnableConfigurationProperties(ArchivingWorkflowListenerProperties.class) diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowListenerProperties.java b/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowListenerProperties.java index 90076089ff..dfd57d3017 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowListenerProperties.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowListenerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowStatusListener.java b/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowStatusListener.java index f84c99f705..f1fe98cca8 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowStatusListener.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/listener/archive/ArchivingWorkflowStatusListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -15,10 +15,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; import com.netflix.conductor.core.listener.WorkflowStatusListener; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.WorkflowModel; /** * Provides default implementation of workflow archiving immediately after workflow is completed or @@ -37,14 +37,14 @@ public ArchivingWorkflowStatusListener(ExecutionDAOFacade executionDAOFacade) { } @Override - public void onWorkflowCompleted(Workflow workflow) { + public void onWorkflowCompleted(WorkflowModel workflow) { LOGGER.info("Archiving workflow {} on completion ", workflow.getWorkflowId()); this.executionDAOFacade.removeWorkflow(workflow.getWorkflowId(), true); Monitors.recordWorkflowArchived(workflow.getWorkflowName(), workflow.getStatus()); } @Override - public void onWorkflowTerminated(Workflow workflow) { + public void onWorkflowTerminated(WorkflowModel workflow) { LOGGER.info("Archiving workflow {} on termination", workflow.getWorkflowId()); this.executionDAOFacade.removeWorkflow(workflow.getWorkflowId(), true); Monitors.recordWorkflowArchived(workflow.getWorkflowName(), workflow.getStatus()); diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisher.java b/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisher.java index 45060f322d..c11ef06103 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisher.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisher.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -17,11 +17,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.run.WorkflowSummary; +import com.netflix.conductor.core.dal.ModelMapper; import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.core.listener.WorkflowStatusListener; import com.netflix.conductor.dao.QueueDAO; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -35,6 +36,7 @@ public class ConductorQueueStatusPublisher implements WorkflowStatusListener { private static final Logger LOGGER = LoggerFactory.getLogger(ConductorQueueStatusPublisher.class); private final QueueDAO queueDAO; + private final ModelMapper modelMapper; private final ObjectMapper objectMapper; private final String successStatusQueue; @@ -43,9 +45,11 @@ public class ConductorQueueStatusPublisher implements WorkflowStatusListener { public ConductorQueueStatusPublisher( QueueDAO queueDAO, + ModelMapper modelMapper, ObjectMapper objectMapper, ConductorQueueStatusPublisherProperties properties) { this.queueDAO = queueDAO; + this.modelMapper = modelMapper; this.objectMapper = objectMapper; this.successStatusQueue = properties.getSuccessQueue(); this.failureStatusQueue = properties.getFailureQueue(); @@ -53,26 +57,26 @@ public ConductorQueueStatusPublisher( } @Override - public void onWorkflowCompleted(Workflow workflow) { + public void onWorkflowCompleted(WorkflowModel workflow) { LOGGER.info("Publishing callback of workflow {} on completion ", workflow.getWorkflowId()); queueDAO.push(successStatusQueue, Collections.singletonList(workflowToMessage(workflow))); } @Override - public void onWorkflowTerminated(Workflow workflow) { + public void onWorkflowTerminated(WorkflowModel workflow) { LOGGER.info("Publishing callback of workflow {} on termination", workflow.getWorkflowId()); queueDAO.push(failureStatusQueue, Collections.singletonList(workflowToMessage(workflow))); } @Override - public void onWorkflowFinalized(Workflow workflow) { + public void onWorkflowFinalized(WorkflowModel workflow) { LOGGER.info("Publishing callback of workflow {} on finalization", workflow.getWorkflowId()); queueDAO.push(finalizeStatusQueue, Collections.singletonList(workflowToMessage(workflow))); } - private Message workflowToMessage(Workflow workflow) { + private Message workflowToMessage(WorkflowModel workflow) { String jsonWfSummary; - WorkflowSummary summary = new WorkflowSummary(workflow); + WorkflowSummary summary = new WorkflowSummary(modelMapper.getWorkflow(workflow)); try { jsonWfSummary = objectMapper.writeValueAsString(summary); } catch (JsonProcessingException e) { diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisherConfiguration.java b/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisherConfiguration.java index 13d8d0a934..12dda6c444 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisherConfiguration.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisherConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -17,6 +17,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import com.netflix.conductor.core.dal.ModelMapper; import com.netflix.conductor.core.listener.WorkflowStatusListener; import com.netflix.conductor.dao.QueueDAO; @@ -32,8 +33,9 @@ public class ConductorQueueStatusPublisherConfiguration { @Bean public WorkflowStatusListener getWorkflowStatusListener( QueueDAO queueDAO, + ModelMapper modelMapper, ConductorQueueStatusPublisherProperties properties, ObjectMapper objectMapper) { - return new ConductorQueueStatusPublisher(queueDAO, objectMapper, properties); + return new ConductorQueueStatusPublisher(queueDAO, modelMapper, objectMapper, properties); } } diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisherProperties.java b/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisherProperties.java index e04d2fc2f0..ea9a53f743 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisherProperties.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/listener/conductorqueue/ConductorQueueStatusPublisherProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/queue/sqs/SQSObservableQueue.java b/contribs/src/main/java/com/netflix/conductor/contribs/queue/sqs/SQSObservableQueue.java index 8ff19a0617..e4603791de 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/queue/sqs/SQSObservableQueue.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/queue/sqs/SQSObservableQueue.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/queue/sqs/config/SQSEventQueueConfiguration.java b/contribs/src/main/java/com/netflix/conductor/contribs/queue/sqs/config/SQSEventQueueConfiguration.java index 6de5573159..412bbb8cb9 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/queue/sqs/config/SQSEventQueueConfiguration.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/queue/sqs/config/SQSEventQueueConfiguration.java @@ -32,7 +32,6 @@ import com.amazonaws.services.sqs.AmazonSQSClient; import rx.Scheduler; -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Configuration @EnableConfigurationProperties(SQSEventQueueProperties.class) @ConditionalOnProperty(name = "conductor.event-queues.sqs.enabled", havingValue = "true") diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/storage/S3PayloadStorage.java b/contribs/src/main/java/com/netflix/conductor/contribs/storage/S3PayloadStorage.java index eb9d7dd97d..e79bb6ebca 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/storage/S3PayloadStorage.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/storage/S3PayloadStorage.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -38,7 +38,9 @@ /** * An implementation of {@link ExternalPayloadStorage} using AWS S3 for storing large JSON payload - * data. The S3 client assumes that access to S3 is configured on the instance. + * data. + * + *

NOTE: The S3 client assumes that access to S3 is configured on the instance. * * @see DefaultAWSCredentialsProviderChain diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/storage/config/S3Configuration.java b/contribs/src/main/java/com/netflix/conductor/contribs/storage/config/S3Configuration.java index bb9ca31132..a52ec750cb 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/storage/config/S3Configuration.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/storage/config/S3Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/DefaultRestTemplateProvider.java b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/DefaultRestTemplateProvider.java index 35a9a15e39..670f260638 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/DefaultRestTemplateProvider.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/DefaultRestTemplateProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/HttpTask.java b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/HttpTask.java index 2fce5ac87f..f0f42eaf4d 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/HttpTask.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/HttpTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -21,22 +21,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; import com.netflix.conductor.core.utils.Utils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; @@ -79,12 +74,12 @@ public HttpTask( } @Override - public void start(Workflow workflow, Task task, WorkflowExecutor executor) { + public void start(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { Object request = task.getInputData().get(requestParameter); task.setWorkerId(Utils.getServerId()); if (request == null) { task.setReasonForIncompletion(MISSING_REQUEST); - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); return; } @@ -93,14 +88,14 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { String reason = "Missing HTTP URI. See documentation for HttpTask for required input parameters"; task.setReasonForIncompletion(reason); - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); return; } if (input.getMethod() == null) { String reason = "No HTTP method specified"; task.setReasonForIncompletion(reason); - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); return; } @@ -113,9 +108,9 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { task.getTaskId()); if (response.statusCode > 199 && response.statusCode < 300) { if (isAsyncComplete(task)) { - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); } else { - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); } } else { if (response.body != null) { @@ -123,7 +118,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { } else { task.setReasonForIncompletion("No response from the remote service"); } - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); } //noinspection ConstantConditions if (response != null) { @@ -139,7 +134,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { input.getVipAddress(), task.getWorkflowInstanceId(), e); - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setReasonForIncompletion( "Failed to invoke " + getTaskType() + " task due to: " + e); task.getOutputData().put("response", e.toString()); @@ -206,13 +201,13 @@ private Object extractBody(String responseBody) { } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor executor) { + public boolean execute(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { return false; } @Override - public void cancel(Workflow workflow, Task task, WorkflowExecutor executor) { - task.setStatus(Status.CANCELED); + public void cancel(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { + task.setStatus(TaskModel.Status.CANCELED); } @Override diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/RestTemplateProvider.java b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/RestTemplateProvider.java index 665be8caab..95c648b079 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/RestTemplateProvider.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/http/RestTemplateProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/json/JsonJqTransform.java b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/json/JsonJqTransform.java index 9ec9f2f43d..26520edaf4 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/json/JsonJqTransform.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/json/JsonJqTransform.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -22,10 +22,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -58,7 +58,7 @@ public JsonJqTransform(ObjectMapper objectMapper) { } @Override - public void start(Workflow workflow, Task task, WorkflowExecutor executor) { + public void start(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { final Map taskInput = task.getInputData(); final Map taskOutput = task.getOutputData(); @@ -67,7 +67,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { if (queryExpression == null) { task.setReasonForIncompletion( "Missing '" + QUERY_EXPRESSION_PARAMETER + "' in input parameters"); - task.setStatus(Task.Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); return; } @@ -79,7 +79,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { final List result = query.apply(childScope, input); - task.setStatus(Task.Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); if (result == null) { taskOutput.put(OUTPUT_RESULT, null); taskOutput.put(OUTPUT_RESULT_LIST, null); @@ -96,7 +96,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { task.getTaskId(), workflow.getWorkflowId(), e); - task.setStatus(Task.Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); final String message = extractFirstValidMessage(e); task.setReasonForIncompletion(message); taskOutput.put(OUTPUT_ERROR, message); diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/kafka/KafkaProducerManager.java b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/kafka/KafkaProducerManager.java index db442a8452..4095af478e 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/kafka/KafkaProducerManager.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/kafka/KafkaProducerManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/kafka/KafkaPublishTask.java b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/kafka/KafkaPublishTask.java index 21f779ca6a..8ec91a0396 100644 --- a/contribs/src/main/java/com/netflix/conductor/contribs/tasks/kafka/KafkaPublishTask.java +++ b/contribs/src/main/java/com/netflix/conductor/contribs/tasks/kafka/KafkaPublishTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -34,11 +34,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; import com.netflix.conductor.core.utils.Utils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.annotations.VisibleForTesting; @@ -76,7 +76,7 @@ public KafkaPublishTask(KafkaProducerManager clientManager, ObjectMapper objectM } @Override - public void start(Workflow workflow, Task task, WorkflowExecutor executor) { + public void start(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { long taskStartMillis = Instant.now().toEpochMilli(); task.setWorkerId(Utils.getServerId()); @@ -109,9 +109,9 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { try { recordMetaDataFuture.get(); if (isAsyncComplete(task)) { - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); } else { - task.setStatus(Task.Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); } long timeTakenToCompleteTask = Instant.now().toEpochMilli() - taskStartMillis; LOGGER.debug("Published message {}, Time taken {}", input, timeTakenToCompleteTask); @@ -133,9 +133,9 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { } } - private void markTaskAsFailed(Task task, String reasonForIncompletion) { + private void markTaskAsFailed(TaskModel task, String reasonForIncompletion) { task.setReasonForIncompletion(reasonForIncompletion); - task.setStatus(Task.Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); } /** @@ -195,13 +195,13 @@ Object getKey(Input input) { } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor executor) { + public boolean execute(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { return false; } @Override - public void cancel(Workflow workflow, Task task, WorkflowExecutor executor) { - task.setStatus(Task.Status.CANCELED); + public void cancel(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { + task.setStatus(TaskModel.Status.CANCELED); } @Override diff --git a/contribs/src/test/java/com/netflix/conductor/contribs/listener/ArchivingWorkflowStatusListenerTest.java b/contribs/src/test/java/com/netflix/conductor/contribs/listener/ArchivingWorkflowStatusListenerTest.java index 3d58db5be5..9a89e86deb 100644 --- a/contribs/src/test/java/com/netflix/conductor/contribs/listener/ArchivingWorkflowStatusListenerTest.java +++ b/contribs/src/test/java/com/netflix/conductor/contribs/listener/ArchivingWorkflowStatusListenerTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -19,24 +19,22 @@ import org.mockito.Mockito; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.contribs.listener.archive.ArchivingWorkflowStatusListener; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; +import com.netflix.conductor.model.WorkflowModel; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.*; /** @author pavel.halabala */ public class ArchivingWorkflowStatusListenerTest { - Workflow workflow; + WorkflowModel workflow; ExecutionDAOFacade executionDAOFacade; ArchivingWorkflowStatusListener listener; @Before public void before() { - workflow = new Workflow(); + workflow = new WorkflowModel(); WorkflowDef def = new WorkflowDef(); def.setName("name1"); def.setVersion(1); diff --git a/contribs/src/test/java/com/netflix/conductor/contribs/queue/sqs/DefaultEventQueueProcessorTest.java b/contribs/src/test/java/com/netflix/conductor/contribs/queue/sqs/DefaultEventQueueProcessorTest.java index 1b6c619db7..f661e62b33 100644 --- a/contribs/src/test/java/com/netflix/conductor/contribs/queue/sqs/DefaultEventQueueProcessorTest.java +++ b/contribs/src/test/java/com/netflix/conductor/contribs/queue/sqs/DefaultEventQueueProcessorTest.java @@ -30,6 +30,7 @@ import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.Task.Status; +import com.netflix.conductor.common.metadata.tasks.TaskResult; import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.events.queue.DefaultEventQueueProcessor; import com.netflix.conductor.core.events.queue.Message; @@ -63,7 +64,7 @@ public class DefaultEventQueueProcessorTest { @Autowired private ObjectMapper objectMapper; private static final List messages = new LinkedList<>(); - private static final List updatedTasks = new LinkedList<>(); + private static final List updatedTasks = new LinkedList<>(); @Before public void init() { @@ -129,11 +130,11 @@ public static void setup() { doAnswer( (Answer) invocation -> { - updatedTasks.add(invocation.getArgument(0, Task.class)); + updatedTasks.add(invocation.getArgument(0, TaskResult.class)); return null; }) .when(executionService) - .updateTask(any(Task.class)); + .updateTask(any(TaskResult.class)); } @Test diff --git a/contribs/src/test/java/com/netflix/conductor/contribs/tasks/http/DefaultRestTemplateProviderTest.java b/contribs/src/test/java/com/netflix/conductor/contribs/tasks/http/DefaultRestTemplateProviderTest.java index 480e97588b..31e5ef2d45 100644 --- a/contribs/src/test/java/com/netflix/conductor/contribs/tasks/http/DefaultRestTemplateProviderTest.java +++ b/contribs/src/test/java/com/netflix/conductor/contribs/tasks/http/DefaultRestTemplateProviderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/contribs/src/test/java/com/netflix/conductor/contribs/tasks/http/HttpTaskTest.java b/contribs/src/test/java/com/netflix/conductor/contribs/tasks/http/HttpTaskTest.java index f87eb6022b..065b492353 100644 --- a/contribs/src/test/java/com/netflix/conductor/contribs/tasks/http/HttpTaskTest.java +++ b/contribs/src/test/java/com/netflix/conductor/contribs/tasks/http/HttpTaskTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -12,343 +12,356 @@ */ package com.netflix.conductor.contribs.tasks.http; -import org.junit.Ignore; +import java.time.Duration; +import java.time.Instant; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.junit.*; +import org.mockserver.client.MockServerClient; +import org.mockserver.model.MediaType; +import org.testcontainers.containers.MockServerContainer; +import org.testcontainers.utility.DockerImageName; + +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.core.execution.DeciderService; +import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.core.execution.tasks.SystemTaskRegistry; +import com.netflix.conductor.core.utils.ExternalPayloadStorageUtils; +import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.mockserver.model.HttpRequest.request; +import static org.mockserver.model.HttpResponse.response; @SuppressWarnings("unchecked") -@Ignore // Test causes "OutOfMemoryError" error during build +// @Ignore // Test causes "OutOfMemoryError" error during build public class HttpTaskTest { - // private static final String ERROR_RESPONSE = "Something went wrong!"; - // private static final String TEXT_RESPONSE = "Text Response"; - // private static final double NUM_RESPONSE = 42.42d; - // - // private HttpTask httpTask; - // private WorkflowExecutor workflowExecutor; - // private final Workflow workflow = new Workflow(); - // - // private static final ObjectMapper objectMapper = new ObjectMapper(); - // private static String JSON_RESPONSE; - // - // @ClassRule - // public static MockServerContainer mockServer = new MockServerContainer( - // DockerImageName.parse("mockserver/mockserver")); - // - // @BeforeClass - // public static void init() throws Exception { - // Map map = new HashMap<>(); - // map.put("key", "value1"); - // map.put("num", 42); - // map.put("SomeKey", null); - // JSON_RESPONSE = objectMapper.writeValueAsString(map); - // - // final TypeReference> mapOfObj = new TypeReference>() { - // }; - // MockServerClient client = new MockServerClient(mockServer.getHost(), - // mockServer.getServerPort()); - // client.when( - // request() - // .withPath("/post") - // .withMethod("POST")) - // .respond(request -> { - // Map reqBody = - // objectMapper.readValue(request.getBody().toString(), mapOfObj); - // Set keys = reqBody.keySet(); - // Map respBody = new HashMap<>(); - // keys.forEach(k -> respBody.put(k, k)); - // return response() - // .withContentType(MediaType.APPLICATION_JSON) - // .withBody(objectMapper.writeValueAsString(respBody)); - // }); - // client.when( - // request() - // .withPath("/post2") - // .withMethod("POST")) - // .respond(response() - // .withStatusCode(204)); - // client.when( - // request() - // .withPath("/failure") - // .withMethod("GET")) - // .respond(response() - // .withStatusCode(500) - // .withContentType(MediaType.TEXT_PLAIN) - // .withBody(ERROR_RESPONSE)); - // client.when( - // request() - // .withPath("/text") - // .withMethod("GET")) - // .respond(response() - // .withBody(TEXT_RESPONSE)); - // client.when( - // request() - // .withPath("/numeric") - // .withMethod("GET")) - // .respond(response() - // .withBody(String.valueOf(NUM_RESPONSE))); - // client.when( - // request() - // .withPath("/json") - // .withMethod("GET")) - // .respond(response() - // .withContentType(MediaType.APPLICATION_JSON) - // .withBody(JSON_RESPONSE)); - // } - // - // @Before - // public void setup() { - // workflowExecutor = mock(WorkflowExecutor.class); - // DefaultRestTemplateProvider defaultRestTemplateProvider = - // new DefaultRestTemplateProvider(Duration.ofMillis(150), Duration.ofMillis(100)); - // httpTask = new HttpTask(defaultRestTemplateProvider, objectMapper); - // } - // - // @Test - // public void testPost() { - // - // Task task = new Task(); - // Input input = new Input(); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/post"); - // Map body = new HashMap<>(); - // body.put("input_key1", "value1"); - // body.put("input_key2", 45.3d); - // body.put("someKey", null); - // input.setBody(body); - // input.setMethod("POST"); - // input.setReadTimeOut(1000); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // - // httpTask.start(workflow, task, workflowExecutor); - // assertEquals(task.getReasonForIncompletion(), Status.COMPLETED, task.getStatus()); - // Map hr = (Map) task.getOutputData().get("response"); - // Object response = hr.get("body"); - // assertEquals(Status.COMPLETED, task.getStatus()); - // assertTrue("response is: " + response, response instanceof Map); - // Map map = (Map) response; - // Set inputKeys = body.keySet(); - // Set responseKeys = map.keySet(); - // inputKeys.containsAll(responseKeys); - // responseKeys.containsAll(inputKeys); - // } - // - // @Test - // public void testPostNoContent() { - // - // Task task = new Task(); - // Input input = new Input(); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/post2"); - // Map body = new HashMap<>(); - // body.put("input_key1", "value1"); - // body.put("input_key2", 45.3d); - // input.setBody(body); - // input.setMethod("POST"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // - // httpTask.start(workflow, task, workflowExecutor); - // assertEquals(task.getReasonForIncompletion(), Status.COMPLETED, task.getStatus()); - // Map hr = (Map) task.getOutputData().get("response"); - // Object response = hr.get("body"); - // assertEquals(Status.COMPLETED, task.getStatus()); - // assertNull("response is: " + response, response); - // } - // - // @Test - // public void testFailure() { - // - // Task task = new Task(); - // Input input = new Input(); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/failure"); - // input.setMethod("GET"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // - // httpTask.start(workflow, task, workflowExecutor); - // assertEquals("Task output: " + task.getOutputData(), Status.FAILED, task.getStatus()); - // assertTrue(task.getReasonForIncompletion().contains(ERROR_RESPONSE)); - // - // task.setStatus(Status.SCHEDULED); - // task.getInputData().remove(HttpTask.REQUEST_PARAMETER_NAME); - // httpTask.start(workflow, task, workflowExecutor); - // assertEquals(Status.FAILED, task.getStatus()); - // assertEquals(HttpTask.MISSING_REQUEST, task.getReasonForIncompletion()); - // } - // - // @Test - // public void testPostAsyncComplete() { - // - // Task task = new Task(); - // Input input = new Input(); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/post"); - // Map body = new HashMap<>(); - // body.put("input_key1", "value1"); - // body.put("input_key2", 45.3d); - // input.setBody(body); - // input.setMethod("POST"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // task.getInputData().put("asyncComplete", true); - // - // httpTask.start(workflow, task, workflowExecutor); - // assertEquals(task.getReasonForIncompletion(), Status.IN_PROGRESS, task.getStatus()); - // Map hr = (Map) task.getOutputData().get("response"); - // Object response = hr.get("body"); - // assertEquals(Status.IN_PROGRESS, task.getStatus()); - // assertTrue("response is: " + response, response instanceof Map); - // Map map = (Map) response; - // Set inputKeys = body.keySet(); - // Set responseKeys = map.keySet(); - // inputKeys.containsAll(responseKeys); - // responseKeys.containsAll(inputKeys); - // } - // - // @Test - // public void testTextGET() { - // Task task = new Task(); - // Input input = new Input(); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/text"); - // input.setMethod("GET"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // - // httpTask.start(workflow, task, workflowExecutor); - // Map hr = (Map) task.getOutputData().get("response"); - // Object response = hr.get("body"); - // assertEquals(Status.COMPLETED, task.getStatus()); - // assertEquals(TEXT_RESPONSE, response); - // } - // - // @Test - // public void testNumberGET() { - // Task task = new Task(); - // Input input = new Input(); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/numeric"); - // input.setMethod("GET"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // - // httpTask.start(workflow, task, workflowExecutor); - // Map hr = (Map) task.getOutputData().get("response"); - // Object response = hr.get("body"); - // assertEquals(Status.COMPLETED, task.getStatus()); - // assertEquals(NUM_RESPONSE, response); - // assertTrue(response instanceof Number); - // } - // - // @Test - // public void testJsonGET() throws JsonProcessingException { - // - // Task task = new Task(); - // Input input = new Input(); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/json"); - // input.setMethod("GET"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // - // httpTask.start(workflow, task, workflowExecutor); - // Map hr = (Map) task.getOutputData().get("response"); - // Object response = hr.get("body"); - // assertEquals(Status.COMPLETED, task.getStatus()); - // assertTrue(response instanceof Map); - // Map map = (Map) response; - // assertEquals(JSON_RESPONSE, objectMapper.writeValueAsString(map)); - // } - // - // @Test - // public void testExecute() { - // - // Task task = new Task(); - // Input input = new Input(); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/json"); - // input.setMethod("GET"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // task.setStatus(Status.SCHEDULED); - // task.setScheduledTime(0); - // - // boolean executed = httpTask.execute(workflow, task, workflowExecutor); - // assertFalse(executed); - // } - // - // @Test - // public void testHTTPGetConnectionTimeOut() { - // Task task = new Task(); - // Input input = new Input(); - // Instant start = Instant.now(); - // input.setConnectionTimeOut(110); - // input.setMethod("GET"); - // input.setUri("http://10.255.14.15"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // task.setStatus(Status.SCHEDULED); - // task.setScheduledTime(0); - // httpTask.start(workflow, task, workflowExecutor); - // Instant end = Instant.now(); - // long diff = end.toEpochMilli() - start.toEpochMilli(); - // assertEquals(task.getStatus(), Status.FAILED); - // assertTrue(diff >= 110L); - // } - // - // @Test - // public void testHTTPGETReadTimeOut() { - // Task task = new Task(); - // Input input = new Input(); - // input.setReadTimeOut(-1); - // input.setMethod("GET"); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/json"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // task.setStatus(Status.SCHEDULED); - // task.setScheduledTime(0); - // - // httpTask.start(workflow, task, workflowExecutor); - // assertEquals(task.getStatus(), Status.FAILED); - // } - // - // @Test - // public void testOptional() { - // Task task = new Task(); - // Input input = new Input(); - // input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + - // "/failure"); - // input.setMethod("GET"); - // task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); - // - // httpTask.start(workflow, task, workflowExecutor); - // assertEquals("Task output: " + task.getOutputData(), Status.FAILED, task.getStatus()); - // assertTrue(task.getReasonForIncompletion().contains(ERROR_RESPONSE)); - // assertFalse(task.getStatus().isSuccessful()); - // - // task.setStatus(Status.SCHEDULED); - // task.getInputData().remove(HttpTask.REQUEST_PARAMETER_NAME); - // task.setReferenceTaskName("t1"); - // httpTask.start(workflow, task, workflowExecutor); - // assertEquals(Status.FAILED, task.getStatus()); - // assertEquals(HttpTask.MISSING_REQUEST, task.getReasonForIncompletion()); - // assertFalse(task.getStatus().isSuccessful()); - // - // WorkflowTask workflowTask = new WorkflowTask(); - // workflowTask.setOptional(true); - // workflowTask.setName("HTTP"); - // workflowTask.setWorkflowTaskType(TaskType.USER_DEFINED); - // workflowTask.setTaskReferenceName("t1"); - // - // WorkflowDef def = new WorkflowDef(); - // def.getTasks().add(workflowTask); - // - // Workflow workflow = new Workflow(); - // workflow.setWorkflowDefinition(def); - // workflow.getTasks().add(task); - // - // MetadataDAO metadataDAO = mock(MetadataDAO.class); - // ExternalPayloadStorageUtils externalPayloadStorageUtils = - // mock(ExternalPayloadStorageUtils.class); - // ParametersUtils parametersUtils = mock(ParametersUtils.class); - // SystemTaskRegistry systemTaskRegistry = mock(SystemTaskRegistry.class); - // - // new DeciderService(parametersUtils, metadataDAO, externalPayloadStorageUtils, - // systemTaskRegistry, - // Collections.emptyMap(), - // Duration.ofMinutes(60)).decide(workflow); - // } + private static final String ERROR_RESPONSE = "Something went wrong!"; + private static final String TEXT_RESPONSE = "Text Response"; + private static final double NUM_RESPONSE = 42.42d; + + private HttpTask httpTask; + private WorkflowExecutor workflowExecutor; + private final WorkflowModel workflow = new WorkflowModel(); + + private static final ObjectMapper objectMapper = new ObjectMapper(); + private static String JSON_RESPONSE; + + @ClassRule + public static MockServerContainer mockServer = + new MockServerContainer(DockerImageName.parse("mockserver/mockserver")); + + @BeforeClass + public static void init() throws Exception { + Map map = new HashMap<>(); + map.put("key", "value1"); + map.put("num", 42); + map.put("SomeKey", null); + JSON_RESPONSE = objectMapper.writeValueAsString(map); + + final TypeReference> mapOfObj = new TypeReference<>() {}; + MockServerClient client = + new MockServerClient(mockServer.getHost(), mockServer.getServerPort()); + client.when(request().withPath("/post").withMethod("POST")) + .respond( + request -> { + Map reqBody = + objectMapper.readValue(request.getBody().toString(), mapOfObj); + Set keys = reqBody.keySet(); + Map respBody = new HashMap<>(); + keys.forEach(k -> respBody.put(k, k)); + return response() + .withContentType(MediaType.APPLICATION_JSON) + .withBody(objectMapper.writeValueAsString(respBody)); + }); + client.when(request().withPath("/post2").withMethod("POST")) + .respond(response().withStatusCode(204)); + client.when(request().withPath("/failure").withMethod("GET")) + .respond( + response() + .withStatusCode(500) + .withContentType(MediaType.TEXT_PLAIN) + .withBody(ERROR_RESPONSE)); + client.when(request().withPath("/text").withMethod("GET")) + .respond(response().withBody(TEXT_RESPONSE)); + client.when(request().withPath("/numeric").withMethod("GET")) + .respond(response().withBody(String.valueOf(NUM_RESPONSE))); + client.when(request().withPath("/json").withMethod("GET")) + .respond( + response() + .withContentType(MediaType.APPLICATION_JSON) + .withBody(JSON_RESPONSE)); + } + + @Before + public void setup() { + workflowExecutor = mock(WorkflowExecutor.class); + DefaultRestTemplateProvider defaultRestTemplateProvider = + new DefaultRestTemplateProvider(Duration.ofMillis(150), Duration.ofMillis(100)); + httpTask = new HttpTask(defaultRestTemplateProvider, objectMapper); + } + + @Test + public void testPost() { + + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/post"); + Map body = new HashMap<>(); + body.put("input_key1", "value1"); + body.put("input_key2", 45.3d); + body.put("someKey", null); + input.setBody(body); + input.setMethod("POST"); + input.setReadTimeOut(1000); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + + httpTask.start(workflow, task, workflowExecutor); + assertEquals(task.getReasonForIncompletion(), TaskModel.Status.COMPLETED, task.getStatus()); + Map hr = (Map) task.getOutputData().get("response"); + Object response = hr.get("body"); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); + assertTrue("response is: " + response, response instanceof Map); + Map map = (Map) response; + Set inputKeys = body.keySet(); + Set responseKeys = map.keySet(); + inputKeys.containsAll(responseKeys); + responseKeys.containsAll(inputKeys); + } + + @Test + public void testPostNoContent() { + + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setUri( + "http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/post2"); + Map body = new HashMap<>(); + body.put("input_key1", "value1"); + body.put("input_key2", 45.3d); + input.setBody(body); + input.setMethod("POST"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + + httpTask.start(workflow, task, workflowExecutor); + assertEquals(task.getReasonForIncompletion(), TaskModel.Status.COMPLETED, task.getStatus()); + Map hr = (Map) task.getOutputData().get("response"); + Object response = hr.get("body"); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); + assertNull("response is: " + response, response); + } + + @Test + public void testFailure() { + + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setUri( + "http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/failure"); + input.setMethod("GET"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + + httpTask.start(workflow, task, workflowExecutor); + assertEquals( + "Task output: " + task.getOutputData(), TaskModel.Status.FAILED, task.getStatus()); + assertTrue(task.getReasonForIncompletion().contains(ERROR_RESPONSE)); + + task.setStatus(TaskModel.Status.SCHEDULED); + task.getInputData().remove(HttpTask.REQUEST_PARAMETER_NAME); + httpTask.start(workflow, task, workflowExecutor); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); + assertEquals(HttpTask.MISSING_REQUEST, task.getReasonForIncompletion()); + } + + @Test + public void testPostAsyncComplete() { + + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/post"); + Map body = new HashMap<>(); + body.put("input_key1", "value1"); + body.put("input_key2", 45.3d); + input.setBody(body); + input.setMethod("POST"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + task.getInputData().put("asyncComplete", true); + + httpTask.start(workflow, task, workflowExecutor); + assertEquals( + task.getReasonForIncompletion(), TaskModel.Status.IN_PROGRESS, task.getStatus()); + Map hr = (Map) task.getOutputData().get("response"); + Object response = hr.get("body"); + assertEquals(TaskModel.Status.IN_PROGRESS, task.getStatus()); + assertTrue("response is: " + response, response instanceof Map); + Map map = (Map) response; + Set inputKeys = body.keySet(); + Set responseKeys = map.keySet(); + inputKeys.containsAll(responseKeys); + responseKeys.containsAll(inputKeys); + } + + @Test + public void testTextGET() { + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/text"); + input.setMethod("GET"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + + httpTask.start(workflow, task, workflowExecutor); + Map hr = (Map) task.getOutputData().get("response"); + Object response = hr.get("body"); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); + assertEquals(TEXT_RESPONSE, response); + } + + @Test + public void testNumberGET() { + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setUri( + "http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/numeric"); + input.setMethod("GET"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + + httpTask.start(workflow, task, workflowExecutor); + Map hr = (Map) task.getOutputData().get("response"); + Object response = hr.get("body"); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); + assertEquals(NUM_RESPONSE, response); + assertTrue(response instanceof Number); + } + + @Test + public void testJsonGET() throws JsonProcessingException { + + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/json"); + input.setMethod("GET"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + + httpTask.start(workflow, task, workflowExecutor); + Map hr = (Map) task.getOutputData().get("response"); + Object response = hr.get("body"); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); + assertTrue(response instanceof Map); + Map map = (Map) response; + assertEquals(JSON_RESPONSE, objectMapper.writeValueAsString(map)); + } + + @Test + public void testExecute() { + + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/json"); + input.setMethod("GET"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + task.setStatus(TaskModel.Status.SCHEDULED); + task.setScheduledTime(0); + + boolean executed = httpTask.execute(workflow, task, workflowExecutor); + assertFalse(executed); + } + + @Test + public void testHTTPGetConnectionTimeOut() { + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + Instant start = Instant.now(); + input.setConnectionTimeOut(110); + input.setMethod("GET"); + input.setUri("http://10.255.14.15"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + task.setStatus(TaskModel.Status.SCHEDULED); + task.setScheduledTime(0); + httpTask.start(workflow, task, workflowExecutor); + Instant end = Instant.now(); + long diff = end.toEpochMilli() - start.toEpochMilli(); + assertEquals(task.getStatus(), TaskModel.Status.FAILED); + assertTrue(diff >= 110L); + } + + @Test + public void testHTTPGETReadTimeOut() { + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setReadTimeOut(-1); + input.setMethod("GET"); + input.setUri("http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/json"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + task.setStatus(TaskModel.Status.SCHEDULED); + task.setScheduledTime(0); + + httpTask.start(workflow, task, workflowExecutor); + assertEquals(task.getStatus(), TaskModel.Status.FAILED); + } + + @Test + public void testOptional() { + TaskModel task = new TaskModel(); + HttpTask.Input input = new HttpTask.Input(); + input.setUri( + "http://" + mockServer.getHost() + ":" + mockServer.getServerPort() + "/failure"); + input.setMethod("GET"); + task.getInputData().put(HttpTask.REQUEST_PARAMETER_NAME, input); + + httpTask.start(workflow, task, workflowExecutor); + assertEquals( + "Task output: " + task.getOutputData(), TaskModel.Status.FAILED, task.getStatus()); + assertTrue(task.getReasonForIncompletion().contains(ERROR_RESPONSE)); + assertFalse(task.getStatus().isSuccessful()); + + task.setStatus(TaskModel.Status.SCHEDULED); + task.getInputData().remove(HttpTask.REQUEST_PARAMETER_NAME); + task.setReferenceTaskName("t1"); + httpTask.start(workflow, task, workflowExecutor); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); + assertEquals(HttpTask.MISSING_REQUEST, task.getReasonForIncompletion()); + assertFalse(task.getStatus().isSuccessful()); + + WorkflowTask workflowTask = new WorkflowTask(); + workflowTask.setOptional(true); + workflowTask.setName("HTTP"); + workflowTask.setWorkflowTaskType(TaskType.USER_DEFINED); + workflowTask.setTaskReferenceName("t1"); + + WorkflowDef def = new WorkflowDef(); + def.getTasks().add(workflowTask); + + WorkflowModel workflow = new WorkflowModel(); + workflow.setWorkflowDefinition(def); + workflow.getTasks().add(task); + + MetadataDAO metadataDAO = mock(MetadataDAO.class); + ExternalPayloadStorageUtils externalPayloadStorageUtils = + mock(ExternalPayloadStorageUtils.class); + ParametersUtils parametersUtils = mock(ParametersUtils.class); + SystemTaskRegistry systemTaskRegistry = mock(SystemTaskRegistry.class); + + new DeciderService( + parametersUtils, + metadataDAO, + externalPayloadStorageUtils, + systemTaskRegistry, + Collections.emptyMap(), + Duration.ofMinutes(60)) + .decide(workflow); + } } diff --git a/contribs/src/test/java/com/netflix/conductor/contribs/tasks/json/JsonJqTransformTest.java b/contribs/src/test/java/com/netflix/conductor/contribs/tasks/json/JsonJqTransformTest.java index 538aee95c7..553130ab8f 100644 --- a/contribs/src/test/java/com/netflix/conductor/contribs/tasks/json/JsonJqTransformTest.java +++ b/contribs/src/test/java/com/netflix/conductor/contribs/tasks/json/JsonJqTransformTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -19,8 +19,8 @@ import org.junit.Test; import com.netflix.conductor.common.config.ObjectMapperProvider; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -35,8 +35,8 @@ public class JsonJqTransformTest { @Test public void dataShouldBeCorrectlySelected() { final JsonJqTransform jsonJqTransform = new JsonJqTransform(objectMapper); - final Workflow workflow = new Workflow(); - final Task task = new Task(); + final WorkflowModel workflow = new WorkflowModel(); + final TaskModel task = new TaskModel(); final Map inputData = new HashMap<>(); inputData.put("queryExpression", ".inputJson.key[0]"); final Map inputJson = new HashMap<>(); @@ -55,8 +55,8 @@ public void dataShouldBeCorrectlySelected() { @Test public void simpleErrorShouldBeDisplayed() { final JsonJqTransform jsonJqTransform = new JsonJqTransform(objectMapper); - final Workflow workflow = new Workflow(); - final Task task = new Task(); + final WorkflowModel workflow = new WorkflowModel(); + final TaskModel task = new TaskModel(); final Map inputData = new HashMap<>(); inputData.put("queryExpression", "{"); task.setInputData(inputData); @@ -72,8 +72,8 @@ public void simpleErrorShouldBeDisplayed() { @Test public void nestedExceptionsWithNACausesShouldBeDisregarded() { final JsonJqTransform jsonJqTransform = new JsonJqTransform(objectMapper); - final Workflow workflow = new Workflow(); - final Task task = new Task(); + final WorkflowModel workflow = new WorkflowModel(); + final TaskModel task = new TaskModel(); final Map inputData = new HashMap<>(); inputData.put( "queryExpression", diff --git a/contribs/src/test/java/com/netflix/conductor/contribs/tasks/kafka/KafkaPublishTaskTest.java b/contribs/src/test/java/com/netflix/conductor/contribs/tasks/kafka/KafkaPublishTaskTest.java index 47249e7bec..a6e0961204 100644 --- a/contribs/src/test/java/com/netflix/conductor/contribs/tasks/kafka/KafkaPublishTaskTest.java +++ b/contribs/src/test/java/com/netflix/conductor/contribs/tasks/kafka/KafkaPublishTaskTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -28,9 +28,9 @@ import org.springframework.test.context.junit4.SpringRunner; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -50,15 +50,15 @@ public class KafkaPublishTaskTest { public void missingRequest_Fail() { KafkaPublishTask kafkaPublishTask = new KafkaPublishTask(getKafkaProducerManager(), objectMapper); - Task task = new Task(); - kafkaPublishTask.start(mock(Workflow.class), task, mock(WorkflowExecutor.class)); - assertEquals(Task.Status.FAILED, task.getStatus()); + TaskModel task = new TaskModel(); + kafkaPublishTask.start(mock(WorkflowModel.class), task, mock(WorkflowExecutor.class)); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); } @Test public void missingValue_Fail() { - Task task = new Task(); + TaskModel task = new TaskModel(); KafkaPublishTask.Input input = new KafkaPublishTask.Input(); input.setBootStrapServers("localhost:9092"); input.setTopic("testTopic"); @@ -67,14 +67,14 @@ public void missingValue_Fail() { KafkaPublishTask kPublishTask = new KafkaPublishTask(getKafkaProducerManager(), objectMapper); - kPublishTask.start(mock(Workflow.class), task, mock(WorkflowExecutor.class)); - assertEquals(Task.Status.FAILED, task.getStatus()); + kPublishTask.start(mock(WorkflowModel.class), task, mock(WorkflowExecutor.class)); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); } @Test public void missingBootStrapServers_Fail() { - Task task = new Task(); + TaskModel task = new TaskModel(); KafkaPublishTask.Input input = new KafkaPublishTask.Input(); Map value = new HashMap<>(); @@ -85,15 +85,15 @@ public void missingBootStrapServers_Fail() { KafkaPublishTask kPublishTask = new KafkaPublishTask(getKafkaProducerManager(), objectMapper); - kPublishTask.start(mock(Workflow.class), task, mock(WorkflowExecutor.class)); - assertEquals(Task.Status.FAILED, task.getStatus()); + kPublishTask.start(mock(WorkflowModel.class), task, mock(WorkflowExecutor.class)); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); } @Test public void kafkaPublishExecutionException_Fail() throws ExecutionException, InterruptedException { - Task task = getTask(); + TaskModel task = getTask(); KafkaProducerManager producerManager = mock(KafkaProducerManager.class); KafkaPublishTask kafkaPublishTask = new KafkaPublishTask(producerManager, objectMapper); @@ -109,8 +109,8 @@ public void kafkaPublishExecutionException_Fail() when(executionException.getMessage()).thenReturn("Execution exception"); when(publishingFuture.get()).thenThrow(executionException); - kafkaPublishTask.start(mock(Workflow.class), task, mock(WorkflowExecutor.class)); - assertEquals(Task.Status.FAILED, task.getStatus()); + kafkaPublishTask.start(mock(WorkflowModel.class), task, mock(WorkflowExecutor.class)); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); assertEquals( "Failed to invoke kafka task due to: Execution exception", task.getReasonForIncompletion()); @@ -119,7 +119,7 @@ public void kafkaPublishExecutionException_Fail() @Test public void kafkaPublishUnknownException_Fail() { - Task task = getTask(); + TaskModel task = getTask(); KafkaProducerManager producerManager = mock(KafkaProducerManager.class); KafkaPublishTask kPublishTask = new KafkaPublishTask(producerManager, objectMapper); @@ -129,8 +129,8 @@ public void kafkaPublishUnknownException_Fail() { when(producerManager.getProducer(any())).thenReturn(producer); when(producer.send(any())).thenThrow(new RuntimeException("Unknown exception")); - kPublishTask.start(mock(Workflow.class), task, mock(WorkflowExecutor.class)); - assertEquals(Task.Status.FAILED, task.getStatus()); + kPublishTask.start(mock(WorkflowModel.class), task, mock(WorkflowExecutor.class)); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); assertEquals( "Failed to invoke kafka task due to: Unknown exception", task.getReasonForIncompletion()); @@ -139,7 +139,7 @@ public void kafkaPublishUnknownException_Fail() { @Test public void kafkaPublishSuccess_Completed() { - Task task = getTask(); + TaskModel task = getTask(); KafkaProducerManager producerManager = mock(KafkaProducerManager.class); KafkaPublishTask kPublishTask = new KafkaPublishTask(producerManager, objectMapper); @@ -149,14 +149,14 @@ public void kafkaPublishSuccess_Completed() { when(producerManager.getProducer(any())).thenReturn(producer); when(producer.send(any())).thenReturn(mock(Future.class)); - kPublishTask.start(mock(Workflow.class), task, mock(WorkflowExecutor.class)); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + kPublishTask.start(mock(WorkflowModel.class), task, mock(WorkflowExecutor.class)); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); } @Test public void kafkaPublishSuccess_AsyncComplete() { - Task task = getTask(); + TaskModel task = getTask(); task.getInputData().put("asyncComplete", true); KafkaProducerManager producerManager = mock(KafkaProducerManager.class); @@ -167,12 +167,12 @@ public void kafkaPublishSuccess_AsyncComplete() { when(producerManager.getProducer(any())).thenReturn(producer); when(producer.send(any())).thenReturn(mock(Future.class)); - kPublishTask.start(mock(Workflow.class), task, mock(WorkflowExecutor.class)); - assertEquals(Task.Status.IN_PROGRESS, task.getStatus()); + kPublishTask.start(mock(WorkflowModel.class), task, mock(WorkflowExecutor.class)); + assertEquals(TaskModel.Status.IN_PROGRESS, task.getStatus()); } - private Task getTask() { - Task task = new Task(); + private TaskModel getTask() { + TaskModel task = new TaskModel(); KafkaPublishTask.Input input = new KafkaPublishTask.Input(); input.setBootStrapServers("localhost:9092"); diff --git a/core/src/main/java/com/netflix/conductor/annotations/Audit.java b/core/src/main/java/com/netflix/conductor/annotations/Audit.java index f63379dd0e..6f1d471991 100644 --- a/core/src/main/java/com/netflix/conductor/annotations/Audit.java +++ b/core/src/main/java/com/netflix/conductor/annotations/Audit.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/core/src/main/java/com/netflix/conductor/annotations/Trace.java b/core/src/main/java/com/netflix/conductor/annotations/Trace.java index 8f59d23908..61da42cc47 100644 --- a/core/src/main/java/com/netflix/conductor/annotations/Trace.java +++ b/core/src/main/java/com/netflix/conductor/annotations/Trace.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/core/src/main/java/com/netflix/conductor/core/LifecycleAwareComponent.java b/core/src/main/java/com/netflix/conductor/core/LifecycleAwareComponent.java index 071eace191..bfe1455fb6 100644 --- a/core/src/main/java/com/netflix/conductor/core/LifecycleAwareComponent.java +++ b/core/src/main/java/com/netflix/conductor/core/LifecycleAwareComponent.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 diff --git a/core/src/main/java/com/netflix/conductor/core/WorkflowContext.java b/core/src/main/java/com/netflix/conductor/core/WorkflowContext.java index ab0208db54..2f996a47a6 100644 --- a/core/src/main/java/com/netflix/conductor/core/WorkflowContext.java +++ b/core/src/main/java/com/netflix/conductor/core/WorkflowContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -12,7 +12,7 @@ */ package com.netflix.conductor.core; -/** Store the authentication context, app or user name or both */ +/** Store the authentication context, app or username or both */ public class WorkflowContext { public static final ThreadLocal THREAD_LOCAL = diff --git a/core/src/main/java/com/netflix/conductor/core/orchestration/ExecutionDAOFacade.java b/core/src/main/java/com/netflix/conductor/core/dal/ExecutionDAOFacade.java similarity index 81% rename from core/src/main/java/com/netflix/conductor/core/orchestration/ExecutionDAOFacade.java rename to core/src/main/java/com/netflix/conductor/core/dal/ExecutionDAOFacade.java index a230f4a851..2556693a36 100644 --- a/core/src/main/java/com/netflix/conductor/core/orchestration/ExecutionDAOFacade.java +++ b/core/src/main/java/com/netflix/conductor/core/dal/ExecutionDAOFacade.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

* 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 @@ -10,7 +10,7 @@ * 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.core.orchestration; +package com.netflix.conductor.core.dal; import java.io.IOException; import java.util.Collections; @@ -32,23 +32,22 @@ import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.run.SearchResult; +import com.netflix.conductor.common.run.TaskSummary; import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.exception.ApplicationException.Code; -import com.netflix.conductor.dao.ConcurrentExecutionLimitDAO; -import com.netflix.conductor.dao.ExecutionDAO; -import com.netflix.conductor.dao.IndexDAO; -import com.netflix.conductor.dao.PollDataDAO; -import com.netflix.conductor.dao.QueueDAO; -import com.netflix.conductor.dao.RateLimitingDAO; +import com.netflix.conductor.dao.*; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import static com.netflix.conductor.core.execution.WorkflowExecutor.DECIDER_QUEUE; +import static com.netflix.conductor.core.utils.Utils.DECIDER_QUEUE; /** * Service that acts as a facade for accessing execution data from the {@link ExecutionDAO}, {@link @@ -69,6 +68,7 @@ public class ExecutionDAOFacade { private final RateLimitingDAO rateLimitingDao; private final ConcurrentExecutionLimitDAO concurrentExecutionLimitDAO; private final PollDataDAO pollDataDAO; + private final ModelMapper modelMapper; private final ObjectMapper objectMapper; private final ConductorProperties properties; @@ -81,6 +81,7 @@ public ExecutionDAOFacade( RateLimitingDAO rateLimitingDao, ConcurrentExecutionLimitDAO concurrentExecutionLimitDAO, PollDataDAO pollDataDAO, + ModelMapper modelMapper, ObjectMapper objectMapper, ConductorProperties properties) { this.executionDAO = executionDAO; @@ -89,6 +90,7 @@ public ExecutionDAOFacade( this.rateLimitingDao = rateLimitingDao; this.concurrentExecutionLimitDAO = concurrentExecutionLimitDAO; this.pollDataDAO = pollDataDAO; + this.modelMapper = modelMapper; this.objectMapper = objectMapper; this.properties = properties; this.scheduledThreadPoolExecutor = @@ -126,6 +128,10 @@ public void shutdownExecutorService() { } } + public WorkflowModel getWorkflowModel(String workflowId, boolean includeTasks) { + return modelMapper.getFullCopy(getWorkflowFromDatastore(workflowId, includeTasks)); + } + /** * Fetches the {@link Workflow} object from the data store given the id. Attempts to fetch from * {@link ExecutionDAO} first, if not found, attempts to fetch from {@link IndexDAO}. @@ -139,8 +145,12 @@ public void shutdownExecutorService() { *

  • parsing the {@link Workflow} object fails * */ - public Workflow getWorkflowById(String workflowId, boolean includeTasks) { - Workflow workflow = executionDAO.getWorkflow(workflowId, includeTasks); + public Workflow getWorkflow(String workflowId, boolean includeTasks) { + return modelMapper.getWorkflow(getWorkflowFromDatastore(workflowId, includeTasks)); + } + + private WorkflowModel getWorkflowFromDatastore(String workflowId, boolean includeTasks) { + WorkflowModel workflow = executionDAO.getWorkflow(workflowId, includeTasks); if (workflow == null) { LOGGER.debug("Workflow {} not found in executionDAO, checking indexDAO", workflowId); String json = indexDAO.get(workflowId, RAW_JSON_FIELD); @@ -151,7 +161,7 @@ public Workflow getWorkflowById(String workflowId, boolean includeTasks) { } try { - workflow = objectMapper.readValue(json, Workflow.class); + workflow = objectMapper.readValue(json, WorkflowModel.class); if (!includeTasks) { workflow.getTasks().clear(); } @@ -186,7 +196,7 @@ public List getWorkflowsByCorrelationId( .map( workflowId -> { try { - return getWorkflowById(workflowId, includeTasks); + return getWorkflow(workflowId, includeTasks); } catch (ApplicationException e) { // This might happen when the workflow archival failed and the // workflow was removed from primary datastore @@ -201,15 +211,23 @@ public List getWorkflowsByCorrelationId( .filter(Objects::nonNull) .collect(Collectors.toList()); } - return executionDAO.getWorkflowsByCorrelationId(workflowName, correlationId, includeTasks); + return executionDAO + .getWorkflowsByCorrelationId(workflowName, correlationId, includeTasks) + .stream() + .map(modelMapper::getWorkflow) + .collect(Collectors.toList()); } public List getWorkflowsByName(String workflowName, Long startTime, Long endTime) { - return executionDAO.getWorkflowsByType(workflowName, startTime, endTime); + return executionDAO.getWorkflowsByType(workflowName, startTime, endTime).stream() + .map(modelMapper::getWorkflow) + .collect(Collectors.toList()); } public List getPendingWorkflowsByName(String workflowName, int version) { - return executionDAO.getPendingWorkflowsByType(workflowName, version); + return executionDAO.getPendingWorkflowsByType(workflowName, version).stream() + .map(modelMapper::getWorkflow) + .collect(Collectors.toList()); } public List getRunningWorkflowIds(String workflowName, int version) { @@ -226,21 +244,21 @@ public long getPendingWorkflowCount(String workflowName) { * @param workflow the workflow to be created * @return the id of the created workflow */ - public String createWorkflow(Workflow workflow) { - workflow.setCreateTime(System.currentTimeMillis()); - executionDAO.createWorkflow(workflow); + public String createWorkflow(WorkflowModel workflow) { + WorkflowModel leanWorkflow = modelMapper.getLeanCopy(workflow); + executionDAO.createWorkflow(leanWorkflow); // Add to decider queue queueDAO.push( DECIDER_QUEUE, - workflow.getWorkflowId(), - workflow.getPriority(), + leanWorkflow.getWorkflowId(), + leanWorkflow.getPriority(), properties.getWorkflowOffsetTimeout().getSeconds()); if (properties.isAsyncIndexingEnabled()) { - indexDAO.asyncIndexWorkflow(workflow); + indexDAO.asyncIndexWorkflow(new WorkflowSummary(modelMapper.getWorkflow(leanWorkflow))); } else { - indexDAO.indexWorkflow(workflow); + indexDAO.indexWorkflow(new WorkflowSummary(modelMapper.getWorkflow(leanWorkflow))); } - return workflow.getWorkflowId(); + return leanWorkflow.getWorkflowId(); } /** @@ -249,15 +267,16 @@ public String createWorkflow(Workflow workflow) { * @param workflow the workflow tp be updated * @return the id of the updated workflow */ - public String updateWorkflow(Workflow workflow) { - workflow.setUpdateTime(System.currentTimeMillis()); + public String updateWorkflow(WorkflowModel workflow) { + workflow.setUpdatedTime(System.currentTimeMillis()); if (workflow.getStatus().isTerminal()) { workflow.setEndTime(System.currentTimeMillis()); } - executionDAO.updateWorkflow(workflow); + WorkflowModel leanWorkflow = modelMapper.getLeanCopy(workflow); + executionDAO.updateWorkflow(leanWorkflow); if (properties.isAsyncIndexingEnabled()) { if (workflow.getStatus().isTerminal() - && workflow.getEndTime() - workflow.getStartTime() + && workflow.getEndTime() - workflow.getCreateTime() < properties.getAsyncUpdateShortRunningWorkflowDuration().toMillis()) { final String workflowId = workflow.getWorkflowId(); DelayWorkflowUpdate delayWorkflowUpdate = new DelayWorkflowUpdate(workflowId); @@ -272,13 +291,19 @@ public String updateWorkflow(Workflow workflow) { Monitors.recordWorkerQueueSize( "delayQueue", scheduledThreadPoolExecutor.getQueue().size()); } else { - indexDAO.asyncIndexWorkflow(workflow); + indexDAO.asyncIndexWorkflow( + new WorkflowSummary(modelMapper.getWorkflow(leanWorkflow))); } if (workflow.getStatus().isTerminal()) { - workflow.getTasks().forEach(indexDAO::asyncIndexTask); + workflow.getTasks() + .forEach( + taskModel -> { + indexDAO.asyncIndexTask( + new TaskSummary(modelMapper.getTask(taskModel))); + }); } } else { - indexDAO.indexWorkflow(workflow); + indexDAO.indexWorkflow(new WorkflowSummary(modelMapper.getWorkflow(leanWorkflow))); } return workflow.getWorkflowId(); } @@ -296,7 +321,7 @@ public void removeFromPendingWorkflow(String workflowType, String workflowId) { */ public void removeWorkflow(String workflowId, boolean archiveWorkflow) { try { - Workflow workflow = getWorkflowById(workflowId, true); + WorkflowModel workflow = getWorkflowFromDatastore(workflowId, true); removeWorkflowIndex(workflow, archiveWorkflow); // remove workflow from DAO @@ -321,7 +346,7 @@ public void removeWorkflow(String workflowId, boolean archiveWorkflow) { } } - private void removeWorkflowIndex(Workflow workflow, boolean archiveWorkflow) + private void removeWorkflowIndex(WorkflowModel workflow, boolean archiveWorkflow) throws JsonProcessingException { if (archiveWorkflow) { if (workflow.getStatus().isTerminal()) { @@ -347,7 +372,7 @@ private void removeWorkflowIndex(Workflow workflow, boolean archiveWorkflow) public void removeWorkflowWithExpiry( String workflowId, boolean archiveWorkflow, int ttlSeconds) { try { - Workflow workflow = getWorkflowById(workflowId, true); + WorkflowModel workflow = getWorkflowFromDatastore(workflowId, true); removeWorkflowIndex(workflow, archiveWorkflow); // remove workflow from DAO with TTL @@ -375,7 +400,7 @@ public void removeWorkflowWithExpiry( */ public void resetWorkflow(String workflowId) { try { - getWorkflowById(workflowId, true); + getWorkflowFromDatastore(workflowId, true); executionDAO.removeWorkflow(workflowId); if (properties.isAsyncIndexingEnabled()) { indexDAO.asyncRemoveWorkflow(workflowId); @@ -392,24 +417,47 @@ public void resetWorkflow(String workflowId) { } } - public List createTasks(List tasks) { + public List createTasks(List tasks) { + tasks = tasks.stream().map(modelMapper::getLeanCopy).collect(Collectors.toList()); return executionDAO.createTasks(tasks); } public List getTasksForWorkflow(String workflowId) { - return executionDAO.getTasksForWorkflow(workflowId); + return executionDAO.getTasksForWorkflow(workflowId).stream() + .map(modelMapper::getTask) + .collect(Collectors.toList()); + } + + public TaskModel getTaskModel(String taskId) { + TaskModel taskModel = getTaskFromDatastore(taskId); + if (taskModel != null) { + return modelMapper.getFullCopy(taskModel); + } + return null; + } + + public Task getTask(String taskId) { + TaskModel taskModel = getTaskFromDatastore(taskId); + if (taskModel != null) { + return modelMapper.getTask(taskModel); + } + return null; } - public Task getTaskById(String taskId) { + private TaskModel getTaskFromDatastore(String taskId) { return executionDAO.getTask(taskId); } public List getTasksByName(String taskName, String startKey, int count) { - return executionDAO.getTasks(taskName, startKey, count); + return executionDAO.getTasks(taskName, startKey, count).stream() + .map(modelMapper::getTask) + .collect(Collectors.toList()); } public List getPendingTasksForTaskType(String taskType) { - return executionDAO.getPendingTasksForTaskType(taskType); + return executionDAO.getPendingTasksForTaskType(taskType).stream() + .map(modelMapper::getTask) + .collect(Collectors.toList()); } public long getInProgressTaskCount(String taskDefName) { @@ -424,7 +472,7 @@ public long getInProgressTaskCount(String taskDefName) { * @param task the task to be updated in the data store * @throws ApplicationException if the dao operations fail */ - public void updateTask(Task task) { + public void updateTask(TaskModel task) { try { if (task.getStatus() != null) { if (!task.getStatus().isTerminal() @@ -435,7 +483,8 @@ public void updateTask(Task task) { task.setEndTime(System.currentTimeMillis()); } } - executionDAO.updateTask(task); + TaskModel leanTask = modelMapper.getLeanCopy(task); + executionDAO.updateTask(leanTask); /* * Indexing a task for every update adds a lot of volume. That is ok but if async indexing * is enabled and tasks are stored in memory until a block has completed, we would lose a lot @@ -443,7 +492,7 @@ public void updateTask(Task task) { * If it *is* enabled, tasks will be indexed only when a workflow is in terminal state. */ if (!properties.isAsyncIndexingEnabled()) { - indexDAO.indexTask(task); + indexDAO.indexTask(new TaskSummary(modelMapper.getTask(leanTask))); } } catch (Exception e) { String errorMsg = @@ -455,7 +504,7 @@ public void updateTask(Task task) { } } - public void updateTasks(List tasks) { + public void updateTasks(List tasks) { tasks.forEach(this::updateTask); } @@ -531,11 +580,11 @@ public void removeEventExecution(EventExecution eventExecution) { executionDAO.removeEventExecution(eventExecution); } - public boolean exceedsInProgressLimit(Task task) { + public boolean exceedsInProgressLimit(TaskModel task) { return concurrentExecutionLimitDAO.exceedsLimit(task); } - public boolean exceedsRateLimitPerFrequency(Task task, TaskDef taskDef) { + public boolean exceedsRateLimitPerFrequency(TaskModel task, TaskDef taskDef) { return rateLimitingDao.exceedsRateLimitPerFrequency(task, taskDef); } @@ -584,8 +633,8 @@ class DelayWorkflowUpdate implements Runnable { @Override public void run() { try { - Workflow workflow = executionDAO.getWorkflow(workflowId, false); - indexDAO.asyncIndexWorkflow(workflow); + WorkflowModel workflow = executionDAO.getWorkflow(workflowId, false); + indexDAO.asyncIndexWorkflow(new WorkflowSummary(modelMapper.getWorkflow(workflow))); } catch (Exception e) { LOGGER.error("Unable to update workflow: {}", workflowId, e); } diff --git a/core/src/main/java/com/netflix/conductor/core/dal/ModelMapper.java b/core/src/main/java/com/netflix/conductor/core/dal/ModelMapper.java new file mode 100644 index 0000000000..a1bd3a0bb7 --- /dev/null +++ b/core/src/main/java/com/netflix/conductor/core/dal/ModelMapper.java @@ -0,0 +1,192 @@ +/* + * Copyright 2022 Netflix, Inc. + *

    + * 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.core.dal; + +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Component; + +import com.netflix.conductor.common.metadata.tasks.Task; +import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.common.utils.ExternalPayloadStorage.Operation; +import com.netflix.conductor.common.utils.ExternalPayloadStorage.PayloadType; +import com.netflix.conductor.core.utils.ExternalPayloadStorageUtils; +import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; + +@Component +public class ModelMapper { + + private static final Logger LOGGER = LoggerFactory.getLogger(ModelMapper.class); + + private final ExternalPayloadStorageUtils externalPayloadStorageUtils; + + public ModelMapper(ExternalPayloadStorageUtils externalPayloadStorageUtils) { + this.externalPayloadStorageUtils = externalPayloadStorageUtils; + } + + /** + * Fetch the fully formed workflow domain object with complete payloads + * + * @param workflowModel the workflow domain object from the datastore + * @return the workflow domain object {@link WorkflowModel} with payloads from external storage + */ + public WorkflowModel getFullCopy(WorkflowModel workflowModel) { + populateWorkflowAndTaskPayloadData(workflowModel); + return workflowModel; + } + + /** + * Get a lean copy of the workflow domain object with large payloads externalized + * + * @param workflowModel the fully formed workflow domain object + * @return the workflow domain object {@link WorkflowModel} with large payloads externalized + */ + public WorkflowModel getLeanCopy(WorkflowModel workflowModel) { + WorkflowModel leanWorkflowModel = workflowModel.copy(); + externalizeWorkflowData(leanWorkflowModel); + workflowModel.getTasks().forEach(this::getLeanCopy); + return leanWorkflowModel; + } + + /** + * Map the workflow domain object to the workflow DTO + * + * @param workflowModel the workflow domain object {@link WorkflowModel} + * @return the workflow DTO {@link Workflow} + */ + public Workflow getWorkflow(WorkflowModel workflowModel) { + externalizeWorkflowData(workflowModel); + + Workflow workflow = new Workflow(); + BeanUtils.copyProperties(workflowModel, workflow); + workflow.setStatus(Workflow.WorkflowStatus.valueOf(workflowModel.getStatus().name())); + workflow.setTasks( + workflowModel.getTasks().stream().map(this::getTask).collect(Collectors.toList())); + + return workflow; + } + + /** + * Fetch the fully formed task domain object with complete payloads + * + * @param taskModel the task domain object from the datastore + * @return the task domain object {@link TaskModel} with payloads from external storage + */ + public TaskModel getFullCopy(TaskModel taskModel) { + populateTaskData(taskModel); + return taskModel; + } + + /** + * Get a lean copy of the task domain object with large payloads externalized + * + * @param taskModel the fully formed task domain object + * @return the task domain object {@link TaskModel} with large payloads externalized + */ + public TaskModel getLeanCopy(TaskModel taskModel) { + TaskModel leanTaskModel = taskModel.copy(); + externalizeTaskData(leanTaskModel); + return leanTaskModel; + } + + /** + * Map the task domain object to the task DTO + * + * @param taskModel the task domain object {@link TaskModel} + * @return the task DTO {@link Task} + */ + public Task getTask(TaskModel taskModel) { + externalizeTaskData(taskModel); + + Task task = new Task(); + BeanUtils.copyProperties(taskModel, task); + task.setStatus(Task.Status.valueOf(taskModel.getStatus().name())); + return task; + } + + /** + * Populates the workflow input data and the tasks input/output data if stored in external + * payload storage. + * + * @param workflowModel the workflowModel for which the payload data needs to be populated from + * external storage (if applicable) + */ + private void populateWorkflowAndTaskPayloadData(WorkflowModel workflowModel) { + if (StringUtils.isNotBlank(workflowModel.getExternalInputPayloadStoragePath())) { + Map workflowInputParams = + externalPayloadStorageUtils.downloadPayload( + workflowModel.getExternalInputPayloadStoragePath()); + Monitors.recordExternalPayloadStorageUsage( + workflowModel.getWorkflowName(), + Operation.READ.toString(), + PayloadType.WORKFLOW_INPUT.toString()); + workflowModel.setInput(workflowInputParams); + workflowModel.setExternalInputPayloadStoragePath(null); + } + + if (StringUtils.isNotBlank(workflowModel.getExternalOutputPayloadStoragePath())) { + Map workflowOutputParams = + externalPayloadStorageUtils.downloadPayload( + workflowModel.getExternalOutputPayloadStoragePath()); + Monitors.recordExternalPayloadStorageUsage( + workflowModel.getWorkflowName(), + Operation.READ.toString(), + PayloadType.WORKFLOW_OUTPUT.toString()); + workflowModel.setOutput(workflowOutputParams); + workflowModel.setExternalOutputPayloadStoragePath(null); + } + + workflowModel.getTasks().forEach(this::populateTaskData); + } + + private void populateTaskData(TaskModel taskModel) { + if (StringUtils.isNotBlank(taskModel.getExternalOutputPayloadStoragePath())) { + taskModel.setOutputData( + externalPayloadStorageUtils.downloadPayload( + taskModel.getExternalOutputPayloadStoragePath())); + Monitors.recordExternalPayloadStorageUsage( + taskModel.getTaskDefName(), + Operation.READ.toString(), + PayloadType.TASK_OUTPUT.toString()); + taskModel.setExternalOutputPayloadStoragePath(null); + } + + if (StringUtils.isNotBlank(taskModel.getExternalInputPayloadStoragePath())) { + taskModel.setInputData( + externalPayloadStorageUtils.downloadPayload( + taskModel.getExternalInputPayloadStoragePath())); + Monitors.recordExternalPayloadStorageUsage( + taskModel.getTaskDefName(), + Operation.READ.toString(), + PayloadType.TASK_INPUT.toString()); + taskModel.setExternalInputPayloadStoragePath(null); + } + } + + private void externalizeTaskData(TaskModel taskModel) { + externalPayloadStorageUtils.verifyAndUpload(taskModel, PayloadType.TASK_INPUT); + externalPayloadStorageUtils.verifyAndUpload(taskModel, PayloadType.TASK_OUTPUT); + } + + private void externalizeWorkflowData(WorkflowModel workflowModel) { + externalPayloadStorageUtils.verifyAndUpload(workflowModel, PayloadType.WORKFLOW_INPUT); + externalPayloadStorageUtils.verifyAndUpload(workflowModel, PayloadType.WORKFLOW_OUTPUT); + } +} diff --git a/core/src/main/java/com/netflix/conductor/core/events/ActionProcessor.java b/core/src/main/java/com/netflix/conductor/core/events/ActionProcessor.java index 196d75d669..6b81396529 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/ActionProcessor.java +++ b/core/src/main/java/com/netflix/conductor/core/events/ActionProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/events/DefaultEventProcessor.java b/core/src/main/java/com/netflix/conductor/core/events/DefaultEventProcessor.java index 309fd8c660..52e50f288a 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/DefaultEventProcessor.java +++ b/core/src/main/java/com/netflix/conductor/core/events/DefaultEventProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/events/DefaultEventQueueManager.java b/core/src/main/java/com/netflix/conductor/core/events/DefaultEventQueueManager.java index d71cbda82a..1c83096586 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/DefaultEventQueueManager.java +++ b/core/src/main/java/com/netflix/conductor/core/events/DefaultEventQueueManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -49,7 +49,6 @@ * * @see DefaultEventQueueProcessor */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component @ConditionalOnProperty( name = "conductor.default-event-processor.enabled", diff --git a/core/src/main/java/com/netflix/conductor/core/events/EventQueueManager.java b/core/src/main/java/com/netflix/conductor/core/events/EventQueueManager.java index 9b532c38d8..fc6a568f68 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/EventQueueManager.java +++ b/core/src/main/java/com/netflix/conductor/core/events/EventQueueManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/events/EventQueueProvider.java b/core/src/main/java/com/netflix/conductor/core/events/EventQueueProvider.java index 4bcceb0b8c..8bd11f929a 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/EventQueueProvider.java +++ b/core/src/main/java/com/netflix/conductor/core/events/EventQueueProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/events/EventQueues.java b/core/src/main/java/com/netflix/conductor/core/events/EventQueues.java index e29b17ee5b..b4ab2e388f 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/EventQueues.java +++ b/core/src/main/java/com/netflix/conductor/core/events/EventQueues.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/events/ScriptEvaluator.java b/core/src/main/java/com/netflix/conductor/core/events/ScriptEvaluator.java index 44e3aaae6b..506ded2211 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/ScriptEvaluator.java +++ b/core/src/main/java/com/netflix/conductor/core/events/ScriptEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/events/SimpleActionProcessor.java b/core/src/main/java/com/netflix/conductor/core/events/SimpleActionProcessor.java index 0f421f6da0..7265e21dce 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/SimpleActionProcessor.java +++ b/core/src/main/java/com/netflix/conductor/core/events/SimpleActionProcessor.java @@ -24,14 +24,14 @@ import com.netflix.conductor.common.metadata.events.EventHandler.Action; import com.netflix.conductor.common.metadata.events.EventHandler.StartWorkflow; import com.netflix.conductor.common.metadata.events.EventHandler.TaskDetails; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.metadata.tasks.TaskResult; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.core.dal.ModelMapper; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.utils.JsonUtils; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * Action Processor subscribes to the Event Actions queue and processes the actions (e.g. start @@ -43,14 +43,17 @@ public class SimpleActionProcessor implements ActionProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleActionProcessor.class); private final WorkflowExecutor workflowExecutor; + private final ModelMapper modelMapper; private final ParametersUtils parametersUtils; private final JsonUtils jsonUtils; public SimpleActionProcessor( WorkflowExecutor workflowExecutor, + ModelMapper modelMapper, ParametersUtils parametersUtils, JsonUtils jsonUtils) { this.workflowExecutor = workflowExecutor; + this.modelMapper = modelMapper; this.parametersUtils = parametersUtils; this.jsonUtils = jsonUtils; } @@ -77,12 +80,17 @@ public Map execute( action, jsonObject, action.getComplete_task(), - Status.COMPLETED, + TaskModel.Status.COMPLETED, event, messageId); case fail_task: return completeTask( - action, jsonObject, action.getFail_task(), Status.FAILED, event, messageId); + action, + jsonObject, + action.getFail_task(), + TaskModel.Status.FAILED, + event, + messageId); default: break; } @@ -94,7 +102,7 @@ private Map completeTask( Action action, Object payload, TaskDetails taskDetails, - Status status, + TaskModel.Status status, String event, String messageId) { @@ -109,11 +117,11 @@ private Map completeTask( String taskId = (String) replaced.get("taskId"); String taskRefName = (String) replaced.get("taskRefName"); - Task task = null; + TaskModel task = null; if (StringUtils.isNotEmpty(taskId)) { task = workflowExecutor.getTask(taskId); } else if (StringUtils.isNotEmpty(workflowId) && StringUtils.isNotEmpty(taskRefName)) { - Workflow workflow = workflowExecutor.getWorkflow(workflowId, true); + WorkflowModel workflow = workflowExecutor.getWorkflow(workflowId, true); if (workflow == null) { replaced.put("error", "No workflow found with ID: " + workflowId); return replaced; @@ -140,7 +148,7 @@ private Map completeTask( task.getOutputData().put("conductor.event.name", event); try { - workflowExecutor.updateTask(new TaskResult(task)); + workflowExecutor.updateTask(new TaskResult(modelMapper.getTask(task))); LOGGER.debug( "Updated task: {} in workflow:{} with status: {} for event: {} for message:{}", taskId, diff --git a/core/src/main/java/com/netflix/conductor/core/events/queue/ConductorEventQueueProvider.java b/core/src/main/java/com/netflix/conductor/core/events/queue/ConductorEventQueueProvider.java index a3d0ac2abc..76e5301013 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/queue/ConductorEventQueueProvider.java +++ b/core/src/main/java/com/netflix/conductor/core/events/queue/ConductorEventQueueProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -35,7 +35,6 @@ * * @see ConductorObservableQueue */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component @ConditionalOnProperty( name = "conductor.event-queues.default.enabled", diff --git a/core/src/main/java/com/netflix/conductor/core/events/queue/ConductorObservableQueue.java b/core/src/main/java/com/netflix/conductor/core/events/queue/ConductorObservableQueue.java index 4ecf0ea875..649cc7b501 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/queue/ConductorObservableQueue.java +++ b/core/src/main/java/com/netflix/conductor/core/events/queue/ConductorObservableQueue.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/events/queue/DefaultEventQueueProcessor.java b/core/src/main/java/com/netflix/conductor/core/events/queue/DefaultEventQueueProcessor.java index 7255b51e99..de3a2811b8 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/queue/DefaultEventQueueProcessor.java +++ b/core/src/main/java/com/netflix/conductor/core/events/queue/DefaultEventQueueProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -27,6 +27,7 @@ import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.Task.Status; +import com.netflix.conductor.common.metadata.tasks.TaskResult; import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.exception.ApplicationException.Code; @@ -55,8 +56,7 @@ public class DefaultEventQueueProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultEventQueueProcessor.class); private final Map queues; private final ExecutionService executionService; - private static final TypeReference> _mapType = - new TypeReference>() {}; + private static final TypeReference> _mapType = new TypeReference<>() {}; private final ObjectMapper objectMapper; public DefaultEventQueueProcessor( @@ -135,7 +135,7 @@ private void startMonitor(Status status, ObservableQueue queue) { .findFirst(); } - if (!taskOptional.isPresent()) { + if (taskOptional.isEmpty()) { LOGGER.error( "No matching tasks found to be marked as completed for workflow {}, taskRefName {}, taskId {}", workflowId, @@ -149,12 +149,11 @@ private void startMonitor(Status status, ObservableQueue queue) { task.setStatus(status); task.getOutputData() .putAll(objectMapper.convertValue(payloadJSON, _mapType)); - executionService.updateTask(task); + executionService.updateTask(new TaskResult(task)); List failures = queue.ack(Collections.singletonList(msg)); if (!failures.isEmpty()) { - LOGGER.error( - "Not able to ack the messages {}", failures.toString()); + LOGGER.error("Not able to ack the messages {}", failures); } } catch (JsonParseException e) { LOGGER.error("Bad message? : {} ", msg, e); diff --git a/core/src/main/java/com/netflix/conductor/core/events/queue/Message.java b/core/src/main/java/com/netflix/conductor/core/events/queue/Message.java index a6c8584ae5..7db1ac56d7 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/queue/Message.java +++ b/core/src/main/java/com/netflix/conductor/core/events/queue/Message.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/events/queue/ObservableQueue.java b/core/src/main/java/com/netflix/conductor/core/events/queue/ObservableQueue.java index c9195b6f63..897090ba7f 100644 --- a/core/src/main/java/com/netflix/conductor/core/events/queue/ObservableQueue.java +++ b/core/src/main/java/com/netflix/conductor/core/events/queue/ObservableQueue.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/exception/ApplicationException.java b/core/src/main/java/com/netflix/conductor/core/exception/ApplicationException.java index baa0b11657..f1a086d403 100644 --- a/core/src/main/java/com/netflix/conductor/core/exception/ApplicationException.java +++ b/core/src/main/java/com/netflix/conductor/core/exception/ApplicationException.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -18,7 +18,6 @@ import java.util.LinkedHashMap; import java.util.Map; -@SuppressWarnings("serial") public class ApplicationException extends RuntimeException { public enum Code { @@ -78,7 +77,7 @@ public String getTrace() { PrintStream ps = new PrintStream(baos); this.printStackTrace(ps); ps.flush(); - return new String(baos.toByteArray()); + return baos.toString(); } public Map toMap() { diff --git a/core/src/main/java/com/netflix/conductor/core/exception/TerminateWorkflowException.java b/core/src/main/java/com/netflix/conductor/core/exception/TerminateWorkflowException.java index 5ae9caa991..366c4864f8 100644 --- a/core/src/main/java/com/netflix/conductor/core/exception/TerminateWorkflowException.java +++ b/core/src/main/java/com/netflix/conductor/core/exception/TerminateWorkflowException.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,33 +12,36 @@ */ package com.netflix.conductor.core.exception; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow.WorkflowStatus; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; + +import static com.netflix.conductor.model.WorkflowModel.Status.FAILED; public class TerminateWorkflowException extends RuntimeException { - private final WorkflowStatus workflowStatus; - private final Task task; + private final WorkflowModel.Status workflowStatus; + private final TaskModel task; public TerminateWorkflowException(String reason) { - this(reason, WorkflowStatus.FAILED); + this(reason, FAILED); } - public TerminateWorkflowException(String reason, WorkflowStatus workflowStatus) { + public TerminateWorkflowException(String reason, WorkflowModel.Status workflowStatus) { this(reason, workflowStatus, null); } - public TerminateWorkflowException(String reason, WorkflowStatus workflowStatus, Task task) { + public TerminateWorkflowException( + String reason, WorkflowModel.Status workflowStatus, TaskModel task) { super(reason); this.workflowStatus = workflowStatus; this.task = task; } - public WorkflowStatus getWorkflowStatus() { + public WorkflowModel.Status getWorkflowStatus() { return workflowStatus; } - public Task getTask() { + public TaskModel getTask() { return task; } } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/AsyncSystemTaskExecutor.java b/core/src/main/java/com/netflix/conductor/core/execution/AsyncSystemTaskExecutor.java index 07afb03672..cb5d737d35 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/AsyncSystemTaskExecutor.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/AsyncSystemTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -16,19 +16,15 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.config.ConductorProperties; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; import com.netflix.conductor.core.utils.QueueUtils; import com.netflix.conductor.dao.MetadataDAO; import com.netflix.conductor.dao.QueueDAO; import com.netflix.conductor.metrics.Monitors; - -import static com.netflix.conductor.common.metadata.tasks.Task.Status.CANCELED; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.IN_PROGRESS; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.SCHEDULED; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; @Component public class AsyncSystemTaskExecutor { @@ -39,7 +35,6 @@ public class AsyncSystemTaskExecutor { private final long queueTaskMessagePostponeSecs; private final long systemTaskCallbackTime; private final WorkflowExecutor workflowExecutor; - private final DeciderService deciderService; private static final Logger LOGGER = LoggerFactory.getLogger(AsyncSystemTaskExecutor.class); @@ -48,13 +43,11 @@ public AsyncSystemTaskExecutor( QueueDAO queueDAO, MetadataDAO metadataDAO, ConductorProperties conductorProperties, - WorkflowExecutor workflowExecutor, - DeciderService deciderService) { + WorkflowExecutor workflowExecutor) { this.executionDAOFacade = executionDAOFacade; this.queueDAO = queueDAO; this.metadataDAO = metadataDAO; this.workflowExecutor = workflowExecutor; - this.deciderService = deciderService; this.systemTaskCallbackTime = conductorProperties.getSystemTaskWorkerCallbackDuration().getSeconds(); this.queueTaskMessagePostponeSecs = @@ -65,10 +58,10 @@ public AsyncSystemTaskExecutor( * Executes and persists the results of an async {@link WorkflowSystemTask}. * * @param systemTask The {@link WorkflowSystemTask} to be executed. - * @param taskId The id of the {@link Task} object. + * @param taskId The id of the {@link TaskModel} object. */ public void execute(WorkflowSystemTask systemTask, String taskId) { - Task task = loadTaskQuietly(taskId); + TaskModel task = loadTaskQuietly(taskId); if (task == null) { LOGGER.error("TaskId: {} could not be found while executing {}", taskId, systemTask); return; @@ -84,9 +77,8 @@ public void execute(WorkflowSystemTask systemTask, String taskId) { return; } - if (task.getStatus().equals(SCHEDULED)) { + if (task.getStatus().equals(TaskModel.Status.SCHEDULED)) { if (executionDAOFacade.exceedsInProgressLimit(task)) { - // TODO: add a metric to record this LOGGER.warn( "Concurrent Execution limited for {}:{}", taskId, task.getTaskDefName()); postponeQuietly(queueName, task); @@ -110,7 +102,7 @@ public void execute(WorkflowSystemTask systemTask, String taskId) { // if we are here the Task object is updated and needs to be persisted regardless of an // exception try { - Workflow workflow = executionDAOFacade.getWorkflowById(workflowId, true); + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true); if (workflow.getStatus().isTerminal()) { LOGGER.info( @@ -119,7 +111,7 @@ public void execute(WorkflowSystemTask systemTask, String taskId) { systemTask, task.getTaskId()); if (!task.getStatus().isTerminal()) { - task.setStatus(CANCELED); + task.setStatus(TaskModel.Status.CANCELED); task.setReasonForIncompletion( String.format( "Workflow is in %s state", workflow.getStatus().toString())); @@ -134,29 +126,22 @@ public void execute(WorkflowSystemTask systemTask, String taskId) { task.getTaskId(), task.getStatus()); - // load task data (input/output) from external storage, if necessary - deciderService.populateTaskData(task); - boolean isTaskAsyncComplete = systemTask.isAsyncComplete(task); - if (task.getStatus() == SCHEDULED || !isTaskAsyncComplete) { + if (task.getStatus() == TaskModel.Status.SCHEDULED || !isTaskAsyncComplete) { task.incrementPollCount(); } - if (task.getStatus() == SCHEDULED) { + if (task.getStatus() == TaskModel.Status.SCHEDULED) { task.setStartTime(System.currentTimeMillis()); Monitors.recordQueueWaitTime(task.getTaskDefName(), task.getQueueWaitTime()); systemTask.start(workflow, task, workflowExecutor); - } else if (task.getStatus() == IN_PROGRESS) { + } else if (task.getStatus() == TaskModel.Status.IN_PROGRESS) { systemTask.execute(workflow, task, workflowExecutor); } - if (task.getOutputData() != null && !task.getOutputData().isEmpty()) { - deciderService.externalizeTaskData(task); - } - // Update message in Task queue based on Task status // Remove asyncComplete system tasks from the queue that are not in SCHEDULED state - if (isTaskAsyncComplete && task.getStatus() != SCHEDULED) { + if (isTaskAsyncComplete && task.getStatus() != TaskModel.Status.SCHEDULED) { queueDAO.remove(queueName, task.getTaskId()); hasTaskExecutionCompleted = true; } else if (task.getStatus().isTerminal()) { @@ -191,7 +176,7 @@ public void execute(WorkflowSystemTask systemTask, String taskId) { } } - private void postponeQuietly(String queueName, Task task) { + private void postponeQuietly(String queueName, TaskModel task) { try { queueDAO.postpone( queueName, @@ -203,9 +188,9 @@ private void postponeQuietly(String queueName, Task task) { } } - private Task loadTaskQuietly(String taskId) { + private TaskModel loadTaskQuietly(String taskId) { try { - return executionDAOFacade.getTaskById(taskId); + return executionDAOFacade.getTaskModel(taskId); } catch (Exception e) { return null; } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/DeciderService.java b/core/src/main/java/com/netflix/conductor/core/execution/DeciderService.java index 9f04f1f51e..66cc2c9e74 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/DeciderService.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/DeciderService.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -13,14 +13,7 @@ package com.netflix.conductor.core.execution; import java.time.Duration; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -31,14 +24,10 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; 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.common.run.Workflow.WorkflowStatus; import com.netflix.conductor.common.utils.ExternalPayloadStorage.Operation; import com.netflix.conductor.common.utils.ExternalPayloadStorage.PayloadType; import com.netflix.conductor.common.utils.TaskUtils; @@ -51,22 +40,19 @@ import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.google.common.annotations.VisibleForTesting; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.COMPLETED_WITH_ERRORS; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.IN_PROGRESS; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.SCHEDULED; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.SKIPPED; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.TIMED_OUT; import static com.netflix.conductor.common.metadata.tasks.TaskType.TERMINATE; +import static com.netflix.conductor.model.TaskModel.Status.*; /** * Decider evaluates the state of the workflow by inspecting the current state along with the * blueprint. The result of the evaluation is either to schedule further tasks, complete/fail the * workflow or do nothing. */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Service public class DeciderService { @@ -82,10 +68,10 @@ public class DeciderService { private final Map taskMappers; - private final Predicate isNonPendingTask = + private final Predicate isNonPendingTask = task -> !task.isRetried() && !task.getStatus().equals(SKIPPED) && !task.isExecuted(); - private final Predicate containsSuccessfulTerminateTask = + private final Predicate containsSuccessfulTerminateTask = workflow -> workflow.getTasks().stream() .anyMatch( @@ -110,19 +96,19 @@ public DeciderService( this.systemTaskRegistry = systemTaskRegistry; } - public DeciderOutcome decide(Workflow workflow) throws TerminateWorkflowException { + public DeciderOutcome decide(WorkflowModel workflow) throws TerminateWorkflowException { // In case of a new workflow the list of tasks will be empty. - final List tasks = workflow.getTasks(); + final List tasks = workflow.getTasks(); // Filter the list of tasks and include only tasks that are not executed, // not marked to be skipped and not ready for rerun. // For a new workflow, the list of unprocessedTasks will be empty - List unprocessedTasks = + List unprocessedTasks = tasks.stream() .filter(t -> !t.getStatus().equals(SKIPPED) && !t.isExecuted()) .collect(Collectors.toList()); - List tasksToBeScheduled = new LinkedList<>(); + List tasksToBeScheduled = new LinkedList<>(); if (unprocessedTasks.isEmpty()) { // this is the flow that the new workflow will go through tasksToBeScheduled = startWorkflow(workflow); @@ -133,7 +119,7 @@ public DeciderOutcome decide(Workflow workflow) throws TerminateWorkflowExceptio return decide(workflow, tasksToBeScheduled); } - private DeciderOutcome decide(final Workflow workflow, List preScheduledTasks) + private DeciderOutcome decide(final WorkflowModel workflow, List preScheduledTasks) throws TerminateWorkflowException { DeciderOutcome outcome = new DeciderOutcome(); @@ -149,7 +135,7 @@ private DeciderOutcome decide(final Workflow workflow, List preScheduledTa checkWorkflowTimeout(workflow); - if (workflow.getStatus().equals(WorkflowStatus.PAUSED)) { + if (workflow.getStatus().equals(WorkflowModel.Status.PAUSED)) { LOGGER.debug("Workflow " + workflow.getWorkflowId() + " is paused"); return outcome; } @@ -157,18 +143,18 @@ private DeciderOutcome decide(final Workflow workflow, List preScheduledTa // Filter the list of tasks and include only tasks that are not retried, not executed // marked to be skipped and not part of System tasks that is DECISION, FORK, JOIN // This list will be empty for a new workflow being started - List pendingTasks = + List pendingTasks = workflow.getTasks().stream().filter(isNonPendingTask).collect(Collectors.toList()); // Get all the tasks that have not completed their lifecycle yet // This list will be empty for a new workflow Set executedTaskRefNames = workflow.getTasks().stream() - .filter(Task::isExecuted) - .map(Task::getReferenceTaskName) + .filter(TaskModel::isExecuted) + .map(TaskModel::getReferenceTaskName) .collect(Collectors.toSet()); - Map tasksToBeScheduled = new LinkedHashMap<>(); + Map tasksToBeScheduled = new LinkedHashMap<>(); preScheduledTasks.forEach( preScheduledTask -> { @@ -177,7 +163,7 @@ private DeciderOutcome decide(final Workflow workflow, List preScheduledTa }); // A new workflow does not enter this code branch - for (Task pendingTask : pendingTasks) { + for (TaskModel pendingTask : pendingTasks) { if (systemTaskRegistry.isSystemTask(pendingTask.getTaskType()) && !pendingTask.getStatus().isTerminal()) { @@ -213,7 +199,7 @@ private DeciderOutcome decide(final Workflow workflow, List preScheduledTa .getTaskByRefName(pendingTask.getReferenceTaskName()); } - Optional retryTask = + Optional retryTask = retry(taskDefinition.orElse(null), workflowTask, pendingTask, workflow); if (retryTask.isPresent()) { tasksToBeScheduled.put(retryTask.get().getReferenceTaskName(), retryTask.get()); @@ -228,7 +214,7 @@ private DeciderOutcome decide(final Workflow workflow, List preScheduledTa && !pendingTask.isRetried() && pendingTask.getStatus().isTerminal()) { pendingTask.setExecuted(true); - List nextTasks = getNextTask(workflow, pendingTask); + List nextTasks = getNextTask(workflow, pendingTask); if (pendingTask.isLoopOverTask() && !TaskType.DO_WHILE.name().equals(pendingTask.getTaskType()) && !nextTasks.isEmpty()) { @@ -242,13 +228,15 @@ private DeciderOutcome decide(final Workflow workflow, List preScheduledTa LOGGER.debug( "Scheduling Tasks from {}, next = {} for workflowId: {}", pendingTask.getTaskDefName(), - nextTasks.stream().map(Task::getTaskDefName).collect(Collectors.toList()), + nextTasks.stream() + .map(TaskModel::getTaskDefName) + .collect(Collectors.toList()), workflow.getWorkflowId()); } } // All the tasks that need to scheduled are added to the outcome, in case of - List unScheduledTasks = + List unScheduledTasks = tasksToBeScheduled.values().stream() .filter(task -> !executedTaskRefNames.contains(task.getReferenceTaskName())) .collect(Collectors.toList()); @@ -256,7 +244,7 @@ private DeciderOutcome decide(final Workflow workflow, List preScheduledTa LOGGER.debug( "Scheduling Tasks: {} for workflow: {}", unScheduledTasks.stream() - .map(Task::getTaskDefName) + .map(TaskModel::getTaskDefName) .collect(Collectors.toList()), workflow.getWorkflowId()); outcome.tasksToBeScheduled.addAll(unScheduledTasks); @@ -271,7 +259,8 @@ private DeciderOutcome decide(final Workflow workflow, List preScheduledTa } @VisibleForTesting - List filterNextLoopOverTasks(List tasks, Task pendingTask, Workflow workflow) { + List filterNextLoopOverTasks( + List tasks, TaskModel pendingTask, WorkflowModel workflow) { // Update the task reference name and iteration tasks.forEach( @@ -286,9 +275,9 @@ List filterNextLoopOverTasks(List tasks, Task pendingTask, Workflow workflow.getTasks().stream() .filter( runningTask -> - runningTask.getStatus().equals(Status.IN_PROGRESS) + runningTask.getStatus().equals(TaskModel.Status.IN_PROGRESS) || runningTask.getStatus().isTerminal()) - .map(Task::getReferenceTaskName) + .map(TaskModel::getReferenceTaskName) .collect(Collectors.toList()); return tasks.stream() @@ -298,19 +287,20 @@ List filterNextLoopOverTasks(List tasks, Task pendingTask, Workflow .collect(Collectors.toList()); } - private List startWorkflow(Workflow workflow) throws TerminateWorkflowException { + private List startWorkflow(WorkflowModel workflow) + throws TerminateWorkflowException { final WorkflowDef workflowDef = workflow.getWorkflowDefinition(); LOGGER.debug("Starting workflow: {}", workflow); // The tasks will be empty in case of new workflow - List tasks = workflow.getTasks(); + List tasks = workflow.getTasks(); // Check if the workflow is a re-run case or if it is a new workflow execution if (workflow.getReRunFromWorkflowId() == null || tasks.isEmpty()) { if (workflowDef.getTasks().isEmpty()) { throw new TerminateWorkflowException( - "No tasks found to be executed", WorkflowStatus.COMPLETED); + "No tasks found to be executed", WorkflowModel.Status.COMPLETED); } WorkflowTask taskToSchedule = @@ -327,7 +317,7 @@ private List startWorkflow(Workflow workflow) throws TerminateWorkflowExce } // Get the first task to schedule - Task rerunFromTask = + TaskModel rerunFromTask = tasks.stream() .findFirst() .map( @@ -359,14 +349,14 @@ private List startWorkflow(Workflow workflow) throws TerminateWorkflowExce * last task in the workflow will be copied to workflow output of no output parameters are * specified in the workflow definition */ - void updateWorkflowOutput(final Workflow workflow, Task task) { - List allTasks = workflow.getTasks(); + void updateWorkflowOutput(final WorkflowModel workflow, TaskModel task) { + List allTasks = workflow.getTasks(); if (allTasks.isEmpty()) { return; } Map output = new HashMap<>(); - Optional optionalTask = + Optional optionalTask = allTasks.stream() .filter( t -> @@ -375,7 +365,7 @@ void updateWorkflowOutput(final Workflow workflow, Task task) { && t.getStatus().isSuccessful()) .findFirst(); if (optionalTask.isPresent()) { - Task terminateTask = optionalTask.get(); + TaskModel terminateTask = optionalTask.get(); if (StringUtils.isNotBlank(terminateTask.getExternalOutputPayloadStoragePath())) { output = externalPayloadStorageUtils.downloadPayload( @@ -388,14 +378,13 @@ void updateWorkflowOutput(final Workflow workflow, Task task) { output = terminateTask.getOutputData(); } } else { - Task last = Optional.ofNullable(task).orElse(allTasks.get(allTasks.size() - 1)); + TaskModel last = Optional.ofNullable(task).orElse(allTasks.get(allTasks.size() - 1)); WorkflowDef workflowDef = workflow.getWorkflowDefinition(); if (workflowDef.getOutputParameters() != null && !workflowDef.getOutputParameters().isEmpty()) { - Workflow workflowInstance = populateWorkflowAndTaskData(workflow); output = parametersUtils.getTaskInput( - workflowDef.getOutputParameters(), workflowInstance, null, null); + workflowDef.getOutputParameters(), workflow, null, null); } else if (StringUtils.isNotBlank(last.getExternalOutputPayloadStoragePath())) { output = externalPayloadStorageUtils.downloadPayload( @@ -409,12 +398,12 @@ void updateWorkflowOutput(final Workflow workflow, Task task) { } } workflow.setOutput(output); - externalizeWorkflowData(workflow); } @VisibleForTesting - boolean checkForWorkflowCompletion(final Workflow workflow) throws TerminateWorkflowException { - List allTasks = workflow.getTasks(); + boolean checkForWorkflowCompletion(final WorkflowModel workflow) + throws TerminateWorkflowException { + List allTasks = workflow.getTasks(); if (allTasks.isEmpty()) { return false; } @@ -423,7 +412,7 @@ boolean checkForWorkflowCompletion(final Workflow workflow) throws TerminateWork return true; } - Map taskStatusMap = new HashMap<>(); + Map taskStatusMap = new HashMap<>(); workflow.getTasks() .forEach(task -> taskStatusMap.put(task.getReferenceTaskName(), task.getStatus())); @@ -433,14 +422,15 @@ boolean checkForWorkflowCompletion(final Workflow workflow) throws TerminateWork .parallel() .allMatch( wftask -> { - Status status = + TaskModel.Status status = taskStatusMap.get(wftask.getTaskReferenceName()); return status != null && status.isSuccessful() && status.isTerminal(); }); - boolean noPendingTasks = taskStatusMap.values().stream().allMatch(Status::isTerminal); + boolean noPendingTasks = + taskStatusMap.values().stream().allMatch(TaskModel.Status::isTerminal); boolean noPendingSchedule = workflow.getTasks().stream() @@ -454,7 +444,7 @@ boolean checkForWorkflowCompletion(final Workflow workflow) throws TerminateWork return allCompletedSuccessfully && noPendingTasks && noPendingSchedule; } - List getNextTask(Workflow workflow, Task task) { + List getNextTask(WorkflowModel workflow, TaskModel task) { final WorkflowDef workflowDef = workflow.getWorkflowDefinition(); // Get the following task after the last completed task @@ -493,7 +483,7 @@ List getNextTask(Workflow workflow, Task task) { return Collections.emptyList(); } - private String getNextTasksToBeScheduled(Workflow workflow, Task task) { + private String getNextTasksToBeScheduled(WorkflowModel workflow, TaskModel task) { final WorkflowDef def = workflow.getWorkflowDefinition(); String taskReferenceName = task.getReferenceTaskName(); @@ -505,8 +495,11 @@ private String getNextTasksToBeScheduled(Workflow workflow, Task task) { } @VisibleForTesting - Optional retry( - TaskDef taskDefinition, WorkflowTask workflowTask, Task task, Workflow workflow) + Optional retry( + TaskDef taskDefinition, + WorkflowTask workflowTask, + TaskModel task, + WorkflowModel workflow) throws TerminateWorkflowException { int retryCount = task.getRetryCount(); @@ -527,16 +520,16 @@ Optional retry( if (workflowTask != null && workflowTask.isOptional()) { return Optional.empty(); } - WorkflowStatus status; + WorkflowModel.Status status; switch (task.getStatus()) { case CANCELED: - status = WorkflowStatus.TERMINATED; + status = WorkflowModel.Status.TERMINATED; break; case TIMED_OUT: - status = WorkflowStatus.TIMED_OUT; + status = WorkflowModel.Status.TIMED_OUT; break; default: - status = WorkflowStatus.FAILED; + status = WorkflowModel.Status.FAILED; break; } updateWorkflowOutput(workflow, task); @@ -572,7 +565,7 @@ Optional retry( task.setRetried(true); - Task rescheduled = task.copy(); + TaskModel rescheduled = task.copy(); rescheduled.setStartDelayInSeconds(startDelay); rescheduled.setCallbackAfterSeconds(startDelay); rescheduled.setRetryCount(task.getRetryCount() + 1); @@ -585,6 +578,11 @@ Optional retry( rescheduled.getInputData().putAll(task.getInputData()); rescheduled.setReasonForIncompletion(null); rescheduled.setSubWorkflowId(null); + rescheduled.setSeq(0); + rescheduled.setScheduledTime(0); + rescheduled.setStartTime(0); + rescheduled.setEndTime(0); + rescheduled.setWorkerId(null); if (StringUtils.isNotBlank(task.getExternalInputPayloadStoragePath())) { rescheduled.setExternalInputPayloadStoragePath( @@ -593,90 +591,20 @@ Optional retry( rescheduled.getInputData().putAll(task.getInputData()); } if (workflowTask != null && workflow.getWorkflowDefinition().getSchemaVersion() > 1) { - Workflow workflowInstance = populateWorkflowAndTaskData(workflow); Map taskInput = parametersUtils.getTaskInputV2( workflowTask.getInputParameters(), - workflowInstance, + workflow, rescheduled.getTaskId(), taskDefinition); rescheduled.getInputData().putAll(taskInput); } - externalizeTaskData(rescheduled); // for the schema version 1, we do not have to recompute the inputs return Optional.of(rescheduled); } - /** - * Populates the workflow input data and the tasks input/output data if stored in external - * payload storage. This method creates a deep copy of the workflow instance where the payloads - * will be stored after downloading from external payload storage. - * - * @param workflow the workflow for which the data needs to be populated - * @return a copy of the workflow with the payload data populated - */ - @VisibleForTesting - Workflow populateWorkflowAndTaskData(Workflow workflow) { - Workflow workflowInstance = workflow.copy(); - - if (StringUtils.isNotBlank(workflow.getExternalInputPayloadStoragePath())) { - // download the workflow input from external storage here and plug it into the workflow - Map workflowInputParams = - externalPayloadStorageUtils.downloadPayload( - workflow.getExternalInputPayloadStoragePath()); - Monitors.recordExternalPayloadStorageUsage( - workflow.getWorkflowName(), - Operation.READ.toString(), - PayloadType.WORKFLOW_INPUT.toString()); - workflowInstance.setInput(workflowInputParams); - workflowInstance.setExternalInputPayloadStoragePath(null); - } - - workflowInstance.getTasks().stream() - .filter( - task -> - StringUtils.isNotBlank(task.getExternalInputPayloadStoragePath()) - || StringUtils.isNotBlank( - task.getExternalOutputPayloadStoragePath())) - .forEach(this::populateTaskData); - return workflowInstance; - } - - void populateTaskData(Task task) { - if (StringUtils.isNotBlank(task.getExternalOutputPayloadStoragePath())) { - task.setOutputData( - externalPayloadStorageUtils.downloadPayload( - task.getExternalOutputPayloadStoragePath())); - Monitors.recordExternalPayloadStorageUsage( - task.getTaskDefName(), - Operation.READ.toString(), - PayloadType.TASK_OUTPUT.toString()); - task.setExternalOutputPayloadStoragePath(null); - } - if (StringUtils.isNotBlank(task.getExternalInputPayloadStoragePath())) { - task.setInputData( - externalPayloadStorageUtils.downloadPayload( - task.getExternalInputPayloadStoragePath())); - Monitors.recordExternalPayloadStorageUsage( - task.getTaskDefName(), - Operation.READ.toString(), - PayloadType.TASK_INPUT.toString()); - task.setExternalInputPayloadStoragePath(null); - } - } - - void externalizeTaskData(Task task) { - externalPayloadStorageUtils.verifyAndUpload(task, PayloadType.TASK_INPUT); - externalPayloadStorageUtils.verifyAndUpload(task, PayloadType.TASK_OUTPUT); - } - - void externalizeWorkflowData(Workflow workflow) { - externalPayloadStorageUtils.verifyAndUpload(workflow, PayloadType.WORKFLOW_INPUT); - externalPayloadStorageUtils.verifyAndUpload(workflow, PayloadType.WORKFLOW_OUTPUT); - } - @VisibleForTesting - void checkWorkflowTimeout(Workflow workflow) { + void checkWorkflowTimeout(WorkflowModel workflow) { WorkflowDef workflowDef = workflow.getWorkflowDefinition(); if (workflowDef == null) { LOGGER.warn("Missing workflow definition : {}", workflow.getWorkflowId()); @@ -691,7 +619,7 @@ void checkWorkflowTimeout(Workflow workflow) { long elapsedTime = workflow.getLastRetriedTime() > 0 ? now - workflow.getLastRetriedTime() - : now - workflow.getStartTime(); + : now - workflow.getCreateTime(); if (elapsedTime < timeout) { return; @@ -710,16 +638,16 @@ void checkWorkflowTimeout(Workflow workflow) { LOGGER.info(reason); Monitors.recordWorkflowTermination( workflow.getWorkflowName(), - WorkflowStatus.TIMED_OUT, + WorkflowModel.Status.TIMED_OUT, workflow.getOwnerApp()); return; case TIME_OUT_WF: - throw new TerminateWorkflowException(reason, WorkflowStatus.TIMED_OUT); + throw new TerminateWorkflowException(reason, WorkflowModel.Status.TIMED_OUT); } } @VisibleForTesting - void checkTaskTimeout(TaskDef taskDef, Task task) { + void checkTaskTimeout(TaskDef taskDef, TaskModel task) { if (taskDef == null) { LOGGER.warn( @@ -755,7 +683,7 @@ void checkTaskTimeout(TaskDef taskDef, Task task) { } @VisibleForTesting - void checkTaskPollTimeout(TaskDef taskDef, Task task) { + void checkTaskPollTimeout(TaskDef taskDef, TaskModel task) { if (taskDef == null) { LOGGER.warn( "Missing task definition for task:{}/{} in workflow:{}", @@ -789,7 +717,7 @@ void checkTaskPollTimeout(TaskDef taskDef, Task task) { timeoutTaskWithTimeoutPolicy(reason, taskDef, task); } - void timeoutTaskWithTimeoutPolicy(String reason, TaskDef taskDef, Task task) { + void timeoutTaskWithTimeoutPolicy(String reason, TaskDef taskDef, TaskModel task) { Monitors.recordTaskTimeout(task.getTaskDefName()); switch (taskDef.getTimeoutPolicy()) { @@ -803,12 +731,12 @@ void timeoutTaskWithTimeoutPolicy(String reason, TaskDef taskDef, Task task) { case TIME_OUT_WF: task.setStatus(TIMED_OUT); task.setReasonForIncompletion(reason); - throw new TerminateWorkflowException(reason, WorkflowStatus.TIMED_OUT, task); + throw new TerminateWorkflowException(reason, WorkflowModel.Status.TIMED_OUT, task); } } @VisibleForTesting - boolean isResponseTimedOut(TaskDef taskDefinition, Task task) { + boolean isResponseTimedOut(TaskDef taskDefinition, TaskModel task) { if (taskDefinition == null) { LOGGER.warn( "missing task type : {}, workflowId= {}", @@ -866,7 +794,7 @@ boolean isResponseTimedOut(TaskDef taskDefinition, Task task) { return true; } - private void timeoutTask(TaskDef taskDef, Task task) { + private void timeoutTask(TaskDef taskDef, TaskModel task) { String reason = "responseTimeout: " + taskDef.getResponseTimeoutSeconds() @@ -879,14 +807,16 @@ private void timeoutTask(TaskDef taskDef, Task task) { task.setReasonForIncompletion(reason); } - public List getTasksToBeScheduled( - Workflow workflow, WorkflowTask taskToSchedule, int retryCount) { + public List getTasksToBeScheduled( + WorkflowModel workflow, WorkflowTask taskToSchedule, int retryCount) { return getTasksToBeScheduled(workflow, taskToSchedule, retryCount, null); } - public List getTasksToBeScheduled( - Workflow workflow, WorkflowTask taskToSchedule, int retryCount, String retriedTaskId) { - workflow = populateWorkflowAndTaskData(workflow); + public List getTasksToBeScheduled( + WorkflowModel workflow, + WorkflowTask taskToSchedule, + int retryCount, + String retriedTaskId) { Map input = parametersUtils.getTaskInput( taskToSchedule.getInputParameters(), workflow, null, null); @@ -899,9 +829,9 @@ public List getTasksToBeScheduled( workflow.getTasks().stream() .filter( runningTask -> - runningTask.getStatus().equals(Status.IN_PROGRESS) + runningTask.getStatus().equals(TaskModel.Status.IN_PROGRESS) || runningTask.getStatus().isTerminal()) - .map(Task::getReferenceTaskName) + .map(TaskModel::getReferenceTaskName) .collect(Collectors.toList()); String taskId = IDGenerator.generate(); @@ -918,24 +848,21 @@ public List getTasksToBeScheduled( .withDeciderService(this) .build(); - // for static forks, each branch of the fork creates a join task upon completion - // for dynamic forks, a join task is created with the fork and also with each branch of the - // fork - // a new task must only be scheduled if a task with the same reference name is not already + // For static forks, each branch of the fork creates a join task upon completion for + // dynamic forks, a join task is created with the fork and also with each branch of the + // fork. + // A new task must only be scheduled if a task, with the same reference name is not already // in this workflow instance - List tasks = - taskMappers.get(taskType).getMappedTasks(taskMapperContext).stream() - .filter(task -> !tasksInWorkflow.contains(task.getReferenceTaskName())) - .collect(Collectors.toList()); - tasks.forEach(this::externalizeTaskData); - return tasks; + return taskMappers.get(taskType).getMappedTasks(taskMapperContext).stream() + .filter(task -> !tasksInWorkflow.contains(task.getReferenceTaskName())) + .collect(Collectors.toList()); } - private boolean isTaskSkipped(WorkflowTask taskToSchedule, Workflow workflow) { + private boolean isTaskSkipped(WorkflowTask taskToSchedule, WorkflowModel workflow) { try { boolean isTaskSkipped = false; if (taskToSchedule != null) { - Task t = workflow.getTaskByRefName(taskToSchedule.getTaskReferenceName()); + TaskModel t = workflow.getTaskByRefName(taskToSchedule.getTaskReferenceName()); if (t == null) { isTaskSkipped = false; } else if (t.getStatus().equals(SKIPPED)) { @@ -948,15 +875,15 @@ private boolean isTaskSkipped(WorkflowTask taskToSchedule, Workflow workflow) { } } - private boolean isAyncCompleteSystemTask(Task task) { + private boolean isAyncCompleteSystemTask(TaskModel task) { return systemTaskRegistry.isSystemTask(task.getTaskType()) && systemTaskRegistry.get(task.getTaskType()).isAsyncComplete(task); } public static class DeciderOutcome { - List tasksToBeScheduled = new LinkedList<>(); - List tasksToBeUpdated = new LinkedList<>(); + List tasksToBeScheduled = new LinkedList<>(); + List tasksToBeUpdated = new LinkedList<>(); boolean isComplete; private DeciderOutcome() {} diff --git a/core/src/main/java/com/netflix/conductor/core/execution/WorkflowExecutor.java b/core/src/main/java/com/netflix/conductor/core/execution/WorkflowExecutor.java index 7ef9cd50ce..711eac10f4 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/WorkflowExecutor.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/WorkflowExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,16 +12,7 @@ */ package com.netflix.conductor.core.execution; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; +import java.util.*; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -31,23 +22,17 @@ import org.springframework.stereotype.Component; import com.netflix.conductor.annotations.Trace; -import com.netflix.conductor.common.metadata.tasks.PollData; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.metadata.tasks.TaskExecLog; -import com.netflix.conductor.common.metadata.tasks.TaskResult; -import com.netflix.conductor.common.metadata.tasks.TaskResult.Status; -import com.netflix.conductor.common.metadata.tasks.TaskType; +import com.netflix.conductor.common.metadata.tasks.*; import com.netflix.conductor.common.metadata.workflow.RerunWorkflowRequest; import com.netflix.conductor.common.metadata.workflow.SkipTaskRequest; 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.common.run.Workflow.WorkflowStatus; import com.netflix.conductor.common.utils.RetryUtil; import com.netflix.conductor.common.utils.TaskUtils; import com.netflix.conductor.core.WorkflowContext; import com.netflix.conductor.core.config.ConductorProperties; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.exception.ApplicationException.Code; import com.netflix.conductor.core.exception.TerminateWorkflowException; @@ -56,33 +41,22 @@ import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; import com.netflix.conductor.core.listener.WorkflowStatusListener; import com.netflix.conductor.core.metadata.MetadataMapperService; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.core.utils.QueueUtils; +import com.netflix.conductor.core.utils.Utils; import com.netflix.conductor.dao.MetadataDAO; import com.netflix.conductor.dao.QueueDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.service.ExecutionLockService; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.CANCELED; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.FAILED; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.FAILED_WITH_TERMINAL_ERROR; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.IN_PROGRESS; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.SCHEDULED; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.SKIPPED; -import static com.netflix.conductor.common.metadata.tasks.Task.Status.valueOf; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_FORK_JOIN_DYNAMIC; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_JOIN; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_SUB_WORKFLOW; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TERMINATE; -import static com.netflix.conductor.core.exception.ApplicationException.Code.BACKEND_ERROR; -import static com.netflix.conductor.core.exception.ApplicationException.Code.CONFLICT; -import static com.netflix.conductor.core.exception.ApplicationException.Code.INVALID_INPUT; -import static com.netflix.conductor.core.exception.ApplicationException.Code.NOT_FOUND; +import static com.netflix.conductor.core.exception.ApplicationException.Code.*; +import static com.netflix.conductor.model.TaskModel.Status.*; /** Workflow services provider interface */ @Trace @@ -103,23 +77,23 @@ public class WorkflowExecutor { private final SystemTaskRegistry systemTaskRegistry; private long activeWorkerLastPollMs; - public static final String DECIDER_QUEUE = "_deciderQueue"; private static final String CLASS_NAME = WorkflowExecutor.class.getSimpleName(); private final ExecutionLockService executionLockService; - private static final Predicate UNSUCCESSFUL_TERMINAL_TASK = + private static final Predicate UNSUCCESSFUL_TERMINAL_TASK = task -> !task.getStatus().isSuccessful() && task.getStatus().isTerminal(); - private static final Predicate UNSUCCESSFUL_JOIN_TASK = - UNSUCCESSFUL_TERMINAL_TASK.and(t -> TASK_TYPE_JOIN.equals(t.getTaskType())); + private static final Predicate UNSUCCESSFUL_JOIN_TASK = + UNSUCCESSFUL_TERMINAL_TASK.and(t -> TaskType.TASK_TYPE_JOIN.equals(t.getTaskType())); + + private static final Predicate NON_TERMINAL_TASK = + task -> !task.getStatus().isTerminal(); private final Predicate validateLastPolledTime = pollData -> pollData.getLastPollTime() > System.currentTimeMillis() - activeWorkerLastPollMs; - private static final Predicate NON_TERMINAL_TASK = task -> !task.getStatus().isTerminal(); - public WorkflowExecutor( DeciderService deciderService, MetadataDAO metadataDAO, @@ -390,18 +364,18 @@ public String startWorkflow( String workflowId = IDGenerator.generate(); // Persist the Workflow - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId(workflowId); workflow.setCorrelationId(correlationId); workflow.setPriority(priority == null ? 0 : priority); workflow.setWorkflowDefinition(workflowDefinition); - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflow.setParentWorkflowId(parentWorkflowId); workflow.setParentWorkflowTaskId(parentWorkflowTaskId); workflow.setOwnerApp(WorkflowContext.get().getClientApp()); workflow.setCreateTime(System.currentTimeMillis()); workflow.setUpdatedBy(null); - workflow.setUpdateTime(null); + workflow.setUpdatedTime(null); workflow.setEvent(event); workflow.setTaskToDomain(taskToDomain); workflow.setVariables(workflowDefinition.getVariables()); @@ -410,7 +384,6 @@ public String startWorkflow( Map parsedInput = parametersUtils.getWorkflowInput(workflowDefinition, workflowInput); workflow.setInput(parsedInput); - deciderService.externalizeWorkflowData(workflow); } else { workflow.setExternalInputPayloadStoragePath(externalInputPayloadStoragePath); } @@ -430,8 +403,7 @@ public String startWorkflow( LOGGER.error("Unable to start workflow: {}", workflowDefinition.getName(), e); // It's possible the remove workflow call hits an exception as well, in that case we - // want to log both - // errors to help diagnosis. + // want to log both errors to help diagnosis. try { executionDAOFacade.removeWorkflow(workflowId, false); } catch (Exception rwe) { @@ -445,7 +417,7 @@ public String startWorkflow( * Acquire and hold the lock till the workflow creation action is completed (in primary and secondary datastores). * This is to ensure that workflow creation action precedes any other action on a given workflow. */ - private void createWorkflow(Workflow workflow) { + private void createWorkflow(WorkflowModel workflow) { if (!executionLockService.acquireLock(workflow.getWorkflowId())) { throw new ApplicationException( BACKEND_ERROR, "Error acquiring lock when creating workflow: {}"); @@ -490,7 +462,7 @@ private void validateWorkflow( * @throws ApplicationException if the workflow is in terminal state */ public void resetCallbacksForWorkflow(String workflowId) { - Workflow workflow = executionDAOFacade.getWorkflowById(workflowId, true); + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true); if (workflow.getStatus().isTerminal()) { throw new ApplicationException( CONFLICT, "Workflow is in terminal state. Status =" + workflow.getStatus()); @@ -541,7 +513,7 @@ public String rerun(RerunWorkflowRequest request) { * */ public void restart(String workflowId, boolean useLatestDefinitions) { - Workflow workflow = executionDAOFacade.getWorkflowById(workflowId, true); + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true); if (!workflow.getStatus().isTerminal()) { String errorMsg = String.format( @@ -584,7 +556,7 @@ public void restart(String workflowId, boolean useLatestDefinitions) { if (!workflowDef.isRestartable() && workflow.getStatus() .equals( - WorkflowStatus + WorkflowModel.Status .COMPLETED)) { // Can only restart non-completed workflows // when the configuration is set to false throw new ApplicationException( @@ -596,11 +568,11 @@ public void restart(String workflowId, boolean useLatestDefinitions) { workflow.getTasks().clear(); workflow.setReasonForIncompletion(null); - workflow.setStartTime(System.currentTimeMillis()); + workflow.setCreateTime(System.currentTimeMillis()); workflow.setEndTime(0); workflow.setLastRetriedTime(0); // Change the status to running - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflow.setOutput(null); workflow.setExternalOutputPayloadStoragePath(null); @@ -627,7 +599,7 @@ public void restart(String workflowId, boolean useLatestDefinitions) { * @param workflowId the id of the workflow to be retried */ public void retry(String workflowId, boolean resumeSubworkflowTasks) { - Workflow workflow = executionDAOFacade.getWorkflowById(workflowId, true); + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true); if (!workflow.getStatus().isTerminal()) { throw new ApplicationException( CONFLICT, "Workflow is still running. status=" + workflow.getStatus()); @@ -637,7 +609,7 @@ public void retry(String workflowId, boolean resumeSubworkflowTasks) { } if (resumeSubworkflowTasks) { - Optional taskToRetry = + Optional taskToRetry = workflow.getTasks().stream().filter(UNSUCCESSFUL_TERMINAL_TASK).findFirst(); if (taskToRetry.isPresent()) { workflow = findLastFailedSubWorkflowIfAny(taskToRetry.get(), workflow); @@ -650,12 +622,12 @@ public void retry(String workflowId, boolean resumeSubworkflowTasks) { } } - private void updateAndPushParents(Workflow workflow, String operation) { + private void updateAndPushParents(WorkflowModel workflow, String operation) { String workflowIdentifier = ""; while (workflow.hasParent()) { // update parent's sub workflow task - Task subWorkflowTask = - executionDAOFacade.getTaskById(workflow.getParentWorkflowTaskId()); + TaskModel subWorkflowTask = + executionDAOFacade.getTaskModel(workflow.getParentWorkflowTaskId()); subWorkflowTask.setSubworkflowChanged(true); subWorkflowTask.setStatus(IN_PROGRESS); executionDAOFacade.updateTask(subWorkflowTask); @@ -676,8 +648,9 @@ private void updateAndPushParents(Workflow workflow, String operation) { // push the parent workflow to decider queue for asynchronous 'decide' String parentWorkflowId = workflow.getParentWorkflowId(); - Workflow parentWorkflow = executionDAOFacade.getWorkflowById(parentWorkflowId, true); - parentWorkflow.setStatus(WorkflowStatus.RUNNING); + WorkflowModel parentWorkflow = + executionDAOFacade.getWorkflowModel(parentWorkflowId, true); + parentWorkflow.setStatus(WorkflowModel.Status.RUNNING); parentWorkflow.setLastRetriedTime(System.currentTimeMillis()); executionDAOFacade.updateWorkflow(parentWorkflow); pushParentWorkflow(parentWorkflowId); @@ -686,14 +659,14 @@ private void updateAndPushParents(Workflow workflow, String operation) { } } - private void retry(Workflow workflow) { + private void retry(WorkflowModel workflow) { // Get all FAILED or CANCELED tasks that are not COMPLETED (or reach other terminal states) // on further executions. // // Eg: for Seq of tasks task1.CANCELED, task1.COMPLETED, task1 shouldn't be retried. // Throw an exception if there are no FAILED tasks. // Handle JOIN task CANCELED status as special case. - Map retriableMap = new HashMap<>(); - for (Task task : workflow.getTasks()) { + Map retriableMap = new HashMap<>(); + for (TaskModel task : workflow.getTasks()) { switch (task.getStatus()) { case FAILED: case FAILED_WITH_TERMINAL_ERROR: @@ -718,7 +691,8 @@ private void retry(Workflow workflow) { // if workflow TIMED_OUT due to timeoutSeconds configured in the workflow definition, // it may not have any unsuccessful tasks that can be retried - if (retriableMap.values().size() == 0 && workflow.getStatus() != WorkflowStatus.TIMED_OUT) { + if (retriableMap.values().size() == 0 + && workflow.getStatus() != WorkflowModel.Status.TIMED_OUT) { throw new ApplicationException( CONFLICT, "There are no retryable tasks! Use restart if you want to attempt entire workflow execution again."); @@ -726,11 +700,11 @@ private void retry(Workflow workflow) { // Update Workflow with new status. // This should load Workflow from archive, if archived. - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflow.setLastRetriedTime(System.currentTimeMillis()); // Add to decider queue queueDAO.push( - DECIDER_QUEUE, + Utils.DECIDER_QUEUE, workflow.getWorkflowId(), workflow.getPriority(), properties.getWorkflowOffsetTimeout().getSeconds()); @@ -738,10 +712,10 @@ private void retry(Workflow workflow) { // taskToBeRescheduled would set task `retried` to true, and hence it's important to // updateTasks after obtaining task copy from taskToBeRescheduled. - final Workflow finalWorkflow = workflow; - List retriableTasks = + final WorkflowModel finalWorkflow = workflow; + List retriableTasks = retriableMap.values().stream() - .sorted(Comparator.comparingInt(Task::getSeq)) + .sorted(Comparator.comparingInt(TaskModel::getSeq)) .map(task -> taskToBeRescheduled(finalWorkflow, task)) .collect(Collectors.toList()); @@ -752,12 +726,13 @@ private void retry(Workflow workflow) { scheduleTask(workflow, retriableTasks); } - private Workflow findLastFailedSubWorkflowIfAny(Task task, Workflow parentWorkflow) { - if (TASK_TYPE_SUB_WORKFLOW.equals(task.getTaskType()) + private WorkflowModel findLastFailedSubWorkflowIfAny( + TaskModel task, WorkflowModel parentWorkflow) { + if (TaskType.TASK_TYPE_SUB_WORKFLOW.equals(task.getTaskType()) && UNSUCCESSFUL_TERMINAL_TASK.test(task)) { - Workflow subWorkflow = - executionDAOFacade.getWorkflowById(task.getSubWorkflowId(), true); - Optional taskToRetry = + WorkflowModel subWorkflow = + executionDAOFacade.getWorkflowModel(task.getSubWorkflowId(), true); + Optional taskToRetry = subWorkflow.getTasks().stream().filter(UNSUCCESSFUL_TERMINAL_TASK).findFirst(); if (taskToRetry.isPresent()) { return findLastFailedSubWorkflowIfAny(taskToRetry.get(), subWorkflow); @@ -772,8 +747,8 @@ private Workflow findLastFailedSubWorkflowIfAny(Task task, Workflow parentWorkfl * @param task failed or cancelled task * @return new instance of a task with "SCHEDULED" status */ - private Task taskToBeRescheduled(Workflow workflow, Task task) { - Task taskToBeRetried = task.copy(); + private TaskModel taskToBeRescheduled(WorkflowModel workflow, TaskModel task) { + TaskModel taskToBeRetried = task.copy(); taskToBeRetried.setTaskId(IDGenerator.generate()); taskToBeRetried.setRetriedTaskId(task.getTaskId()); taskToBeRetried.setStatus(SCHEDULED); @@ -782,7 +757,12 @@ private Task taskToBeRescheduled(Workflow workflow, Task task) { taskToBeRetried.setPollCount(0); taskToBeRetried.setCallbackAfterSeconds(0); taskToBeRetried.setSubWorkflowId(null); + taskToBeRetried.setScheduledTime(0); + taskToBeRetried.setStartTime(0); + taskToBeRetried.setEndTime(0); + taskToBeRetried.setWorkerId(null); taskToBeRetried.setReasonForIncompletion(null); + taskToBeRetried.setSeq(0); // perform parameter replacement for retried task Map taskInput = @@ -800,21 +780,12 @@ private Task taskToBeRescheduled(Workflow workflow, Task task) { return taskToBeRetried; } - public Task getPendingTaskByWorkflow(String taskReferenceName, String workflowId) { - return executionDAOFacade.getTasksForWorkflow(workflowId).stream() - .filter(NON_TERMINAL_TASK) - .filter(task -> task.getReferenceTaskName().equals(taskReferenceName)) - .findFirst() // There can only be one task by a given reference name running at a - // time. - .orElse(null); - } - - private void endExecution(Workflow workflow) { - Optional terminateTask = + private void endExecution(WorkflowModel workflow) { + Optional terminateTask = workflow.getTasks().stream() .filter( t -> - TERMINATE.name().equals(t.getTaskType()) + TaskType.TERMINATE.name().equals(t.getTaskType()) && t.getStatus().isTerminal() && t.getStatus().isSuccessful()) .findFirst(); @@ -830,8 +801,8 @@ private void endExecution(Workflow workflow) { String.format( "Workflow is %s by TERMINATE task: %s", terminationStatus, terminateTask.get().getTaskId()); - if (WorkflowStatus.FAILED.name().equals(terminationStatus)) { - workflow.setStatus(WorkflowStatus.FAILED); + if (WorkflowModel.Status.FAILED.name().equals(terminationStatus)) { + workflow.setStatus(WorkflowModel.Status.FAILED); workflow = terminate(workflow, new TerminateWorkflowException(reason)); } else { workflow.setReasonForIncompletion(reason); @@ -848,11 +819,12 @@ private void endExecution(Workflow workflow) { * @throws ApplicationException if workflow is not in terminal state */ @VisibleForTesting - Workflow completeWorkflow(Workflow workflow) { + WorkflowModel completeWorkflow(WorkflowModel workflow) { LOGGER.debug("Completing workflow execution for {}", workflow.getWorkflowId()); - if (workflow.getStatus().equals(WorkflowStatus.COMPLETED)) { - queueDAO.remove(DECIDER_QUEUE, workflow.getWorkflowId()); // remove from the sweep queue + if (workflow.getStatus().equals(WorkflowModel.Status.COMPLETED)) { + queueDAO.remove( + Utils.DECIDER_QUEUE, workflow.getWorkflowId()); // remove from the sweep queue executionDAOFacade.removeFromPendingWorkflow( workflow.getWorkflowName(), workflow.getWorkflowId()); LOGGER.debug("Workflow: {} has already been completed.", workflow.getWorkflowId()); @@ -873,7 +845,7 @@ Workflow completeWorkflow(Workflow workflow) { } deciderService.updateWorkflowOutput(workflow, null); - workflow.setStatus(WorkflowStatus.COMPLETED); + workflow.setStatus(WorkflowModel.Status.COMPLETED); workflow.setTasks(workflow.getTasks()); workflow.setOutput(workflow.getOutput()); workflow.setReasonForIncompletion(workflow.getReasonForIncompletion()); @@ -889,7 +861,7 @@ Workflow completeWorkflow(Workflow workflow) { FAILED.equals(t.getStatus()) || FAILED_WITH_TERMINAL_ERROR.equals( t.getStatus())) - .map(Task::getReferenceTaskName) + .map(TaskModel::getReferenceTaskName) .collect(Collectors.toSet())); executionDAOFacade.updateWorkflow(workflow); @@ -897,7 +869,7 @@ Workflow completeWorkflow(Workflow workflow) { workflowStatusListener.onWorkflowCompletedIfEnabled(workflow); Monitors.recordWorkflowCompletion( workflow.getWorkflowName(), - workflow.getEndTime() - workflow.getStartTime(), + workflow.getEndTime() - workflow.getCreateTime(), workflow.getOwnerApp()); if (workflow.hasParent()) { @@ -916,11 +888,11 @@ Workflow completeWorkflow(Workflow workflow) { } public void terminateWorkflow(String workflowId, String reason) { - Workflow workflow = executionDAOFacade.getWorkflowById(workflowId, true); - if (WorkflowStatus.COMPLETED.equals(workflow.getStatus())) { + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true); + if (WorkflowModel.Status.COMPLETED.equals(workflow.getStatus())) { throw new ApplicationException(CONFLICT, "Cannot terminate a COMPLETED workflow."); } - workflow.setStatus(WorkflowStatus.TERMINATED); + workflow.setStatus(WorkflowModel.Status.TERMINATED); terminateWorkflow(workflow, reason, null); } @@ -930,12 +902,13 @@ public void terminateWorkflow(String workflowId, String reason) { * @param failureWorkflow the failure workflow (if any) to be triggered as a result of this * termination */ - public Workflow terminateWorkflow(Workflow workflow, String reason, String failureWorkflow) { + public WorkflowModel terminateWorkflow( + WorkflowModel workflow, String reason, String failureWorkflow) { try { executionLockService.acquireLock(workflow.getWorkflowId(), 60000); if (!workflow.getStatus().isTerminal()) { - workflow.setStatus(WorkflowStatus.TERMINATED); + workflow.setStatus(WorkflowModel.Status.TERMINATED); } // FIXME Backwards compatibility for legacy workflows already running. @@ -964,7 +937,7 @@ public Workflow terminateWorkflow(Workflow workflow, String reason, String failu FAILED.equals(t.getStatus()) || FAILED_WITH_TERMINAL_ERROR.equals( t.getStatus())) - .map(Task::getReferenceTaskName) + .map(TaskModel::getReferenceTaskName) .collect(Collectors.toSet())); String workflowId = workflow.getWorkflowId(); @@ -974,7 +947,7 @@ public Workflow terminateWorkflow(Workflow workflow, String reason, String failu Monitors.recordWorkflowTermination( workflow.getWorkflowName(), workflow.getStatus(), workflow.getOwnerApp()); - List tasks = workflow.getTasks(); + List tasks = workflow.getTasks(); try { // Remove from the task queue if they were there tasks.forEach( @@ -1065,7 +1038,7 @@ public void updateTask(TaskResult taskResult) { } String workflowId = taskResult.getWorkflowInstanceId(); - Workflow workflowInstance = executionDAOFacade.getWorkflowById(workflowId, true); + WorkflowModel workflowInstance = executionDAOFacade.getWorkflowModel(workflowId, true); // FIXME Backwards compatibility for legacy workflows already running. // This code will be removed in a future version. @@ -1074,8 +1047,8 @@ public void updateTask(TaskResult taskResult) { metadataMapperService.populateWorkflowWithDefinitions(workflowInstance); } - Task task = - Optional.ofNullable(executionDAOFacade.getTaskById(taskResult.getTaskId())) + TaskModel task = + Optional.ofNullable(executionDAOFacade.getTaskModel(taskResult.getTaskId())) .orElseThrow( () -> new ApplicationException( @@ -1120,10 +1093,10 @@ public void updateTask(TaskResult taskResult) { // undesirable // for worker tasks, set status to SCHEDULED and push to the queue if (!systemTaskRegistry.isSystemTask(task.getTaskType()) - && taskResult.getStatus() == Status.IN_PROGRESS) { + && taskResult.getStatus() == TaskResult.Status.IN_PROGRESS) { task.setStatus(SCHEDULED); } else { - task.setStatus(valueOf(taskResult.getStatus().name())); + task.setStatus(TaskModel.Status.valueOf(taskResult.getStatus().name())); } task.setOutputMessage(taskResult.getOutputMessage()); task.setReasonForIncompletion(taskResult.getReasonForIncompletion()); @@ -1132,9 +1105,7 @@ public void updateTask(TaskResult taskResult) { task.setOutputData(taskResult.getOutputData()); task.setSubWorkflowId(taskResult.getSubWorkflowId()); - if (task.getOutputData() != null && !task.getOutputData().isEmpty()) { - deciderService.externalizeTaskData(task); - } else { + if (StringUtils.isNotBlank(taskResult.getExternalOutputPayloadStoragePath())) { task.setExternalOutputPayloadStoragePath( taskResult.getExternalOutputPayloadStoragePath()); } @@ -1256,8 +1227,8 @@ public void updateTask(TaskResult taskResult) { decide(workflowId); } - public Task getTask(String taskId) { - return Optional.ofNullable(executionDAOFacade.getTaskById(taskId)) + public TaskModel getTask(String taskId) { + return Optional.ofNullable(executionDAOFacade.getTaskModel(taskId)) .map( task -> { if (task.getWorkflowTask() != null) { @@ -1268,18 +1239,12 @@ public Task getTask(String taskId) { .orElse(null); } - public List getTasks(String taskType, String startKey, int count) { - return executionDAOFacade.getTasksByName(taskType, startKey, count); - } - public List getRunningWorkflows(String workflowName, int version) { return executionDAOFacade.getPendingWorkflowsByName(workflowName, version); } public List getWorkflows(String name, Integer version, Long startTime, Long endTime) { - List workflowsByType = - executionDAOFacade.getWorkflowsByName(name, startTime, endTime); - return workflowsByType.stream() + return executionDAOFacade.getWorkflowsByName(name, startTime, endTime).stream() .filter(workflow -> workflow.getWorkflowVersion() == version) .map(Workflow::getWorkflowId) .collect(Collectors.toList()); @@ -1300,7 +1265,7 @@ public boolean decide(String workflowId) { } // If it is a new workflow, the tasks will be still empty even though include tasks is true - Workflow workflow = executionDAOFacade.getWorkflowById(workflowId, true); + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true); // FIXME Backwards compatibility for legacy workflows already running. // This code will be removed in a future version. @@ -1324,26 +1289,23 @@ public boolean decide(String workflowId) { return true; } - List tasksToBeScheduled = outcome.tasksToBeScheduled; + List tasksToBeScheduled = outcome.tasksToBeScheduled; setTaskDomains(tasksToBeScheduled, workflow); - List tasksToBeUpdated = outcome.tasksToBeUpdated; + List tasksToBeUpdated = outcome.tasksToBeUpdated; boolean stateChanged = false; tasksToBeScheduled = dedupAndAddTasks(workflow, tasksToBeScheduled); - Workflow workflowInstance = deciderService.populateWorkflowAndTaskData(workflow); - for (Task task : outcome.tasksToBeScheduled) { + for (TaskModel task : outcome.tasksToBeScheduled) { if (systemTaskRegistry.isSystemTask(task.getTaskType()) && NON_TERMINAL_TASK.test(task)) { WorkflowSystemTask workflowSystemTask = systemTaskRegistry.get(task.getTaskType()); - deciderService.populateTaskData(task); if (!workflowSystemTask.isAsync() - && workflowSystemTask.execute(workflowInstance, task, this)) { + && workflowSystemTask.execute(workflow, task, this)) { tasksToBeUpdated.add(task); stateChanged = true; } - deciderService.externalizeTaskData(task); } } @@ -1371,29 +1333,30 @@ public boolean decide(String workflowId) { return false; } - private void adjustStateIfSubWorkflowChanged(Workflow workflow) { - Optional changedSubWorkflowTask = findChangedSubWorkflowTask(workflow); + private void adjustStateIfSubWorkflowChanged(WorkflowModel workflow) { + Optional changedSubWorkflowTask = findChangedSubWorkflowTask(workflow); if (changedSubWorkflowTask.isPresent()) { // reset the flag - Task subWorkflowTask = changedSubWorkflowTask.get(); + TaskModel subWorkflowTask = changedSubWorkflowTask.get(); subWorkflowTask.setSubworkflowChanged(false); executionDAOFacade.updateTask(subWorkflowTask); // find all terminal and unsuccessful JOIN tasks and set them to IN_PROGRESS - if (workflow.getWorkflowDefinition().containsType(TASK_TYPE_JOIN) - || workflow.getWorkflowDefinition().containsType(TASK_TYPE_FORK_JOIN_DYNAMIC)) { + if (workflow.getWorkflowDefinition().containsType(TaskType.TASK_TYPE_JOIN) + || workflow.getWorkflowDefinition() + .containsType(TaskType.TASK_TYPE_FORK_JOIN_DYNAMIC)) { // if we are here, then the SUB_WORKFLOW task could be part of a FORK_JOIN or // FORK_JOIN_DYNAMIC // and the JOIN task(s) needs to be evaluated again, set them to IN_PROGRESS workflow.getTasks().stream() .filter(UNSUCCESSFUL_JOIN_TASK) - .peek(t -> t.setStatus(Task.Status.IN_PROGRESS)) + .peek(t -> t.setStatus(TaskModel.Status.IN_PROGRESS)) .forEach(executionDAOFacade::updateTask); } } } - private Optional findChangedSubWorkflowTask(Workflow workflow) { + private Optional findChangedSubWorkflowTask(WorkflowModel workflow) { WorkflowDef workflowDef = Optional.ofNullable(workflow.getWorkflowDefinition()) .orElseGet( @@ -1407,12 +1370,13 @@ private Optional findChangedSubWorkflowTask(Workflow workflow) { new ApplicationException( BACKEND_ERROR, "Workflow Definition is not found"))); - if (workflowDef.containsType(TASK_TYPE_SUB_WORKFLOW) - || workflow.getWorkflowDefinition().containsType(TASK_TYPE_FORK_JOIN_DYNAMIC)) { + if (workflowDef.containsType(TaskType.TASK_TYPE_SUB_WORKFLOW) + || workflow.getWorkflowDefinition() + .containsType(TaskType.TASK_TYPE_FORK_JOIN_DYNAMIC)) { return workflow.getTasks().stream() .filter( t -> - t.getTaskType().equals(TASK_TYPE_SUB_WORKFLOW) + t.getTaskType().equals(TaskType.TASK_TYPE_SUB_WORKFLOW) && t.isSubworkflowChanged() && !t.isRetried()) .findFirst(); @@ -1421,10 +1385,10 @@ private Optional findChangedSubWorkflowTask(Workflow workflow) { } @VisibleForTesting - List cancelNonTerminalTasks(Workflow workflow) { + List cancelNonTerminalTasks(WorkflowModel workflow) { List erroredTasks = new ArrayList<>(); // Update non-terminal tasks' status to CANCELED - for (Task task : workflow.getTasks()) { + for (TaskModel task : workflow.getTasks()) { if (!task.getStatus().isTerminal()) { // Cancel the ones which are not completed yet.... task.setStatus(CANCELED); @@ -1449,7 +1413,7 @@ List cancelNonTerminalTasks(Workflow workflow) { if (erroredTasks.isEmpty()) { try { workflowStatusListener.onWorkflowFinalizedIfEnabled(workflow); - queueDAO.remove(DECIDER_QUEUE, workflow.getWorkflowId()); + queueDAO.remove(Utils.DECIDER_QUEUE, workflow.getWorkflowId()); } catch (Exception e) { LOGGER.error( "Error removing workflow: {} from decider queue", @@ -1461,13 +1425,13 @@ List cancelNonTerminalTasks(Workflow workflow) { } @VisibleForTesting - List dedupAndAddTasks(Workflow workflow, List tasks) { + List dedupAndAddTasks(WorkflowModel workflow, List tasks) { List tasksInWorkflow = workflow.getTasks().stream() .map(task -> task.getReferenceTaskName() + "_" + task.getRetryCount()) .collect(Collectors.toList()); - List dedupedTasks = + List dedupedTasks = tasks.stream() .filter( task -> @@ -1485,8 +1449,8 @@ List dedupAndAddTasks(Workflow workflow, List tasks) { public void pauseWorkflow(String workflowId) { try { executionLockService.acquireLock(workflowId, 60000); - WorkflowStatus status = WorkflowStatus.PAUSED; - Workflow workflow = executionDAOFacade.getWorkflowById(workflowId, false); + WorkflowModel.Status status = WorkflowModel.Status.PAUSED; + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, false); if (workflow.getStatus().isTerminal()) { throw new ApplicationException( CONFLICT, @@ -1504,9 +1468,12 @@ public void pauseWorkflow(String workflowId) { // remove from the sweep queue // any exceptions can be ignored, as this is not critical to the pause operation try { - queueDAO.remove(DECIDER_QUEUE, workflowId); + queueDAO.remove(Utils.DECIDER_QUEUE, workflowId); } catch (Exception e) { - LOGGER.info("Error removing workflow: {} from decider queue", workflowId, e); + LOGGER.info( + "[pauseWorkflow] Error removing workflow: {} from decider queue", + workflowId, + e); } } @@ -1515,8 +1482,8 @@ public void pauseWorkflow(String workflowId) { * @throws IllegalStateException if the workflow is not in PAUSED state */ public void resumeWorkflow(String workflowId) { - Workflow workflow = executionDAOFacade.getWorkflowById(workflowId, false); - if (!workflow.getStatus().equals(WorkflowStatus.PAUSED)) { + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, false); + if (!workflow.getStatus().equals(WorkflowModel.Status.PAUSED)) { throw new IllegalStateException( "The workflow " + workflowId @@ -1524,11 +1491,11 @@ public void resumeWorkflow(String workflowId) { + "Current status is " + workflow.getStatus().name()); } - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflow.setLastRetriedTime(System.currentTimeMillis()); // Add to decider queue queueDAO.push( - DECIDER_QUEUE, + Utils.DECIDER_QUEUE, workflow.getWorkflowId(), workflow.getPriority(), properties.getWorkflowOffsetTimeout().getSeconds()); @@ -1537,39 +1504,42 @@ public void resumeWorkflow(String workflowId) { } /** - * @param workflowId - * @param taskReferenceName - * @param skipTaskRequest + * @param workflowId the id of the workflow + * @param taskReferenceName the referenceName of the task to be skipped + * @param skipTaskRequest the {@link SkipTaskRequest} object * @throws IllegalStateException */ public void skipTaskFromWorkflow( String workflowId, String taskReferenceName, SkipTaskRequest skipTaskRequest) { - Workflow wf = executionDAOFacade.getWorkflowById(workflowId, true); + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true); // FIXME Backwards compatibility for legacy workflows already running. // This code will be removed in a future version. - wf = metadataMapperService.populateWorkflowWithDefinitions(wf); + workflow = metadataMapperService.populateWorkflowWithDefinitions(workflow); - // If the wf is not running then cannot skip any task - if (!wf.getStatus().equals(WorkflowStatus.RUNNING)) { + // If the workflow is not running then cannot skip any task + if (!workflow.getStatus().equals(WorkflowModel.Status.RUNNING)) { String errorMsg = String.format( "The workflow %s is not running so the task referenced by %s cannot be skipped", workflowId, taskReferenceName); throw new IllegalStateException(errorMsg); } + // Check if the reference name is as per the workflowdef - WorkflowTask wft = wf.getWorkflowDefinition().getTaskByRefName(taskReferenceName); - if (wft == null) { + WorkflowTask workflowTask = + workflow.getWorkflowDefinition().getTaskByRefName(taskReferenceName); + if (workflowTask == null) { String errorMsg = String.format( "The task referenced by %s does not exist in the WorkflowDefinition %s", - taskReferenceName, wf.getWorkflowName()); + taskReferenceName, workflow.getWorkflowName()); throw new IllegalStateException(errorMsg); } + // If the task is already started the again it cannot be skipped - wf.getTasks() + workflow.getTasks() .forEach( task -> { if (task.getReferenceTaskName().equals(taskReferenceName)) { @@ -1580,30 +1550,31 @@ public void skipTaskFromWorkflow( throw new IllegalStateException(errorMsg); } }); + // Now create a "SKIPPED" task for this workflow - Task theTask = new Task(); - theTask.setTaskId(IDGenerator.generate()); - theTask.setReferenceTaskName(taskReferenceName); - theTask.setWorkflowInstanceId(workflowId); - theTask.setWorkflowPriority(wf.getPriority()); - theTask.setStatus(SKIPPED); - theTask.setTaskType(wft.getName()); - theTask.setCorrelationId(wf.getCorrelationId()); + TaskModel taskToBeSkipped = new TaskModel(); + taskToBeSkipped.setTaskId(IDGenerator.generate()); + taskToBeSkipped.setReferenceTaskName(taskReferenceName); + taskToBeSkipped.setWorkflowInstanceId(workflowId); + taskToBeSkipped.setWorkflowPriority(workflow.getPriority()); + taskToBeSkipped.setStatus(SKIPPED); + taskToBeSkipped.setTaskType(workflowTask.getName()); + taskToBeSkipped.setCorrelationId(workflow.getCorrelationId()); if (skipTaskRequest != null) { - theTask.setInputData(skipTaskRequest.getTaskInput()); - theTask.setOutputData(skipTaskRequest.getTaskOutput()); - theTask.setInputMessage(skipTaskRequest.getTaskInputMessage()); - theTask.setOutputMessage(skipTaskRequest.getTaskOutputMessage()); + taskToBeSkipped.setInputData(skipTaskRequest.getTaskInput()); + taskToBeSkipped.setOutputData(skipTaskRequest.getTaskOutput()); + taskToBeSkipped.setInputMessage(skipTaskRequest.getTaskInputMessage()); + taskToBeSkipped.setOutputMessage(skipTaskRequest.getTaskOutputMessage()); } - executionDAOFacade.createTasks(Collections.singletonList(theTask)); + executionDAOFacade.createTasks(Collections.singletonList(taskToBeSkipped)); decide(workflowId); } - public Workflow getWorkflow(String workflowId, boolean includeTasks) { - return executionDAOFacade.getWorkflowById(workflowId, includeTasks); + public WorkflowModel getWorkflow(String workflowId, boolean includeTasks) { + return executionDAOFacade.getWorkflowModel(workflowId, includeTasks); } - public void addTaskToQueue(Task task) { + public void addTaskToQueue(TaskModel task) { // put in queue String taskQueueName = QueueUtils.getQueueName(task); if (task.getCallbackAfterSeconds() > 0) { @@ -1624,7 +1595,7 @@ public void addTaskToQueue(Task task) { } @VisibleForTesting - void setTaskDomains(List tasks, Workflow workflow) { + void setTaskDomains(List tasks, WorkflowModel workflow) { Map taskToDomain = workflow.getTaskToDomain(); if (taskToDomain != null) { // Step 1: Apply * mapping to all tasks, if present. @@ -1686,19 +1657,19 @@ String getActiveDomain(String taskType, String[] domains) { : domains[domains.length - 1].trim()); } - private long getTaskDuration(long s, Task task) { + private long getTaskDuration(long s, TaskModel task) { long duration = task.getEndTime() - task.getStartTime(); s += duration; if (task.getRetriedTaskId() == null) { return s; } - return s + getTaskDuration(s, executionDAOFacade.getTaskById(task.getRetriedTaskId())); + return s + getTaskDuration(s, executionDAOFacade.getTaskModel(task.getRetriedTaskId())); } @VisibleForTesting - boolean scheduleTask(Workflow workflow, List tasks) { - List createdTasks; - List tasksToBeQueued; + boolean scheduleTask(WorkflowModel workflow, List tasks) { + List createdTasks; + List tasksToBeQueued; boolean startedSystemTasks = false; try { @@ -1707,9 +1678,9 @@ boolean scheduleTask(Workflow workflow, List tasks) { } // Get the highest seq number - int count = workflow.getTasks().stream().mapToInt(Task::getSeq).max().orElse(0); + int count = workflow.getTasks().stream().mapToInt(TaskModel::getSeq).max().orElse(0); - for (Task task : tasks) { + for (TaskModel task : tasks) { if (task.getSeq() == 0) { // Set only if the seq was not set task.setSeq(++count); } @@ -1724,7 +1695,7 @@ boolean scheduleTask(Workflow workflow, List tasks) { // Save the tasks in the DAO createdTasks = executionDAOFacade.createTasks(tasks); - List systemTasks = + List systemTasks = createdTasks.stream() .filter(task -> systemTaskRegistry.isSystemTask(task.getTaskType())) .collect(Collectors.toList()); @@ -1736,7 +1707,7 @@ boolean scheduleTask(Workflow workflow, List tasks) { // Traverse through all the system tasks, start the sync tasks, in case of async queue // the tasks - for (Task task : systemTasks) { + for (TaskModel task : systemTasks) { WorkflowSystemTask workflowSystemTask = systemTaskRegistry.get(task.getTaskType()); if (workflowSystemTask == null) { throw new ApplicationException( @@ -1749,7 +1720,6 @@ boolean scheduleTask(Workflow workflow, List tasks) { } if (!workflowSystemTask.isAsync()) { try { - deciderService.populateTaskData(task); workflowSystemTask.start(workflow, task, this); } catch (Exception e) { String errorMsg = @@ -1762,14 +1732,14 @@ boolean scheduleTask(Workflow workflow, List tasks) { ApplicationException.Code.INTERNAL_ERROR, errorMsg, e); } startedSystemTasks = true; - deciderService.externalizeTaskData(task); executionDAOFacade.updateTask(task); } else { tasksToBeQueued.add(task); } } } catch (Exception e) { - List taskIds = tasks.stream().map(Task::getTaskId).collect(Collectors.toList()); + List taskIds = + tasks.stream().map(TaskModel::getTaskId).collect(Collectors.toList()); String errorMsg = String.format( "Error scheduling tasks: %s, for workflow: %s", @@ -1785,7 +1755,7 @@ boolean scheduleTask(Workflow workflow, List tasks) { addTaskToQueue(tasksToBeQueued); } catch (Exception e) { List taskIds = - tasksToBeQueued.stream().map(Task::getTaskId).collect(Collectors.toList()); + tasksToBeQueued.stream().map(TaskModel::getTaskId).collect(Collectors.toList()); String errorMsg = String.format( "Error pushing tasks to the queue: %s, for workflow: %s", @@ -1796,14 +1766,14 @@ boolean scheduleTask(Workflow workflow, List tasks) { return startedSystemTasks; } - private void addTaskToQueue(final List tasks) { - for (Task task : tasks) { + private void addTaskToQueue(final List tasks) { + for (TaskModel task : tasks) { addTaskToQueue(task); } } - private Workflow terminate( - final Workflow workflow, TerminateWorkflowException terminateWorkflowException) { + private WorkflowModel terminate( + final WorkflowModel workflow, TerminateWorkflowException terminateWorkflowException) { if (!workflow.getStatus().isTerminal()) { workflow.setStatus(terminateWorkflowException.getWorkflowStatus()); } @@ -1831,7 +1801,7 @@ private boolean rerunWF( String correlationId) { // Get the workflow - Workflow workflow = executionDAOFacade.getWorkflowById(workflowId, true); + WorkflowModel workflow = executionDAOFacade.getWorkflowModel(workflowId, true); updateAndPushParents(workflow, "reran"); // If the task Id is null it implies that the entire workflow has to be rerun @@ -1839,7 +1809,7 @@ private boolean rerunWF( // remove all tasks workflow.getTasks().forEach(task -> executionDAOFacade.removeTask(task.getTaskId())); // Set workflow as RUNNING - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); // Reset failure reason from previous run to default workflow.setReasonForIncompletion(null); workflow.setFailedReferenceTaskNames(new HashSet<>()); @@ -1851,7 +1821,7 @@ private boolean rerunWF( } queueDAO.push( - DECIDER_QUEUE, + Utils.DECIDER_QUEUE, workflow.getWorkflowId(), workflow.getPriority(), properties.getWorkflowOffsetTimeout().getSeconds()); @@ -1862,8 +1832,8 @@ private boolean rerunWF( } // Now iterate through the tasks and find the "specific" task - Task rerunFromTask = null; - for (Task task : workflow.getTasks()) { + TaskModel rerunFromTask = null; + for (TaskModel task : workflow.getTasks()) { if (task.getTaskId().equals(taskId)) { rerunFromTask = task; break; @@ -1872,8 +1842,8 @@ private boolean rerunWF( // If not found look into sub workflows if (rerunFromTask == null) { - for (Task task : workflow.getTasks()) { - if (task.getTaskType().equalsIgnoreCase(TASK_TYPE_SUB_WORKFLOW)) { + for (TaskModel task : workflow.getTasks()) { + if (task.getTaskType().equalsIgnoreCase(TaskType.TASK_TYPE_SUB_WORKFLOW)) { String subWorkflowId = task.getSubWorkflowId(); if (rerunWF(subWorkflowId, taskId, taskInput, null, null)) { rerunFromTask = task; @@ -1885,7 +1855,7 @@ private boolean rerunWF( if (rerunFromTask != null) { // set workflow as RUNNING - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); // Reset failure reason from previous run to default workflow.setReasonForIncompletion(null); workflow.setFailedReferenceTaskNames(new HashSet<>()); @@ -1897,7 +1867,7 @@ private boolean rerunWF( } // Add to decider queue queueDAO.push( - DECIDER_QUEUE, + Utils.DECIDER_QUEUE, workflow.getWorkflowId(), workflow.getPriority(), properties.getWorkflowOffsetTimeout().getSeconds()); @@ -1906,7 +1876,7 @@ private boolean rerunWF( // workflows executionDAOFacade.updateTasks(workflow.getTasks()); // Remove all tasks after the "rerunFromTask" - for (Task task : workflow.getTasks()) { + for (TaskModel task : workflow.getTasks()) { if (task.getSeq() > rerunFromTask.getSeq()) { executionDAOFacade.removeTask(task.getTaskId()); } @@ -1920,7 +1890,7 @@ private boolean rerunWF( rerunFromTask.setRetried(false); rerunFromTask.setExecuted(false); rerunFromTask.setExternalOutputPayloadStoragePath(null); - if (rerunFromTask.getTaskType().equalsIgnoreCase(TASK_TYPE_SUB_WORKFLOW)) { + if (rerunFromTask.getTaskType().equalsIgnoreCase(TaskType.TASK_TYPE_SUB_WORKFLOW)) { // if task is sub workflow set task as IN_PROGRESS and reset start time rerunFromTask.setStatus(IN_PROGRESS); rerunFromTask.setStartTime(System.currentTimeMillis()); @@ -1930,8 +1900,7 @@ private boolean rerunWF( } if (systemTaskRegistry.isSystemTask(rerunFromTask.getTaskType()) && !systemTaskRegistry.get(rerunFromTask.getTaskType()).isAsync()) { - // Start the synchronized system task directly - deciderService.populateTaskData(rerunFromTask); + // Start the synchronous system task directly systemTaskRegistry .get(rerunFromTask.getTaskType()) .start(workflow, rerunFromTask, this); @@ -1949,10 +1918,10 @@ private boolean rerunWF( return false; } - public void scheduleNextIteration(Task loopTask, Workflow workflow) { + public void scheduleNextIteration(TaskModel loopTask, WorkflowModel workflow) { // Schedule only first loop over task. Rest will be taken care in Decider Service when this // task will get completed. - List scheduledLoopOverTasks = + List scheduledLoopOverTasks = deciderService.getTasksToBeScheduled( workflow, loopTask.getWorkflowTask().getLoopOver().get(0), @@ -1969,7 +1938,7 @@ public void scheduleNextIteration(Task loopTask, Workflow workflow) { scheduleTask(workflow, scheduledLoopOverTasks); } - public TaskDef getTaskDefinition(Task task) { + public TaskDef getTaskDefinition(TaskModel task) { return task.getTaskDefinition() .orElseGet( () -> @@ -1988,33 +1957,33 @@ public TaskDef getTaskDefinition(Task task) { } @VisibleForTesting - void updateParentWorkflowTask(Workflow subWorkflow) { - Task subWorkflowTask = - executionDAOFacade.getTaskById(subWorkflow.getParentWorkflowTaskId()); + void updateParentWorkflowTask(WorkflowModel subWorkflow) { + TaskModel subWorkflowTask = + executionDAOFacade.getTaskModel(subWorkflow.getParentWorkflowTaskId()); executeSubworkflowTaskAndSyncData(subWorkflow, subWorkflowTask); executionDAOFacade.updateTask(subWorkflowTask); } - private void executeSubworkflowTaskAndSyncData(Workflow subWorkflow, Task subWorkflowTask) { - WorkflowSystemTask subWorkflowSystemTask = systemTaskRegistry.get(TASK_TYPE_SUB_WORKFLOW); + private void executeSubworkflowTaskAndSyncData( + WorkflowModel subWorkflow, TaskModel subWorkflowTask) { + WorkflowSystemTask subWorkflowSystemTask = + systemTaskRegistry.get(TaskType.TASK_TYPE_SUB_WORKFLOW); subWorkflowSystemTask.execute(subWorkflow, subWorkflowTask, this); // Keep Subworkflow task's data consistent with Subworkflow's. if (subWorkflowTask.getStatus().isTerminal() && subWorkflowTask.getExternalOutputPayloadStoragePath() != null && !subWorkflowTask.getOutputData().isEmpty()) { Map parentWorkflowTaskOutputData = subWorkflowTask.getOutputData(); - deciderService.populateTaskData(subWorkflowTask); subWorkflowTask.getOutputData().putAll(parentWorkflowTaskOutputData); - deciderService.externalizeTaskData(subWorkflowTask); } } /** Pushes parent workflow id into the decider queue with a priority. */ private void pushParentWorkflow(String parentWorkflowId) { - if (queueDAO.containsMessage(DECIDER_QUEUE, parentWorkflowId)) { - queueDAO.postpone(DECIDER_QUEUE, parentWorkflowId, PARENT_WF_PRIORITY, 0); + if (queueDAO.containsMessage(Utils.DECIDER_QUEUE, parentWorkflowId)) { + queueDAO.postpone(Utils.DECIDER_QUEUE, parentWorkflowId, PARENT_WF_PRIORITY, 0); } else { - queueDAO.push(DECIDER_QUEUE, parentWorkflowId, PARENT_WF_PRIORITY, 0); + queueDAO.push(Utils.DECIDER_QUEUE, parentWorkflowId, PARENT_WF_PRIORITY, 0); } } } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/evaluators/Evaluator.java b/core/src/main/java/com/netflix/conductor/core/execution/evaluators/Evaluator.java index 05acb6db51..88d01ef7f0 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/evaluators/Evaluator.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/evaluators/Evaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/execution/evaluators/JavascriptEvaluator.java b/core/src/main/java/com/netflix/conductor/core/execution/evaluators/JavascriptEvaluator.java index 896381dd5d..2dd6963d1c 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/evaluators/JavascriptEvaluator.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/evaluators/JavascriptEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,7 +21,6 @@ import com.netflix.conductor.core.events.ScriptEvaluator; import com.netflix.conductor.core.exception.TerminateWorkflowException; -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component(JavascriptEvaluator.NAME) public class JavascriptEvaluator implements Evaluator { diff --git a/core/src/main/java/com/netflix/conductor/core/execution/evaluators/ValueParamEvaluator.java b/core/src/main/java/com/netflix/conductor/core/execution/evaluators/ValueParamEvaluator.java index 6d410181af..f1fda61780 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/evaluators/ValueParamEvaluator.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/evaluators/ValueParamEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,13 +20,13 @@ import com.netflix.conductor.core.exception.TerminateWorkflowException; -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component(ValueParamEvaluator.NAME) public class ValueParamEvaluator implements Evaluator { public static final String NAME = "value-param"; private static final Logger LOGGER = LoggerFactory.getLogger(ValueParamEvaluator.class); + @SuppressWarnings("unchecked") @Override public Object evaluate(String expression, Object input) { LOGGER.debug("ValueParam evaluator -- evaluating: {}", expression); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/DecisionTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/DecisionTaskMapper.java index a7603e3603..f3b49f2101 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/DecisionTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/DecisionTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -24,21 +24,21 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.events.ScriptEvaluator; import com.netflix.conductor.core.exception.TerminateWorkflowException; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.google.common.annotations.VisibleForTesting; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#DECISION} to a List {@link Task} starting with Task of type {@link TaskType#DECISION} - * which is marked as IN_PROGRESS, followed by the list of {@link Task} based on the case expression - * evaluation in the Decision task. + * TaskType#DECISION} to a List {@link TaskModel} starting with Task of type {@link + * TaskType#DECISION} which is marked as IN_PROGRESS, followed by the list of {@link TaskModel} + * based on the case expression evaluation in the Decision task. * * @deprecated {@link com.netflix.conductor.core.execution.tasks.Decision} is also deprecated. Use * {@link com.netflix.conductor.core.execution.tasks.Switch} and so ${@link SwitchTaskMapper} @@ -60,10 +60,10 @@ public TaskType getTaskType() { * type {@link TaskType#DECISION}. * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId * @return List of tasks in the following order: *

      - *
    • {@link TaskType#DECISION} with {@link Task.Status#IN_PROGRESS} + *
    • {@link TaskType#DECISION} with {@link TaskModel.Status#IN_PROGRESS} *
    • List of task based on the evaluation of {@link WorkflowTask#getCaseExpression()} * are scheduled. *
    • In case of no matching result after the evaluation of the {@link @@ -72,11 +72,11 @@ public TaskType getTaskType() { *
    */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in DecisionTaskMapper", taskMapperContext); - List tasksToBeScheduled = new LinkedList<>(); + List tasksToBeScheduled = new LinkedList<>(); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); Map taskInput = taskMapperContext.getTaskInput(); int retryCount = taskMapperContext.getRetryCount(); String taskId = taskMapperContext.getTaskId(); @@ -85,7 +85,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { String caseValue = getEvaluatedCaseValue(taskToSchedule, taskInput); // QQ why is the case value and the caseValue passed and caseOutput passes as the same ?? - Task decisionTask = new Task(); + TaskModel decisionTask = new TaskModel(); decisionTask.setTaskType(TaskType.TASK_TYPE_DECISION); decisionTask.setTaskDefName(TaskType.TASK_TYPE_DECISION); decisionTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -97,7 +97,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { decisionTask.getOutputData().put("caseOutput", Collections.singletonList(caseValue)); decisionTask.setTaskId(taskId); decisionTask.setStartTime(System.currentTimeMillis()); - decisionTask.setStatus(Task.Status.IN_PROGRESS); + decisionTask.setStatus(TaskModel.Status.IN_PROGRESS); decisionTask.setWorkflowTask(taskToSchedule); decisionTask.setWorkflowPriority(workflowInstance.getPriority()); tasksToBeScheduled.add(decisionTask); @@ -110,14 +110,13 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { selectedTasks = taskToSchedule.getDefaultCase(); } // once there are selected tasks that need to proceeded as part of the decision, get the - // next task to be - // scheduled by using the decider service + // next task to be scheduled by using the decider service if (selectedTasks != null && !selectedTasks.isEmpty()) { WorkflowTask selectedTask = selectedTasks.get(0); // Schedule the first task to be executed... // TODO break out this recursive call using function composition of what needs to be // done and then walk back the condition tree - List caseTasks = + List caseTasks = taskMapperContext .getDeciderService() .getTasksToBeScheduled( diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/DoWhileTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/DoWhileTaskMapper.java index 466f12e2ed..bb53044842 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/DoWhileTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/DoWhileTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -22,20 +22,19 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.common.utils.TaskUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#DO_WHILE} to a {@link Task} of type {@link TaskType#DO_WHILE} + * TaskType#DO_WHILE} to a {@link TaskModel} of type {@link TaskType#DO_WHILE} */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component public class DoWhileTaskMapper implements TaskMapper { @@ -55,29 +54,29 @@ public TaskType getTaskType() { /** * This method maps {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#DO_WHILE} to a {@link Task} of type {@link TaskType#DO_WHILE} with a status of - * {@link Task.Status#IN_PROGRESS} + * TaskType#DO_WHILE} to a {@link TaskModel} of type {@link TaskType#DO_WHILE} with a status of + * {@link TaskModel.Status#IN_PROGRESS} * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId - * @return: A {@link Task} of type {@link TaskType#DO_WHILE} in a List + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId + * @return: A {@link TaskModel} of type {@link TaskType#DO_WHILE} in a List */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in DoWhileTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); - Task task = workflowInstance.getTaskByRefName(taskToSchedule.getTaskReferenceName()); + TaskModel task = workflowInstance.getTaskByRefName(taskToSchedule.getTaskReferenceName()); if (task != null && task.getStatus().isTerminal()) { // Since loopTask is already completed no need to schedule task again. return Collections.emptyList(); } String taskId = taskMapperContext.getTaskId(); - List tasksToBeScheduled = new ArrayList<>(); + List tasksToBeScheduled = new ArrayList<>(); int retryCount = taskMapperContext.getRetryCount(); TaskDef taskDefinition = Optional.ofNullable(taskMapperContext.getTaskDefinition()) @@ -88,7 +87,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { taskToSchedule.getName())) .orElseGet(TaskDef::new)); - Task loopTask = new Task(); + TaskModel loopTask = new TaskModel(); loopTask.setTaskType(TaskType.TASK_TYPE_DO_WHILE); loopTask.setTaskDefName(taskToSchedule.getName()); loopTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -98,14 +97,14 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { loopTask.setScheduledTime(System.currentTimeMillis()); loopTask.setTaskId(taskId); loopTask.setIteration(1); - loopTask.setStatus(Task.Status.IN_PROGRESS); + loopTask.setStatus(TaskModel.Status.IN_PROGRESS); loopTask.setWorkflowTask(taskToSchedule); loopTask.setRateLimitPerFrequency(taskDefinition.getRateLimitPerFrequency()); loopTask.setRateLimitFrequencyInSeconds(taskDefinition.getRateLimitFrequencyInSeconds()); tasksToBeScheduled.add(loopTask); List loopOverTasks = taskToSchedule.getLoopOver(); - List tasks2 = + List tasks2 = taskMapperContext .getDeciderService() .getTasksToBeScheduled(workflowInstance, loopOverTasks.get(0), retryCount); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/DynamicTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/DynamicTaskMapper.java index bbbcf618bb..5796a4d11b 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/DynamicTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/DynamicTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -22,24 +22,23 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.google.common.annotations.VisibleForTesting; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#DYNAMIC} to a {@link Task} based on definition derived from the dynamic task name + * TaskType#DYNAMIC} to a {@link TaskModel} based on definition derived from the dynamic task name * defined in {@link WorkflowTask#getInputParameters()} */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component public class DynamicTaskMapper implements TaskMapper { @@ -60,20 +59,20 @@ public TaskType getTaskType() { } /** - * This method maps a dynamic task to a {@link Task} based on the input params + * This method maps a dynamic task to a {@link TaskModel} based on the input params * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId - * @return A {@link List} that contains a single {@link Task} with a {@link - * Task.Status#SCHEDULED} + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId + * @return A {@link List} that contains a single {@link TaskModel} with a {@link + * TaskModel.Status#SCHEDULED} */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) + public List getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException { LOGGER.debug("TaskMapperContext {} in DynamicTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); Map taskInput = taskMapperContext.getTaskInput(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); int retryCount = taskMapperContext.getRetryCount(); String retriedTaskId = taskMapperContext.getRetryTaskId(); @@ -89,14 +88,14 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) workflowInstance, taskDefinition, taskMapperContext.getTaskId()); - Task dynamicTask = new Task(); + TaskModel dynamicTask = new TaskModel(); dynamicTask.setStartDelayInSeconds(taskToSchedule.getStartDelay()); dynamicTask.setTaskId(taskMapperContext.getTaskId()); dynamicTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); dynamicTask.setInputData(input); dynamicTask.setWorkflowInstanceId(workflowInstance.getWorkflowId()); dynamicTask.setWorkflowType(workflowInstance.getWorkflowName()); - dynamicTask.setStatus(Task.Status.SCHEDULED); + dynamicTask.setStatus(TaskModel.Status.SCHEDULED); dynamicTask.setTaskType(taskToSchedule.getType()); dynamicTask.setTaskDefName(taskToSchedule.getName()); dynamicTask.setCorrelationId(workflowInstance.getCorrelationId()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/EventTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/EventTaskMapper.java index 2d6f98a0f6..397c1d418b 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/EventTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/EventTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,11 +21,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_EVENT; @@ -47,12 +47,12 @@ public TaskType getTaskType() { } @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in EventTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); taskToSchedule.getInputParameters().put("sink", taskToSchedule.getSink()); @@ -63,7 +63,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { String sink = (String) eventTaskInput.get("sink"); Boolean asynComplete = (Boolean) eventTaskInput.get("asyncComplete"); - Task eventTask = new Task(); + TaskModel eventTask = new TaskModel(); eventTask.setTaskType(TASK_TYPE_EVENT); eventTask.setTaskDefName(taskToSchedule.getName()); eventTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -75,7 +75,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { eventTask.getInputData().put("sink", sink); eventTask.getInputData().put("asyncComplete", asynComplete); eventTask.setTaskId(taskId); - eventTask.setStatus(Task.Status.SCHEDULED); + eventTask.setStatus(TaskModel.Status.SCHEDULED); eventTask.setWorkflowPriority(workflowInstance.getPriority()); eventTask.setWorkflowTask(taskToSchedule); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/ExclusiveJoinTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/ExclusiveJoinTaskMapper.java index c275bee4d9..867edb7f85 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/ExclusiveJoinTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/ExclusiveJoinTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,10 +21,10 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; @Component public class ExclusiveJoinTaskMapper implements TaskMapper { @@ -37,12 +37,12 @@ public TaskType getTaskType() { } @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in ExclusiveJoinTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); Map joinInput = new HashMap<>(); @@ -52,7 +52,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { joinInput.put("defaultExclusiveJoinTask", taskToSchedule.getDefaultExclusiveJoinTask()); } - Task joinTask = new Task(); + TaskModel joinTask = new TaskModel(); joinTask.setTaskType(TaskType.TASK_TYPE_EXCLUSIVE_JOIN); joinTask.setTaskDefName(TaskType.TASK_TYPE_EXCLUSIVE_JOIN); joinTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -63,7 +63,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { joinTask.setStartTime(System.currentTimeMillis()); joinTask.setInputData(joinInput); joinTask.setTaskId(taskId); - joinTask.setStatus(Task.Status.IN_PROGRESS); + joinTask.setStatus(TaskModel.Status.IN_PROGRESS); joinTask.setWorkflowPriority(workflowInstance.getPriority()); joinTask.setWorkflowTask(taskToSchedule); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapper.java index f8623b6869..addf91523b 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -28,16 +28,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.DynamicForkJoinTaskList; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -45,11 +45,10 @@ /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#FORK_JOIN_DYNAMIC} to a LinkedList of {@link Task} beginning with a {@link + * TaskType#FORK_JOIN_DYNAMIC} to a LinkedList of {@link TaskModel} beginning with a {@link * TaskType#TASK_TYPE_FORK}, followed by the user defined dynamic tasks and a {@link TaskType#JOIN} * at the end */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component public class ForkJoinDynamicTaskMapper implements TaskMapper { @@ -59,7 +58,7 @@ public class ForkJoinDynamicTaskMapper implements TaskMapper { private final ObjectMapper objectMapper; private final MetadataDAO metadataDAO; private static final TypeReference> ListOfWorkflowTasks = - new TypeReference>() {}; + new TypeReference<>() {}; @Autowired public ForkJoinDynamicTaskMapper( @@ -98,13 +97,13 @@ public TaskType getTaskType() { * * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId * @return List of tasks in the following order: *

      - *
    • {@link TaskType#TASK_TYPE_FORK} with {@link Task.Status#COMPLETED} + *
    • {@link TaskType#TASK_TYPE_FORK} with {@link TaskModel.Status#COMPLETED} *
    • Might be any kind of task, but this is most cases is a UserDefinedTask with {@link - * Task.Status#SCHEDULED} - *
    • {@link TaskType#JOIN} with {@link Task.Status#IN_PROGRESS} + * TaskModel.Status#SCHEDULED} + *
    • {@link TaskType#JOIN} with {@link TaskModel.Status#IN_PROGRESS} *
    * * @throws TerminateWorkflowException In case of: @@ -115,16 +114,16 @@ public TaskType getTaskType() { * */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) + public List getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException { LOGGER.debug("TaskMapperContext {} in ForkJoinDynamicTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); int retryCount = taskMapperContext.getRetryCount(); - List mappedTasks = new LinkedList<>(); + List mappedTasks = new LinkedList<>(); // Get the list of dynamic tasks and the input for the tasks Pair, Map>> workflowTasksAndInputPair = Optional.ofNullable(taskToSchedule.getDynamicForkTasksParam()) @@ -143,7 +142,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) Map> tasksInput = workflowTasksAndInputPair.getRight(); // Create Fork Task which needs to be followed by the dynamic tasks - Task forkDynamicTask = + TaskModel forkDynamicTask = createDynamicForkTask(taskToSchedule, workflowInstance, taskId, dynForkTasks); mappedTasks.add(forkDynamicTask); @@ -154,7 +153,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) for (WorkflowTask dynForkTask : dynForkTasks) { // TODO this is a cyclic dependency, break it out using function // composition - List forkedTasks = + List forkedTasks = taskMapperContext .getDeciderService() .getTasksToBeScheduled(workflowInstance, dynForkTask, retryCount); @@ -171,9 +170,11 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) runningTask -> runningTask .getStatus() - .equals(Task.Status.IN_PROGRESS) + .equals( + TaskModel.Status + .IN_PROGRESS) || runningTask.getStatus().isTerminal()) - .map(Task::getReferenceTaskName) + .map(TaskModel::getReferenceTaskName) .filter( refTaskName -> refTaskName.equals( @@ -194,7 +195,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) throw new TerminateWorkflowException(terminateMessage); } - for (Task forkedTask : forkedTasks) { + for (TaskModel forkedTask : forkedTasks) { Map forkedTaskInput = tasksInput.get(forkedTask.getReferenceTaskName()); forkedTask.getInputData().putAll(forkedTaskInput); @@ -202,7 +203,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) mappedTasks.addAll(forkedTasks); // Get the last of the dynamic tasks so that the join can be performed once this task is // done - Task last = forkedTasks.get(forkedTasks.size() - 1); + TaskModel last = forkedTasks.get(forkedTasks.size() - 1); joinOnTaskRefs.add(last.getReferenceTaskName()); } @@ -221,7 +222,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) // Create Join task HashMap joinInput = new HashMap<>(); joinInput.put("joinOn", joinOnTaskRefs); - Task joinTask = createJoinTask(workflowInstance, joinWorkflowTask, joinInput); + TaskModel joinTask = createJoinTask(workflowInstance, joinWorkflowTask, joinInput); mappedTasks.add(joinTask); return mappedTasks; @@ -229,24 +230,24 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) /** * This method creates a FORK task and adds the list of dynamic fork tasks keyed by - * "forkedTaskDefs" and their names keyed by "forkedTasks" into {@link Task#getInputData()} + * "forkedTaskDefs" and their names keyed by "forkedTasks" into {@link TaskModel#getInputData()} * * @param taskToSchedule A {@link WorkflowTask} representing {@link TaskType#FORK_JOIN_DYNAMIC} - * @param workflowInstance: A instance of the {@link Workflow} which represents the workflow - * being executed. + * @param workflowInstance: A instance of the {@link WorkflowModel} which represents the + * workflow being executed. * @param taskId: The string representation of {@link java.util.UUID} which will be set as the * taskId. * @param dynForkTasks: The list of dynamic forked tasks, the reference names of these tasks * will be added to the forkDynamicTask - * @return A new instance of {@link Task} representing a {@link TaskType#TASK_TYPE_FORK} + * @return A new instance of {@link TaskModel} representing a {@link TaskType#TASK_TYPE_FORK} */ @VisibleForTesting - Task createDynamicForkTask( + TaskModel createDynamicForkTask( WorkflowTask taskToSchedule, - Workflow workflowInstance, + WorkflowModel workflowInstance, String taskId, List dynForkTasks) { - Task forkDynamicTask = new Task(); + TaskModel forkDynamicTask = new TaskModel(); forkDynamicTask.setTaskType(TaskType.TASK_TYPE_FORK); forkDynamicTask.setTaskDefName(TaskType.TASK_TYPE_FORK); forkDynamicTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -265,7 +266,7 @@ Task createDynamicForkTask( "forkedTaskDefs", dynForkTasks); // TODO: Remove this parameter in the later releases forkDynamicTask.setTaskId(taskId); - forkDynamicTask.setStatus(Task.Status.COMPLETED); + forkDynamicTask.setStatus(TaskModel.Status.COMPLETED); forkDynamicTask.setWorkflowTask(taskToSchedule); forkDynamicTask.setWorkflowPriority(workflowInstance.getPriority()); return forkDynamicTask; @@ -276,19 +277,19 @@ Task createDynamicForkTask( * this#getMappedTasks(TaskMapperContext)} at the end to add a join task to be scheduled after * all the fork tasks * - * @param workflowInstance: A instance of the {@link Workflow} which represents the workflow - * being executed. + * @param workflowInstance: A instance of the {@link WorkflowModel} which represents the + * workflow being executed. * @param joinWorkflowTask: A instance of {@link WorkflowTask} which is of type {@link * TaskType#JOIN} - * @param joinInput: The input which is set in the {@link Task#setInputData(Map)} - * @return a new instance of {@link Task} representing a {@link TaskType#JOIN} + * @param joinInput: The input which is set in the {@link TaskModel#setInputData(Map)} + * @return a new instance of {@link TaskModel} representing a {@link TaskType#JOIN} */ @VisibleForTesting - Task createJoinTask( - Workflow workflowInstance, + TaskModel createJoinTask( + WorkflowModel workflowInstance, WorkflowTask joinWorkflowTask, HashMap joinInput) { - Task joinTask = new Task(); + TaskModel joinTask = new TaskModel(); joinTask.setTaskType(TaskType.TASK_TYPE_JOIN); joinTask.setTaskDefName(TaskType.TASK_TYPE_JOIN); joinTask.setReferenceTaskName(joinWorkflowTask.getTaskReferenceName()); @@ -298,7 +299,7 @@ Task createJoinTask( joinTask.setScheduledTime(System.currentTimeMillis()); joinTask.setInputData(joinInput); joinTask.setTaskId(IDGenerator.generate()); - joinTask.setStatus(Task.Status.IN_PROGRESS); + joinTask.setStatus(TaskModel.Status.IN_PROGRESS); joinTask.setWorkflowTask(joinWorkflowTask); joinTask.setWorkflowPriority(workflowInstance.getPriority()); return joinTask; @@ -310,8 +311,8 @@ Task createJoinTask( * * @param taskToSchedule: The Task of type FORK_JOIN_DYNAMIC that needs to scheduled, which has * the input parameters - * @param workflowInstance: The instance of the {@link Workflow} which represents the workflow - * being executed. + * @param workflowInstance: The instance of the {@link WorkflowModel} which represents the + * workflow being executed. * @param dynamicForkTaskParam: The key representing the dynamic fork join json payload which is * available in {@link WorkflowTask#getInputParameters()} * @return a {@link Pair} representing the list of dynamic fork tasks in {@link Pair#getLeft()} @@ -322,7 +323,9 @@ Task createJoinTask( @SuppressWarnings("unchecked") @VisibleForTesting Pair, Map>> getDynamicForkTasksAndInput( - WorkflowTask taskToSchedule, Workflow workflowInstance, String dynamicForkTaskParam) + WorkflowTask taskToSchedule, + WorkflowModel workflowInstance, + String dynamicForkTaskParam) throws TerminateWorkflowException { Map input = @@ -360,8 +363,8 @@ Pair, Map>> getDynamicForkTasksAn * * @param taskToSchedule: The Task of type FORK_JOIN_DYNAMIC that needs to scheduled, which has * the input parameters - * @param workflowInstance: The instance of the {@link Workflow} which represents the workflow - * being executed. + * @param workflowInstance: The instance of the {@link WorkflowModel} which represents the + * workflow being executed. * @return {@link Pair} representing the list of dynamic fork tasks in {@link Pair#getLeft()} * and the input for the dynamic fork tasks in {@link Pair#getRight()} * @throws TerminateWorkflowException : In case of the {@link WorkflowTask#getInputParameters()} @@ -369,7 +372,7 @@ Pair, Map>> getDynamicForkTasksAn */ @VisibleForTesting Pair, Map>> getDynamicForkJoinTasksAndInput( - WorkflowTask taskToSchedule, Workflow workflowInstance) + WorkflowTask taskToSchedule, WorkflowModel workflowInstance) throws TerminateWorkflowException { String dynamicForkJoinTaskParam = taskToSchedule.getDynamicForkJoinTasksParam(); Map input = diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinTaskMapper.java index b15d75a210..298f7d8efd 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/ForkJoinTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,16 +20,16 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#FORK_JOIN} to a LinkedList of {@link Task} beginning with a completed {@link + * TaskType#FORK_JOIN} to a LinkedList of {@link TaskModel} beginning with a completed {@link * TaskType#TASK_TYPE_FORK}, followed by the user defined fork tasks */ @Component @@ -47,32 +47,32 @@ public TaskType getTaskType() { * type {@link TaskType#FORK_JOIN}. * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId * @return List of tasks in the following order: * *

      - *
    • {@link TaskType#TASK_TYPE_FORK} with {@link Task.Status#COMPLETED} + *
    • {@link TaskType#TASK_TYPE_FORK} with {@link TaskModel.Status#COMPLETED} *
    • Might be any kind of task, but in most cases is a UserDefinedTask with {@link - * Task.Status#SCHEDULED} + * TaskModel.Status#SCHEDULED} *
    * * @throws TerminateWorkflowException When the task after {@link TaskType#FORK_JOIN} is not a * {@link TaskType#JOIN} */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) + public List getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException { LOGGER.debug("TaskMapperContext {} in ForkJoinTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); Map taskInput = taskMapperContext.getTaskInput(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); int retryCount = taskMapperContext.getRetryCount(); String taskId = taskMapperContext.getTaskId(); - List tasksToBeScheduled = new LinkedList<>(); - Task forkTask = new Task(); + List tasksToBeScheduled = new LinkedList<>(); + TaskModel forkTask = new TaskModel(); forkTask.setTaskType(TaskType.TASK_TYPE_FORK); forkTask.setTaskDefName(TaskType.TASK_TYPE_FORK); forkTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -83,7 +83,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) forkTask.setStartTime(System.currentTimeMillis()); forkTask.setInputData(taskInput); forkTask.setTaskId(taskId); - forkTask.setStatus(Task.Status.COMPLETED); + forkTask.setStatus(TaskModel.Status.COMPLETED); forkTask.setWorkflowPriority(workflowInstance.getPriority()); forkTask.setWorkflowTask(taskToSchedule); @@ -91,7 +91,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) List> forkTasks = taskToSchedule.getForkTasks(); for (List wfts : forkTasks) { WorkflowTask wft = wfts.get(0); - List tasks2 = + List tasks2 = taskMapperContext .getDeciderService() .getTasksToBeScheduled(workflowInstance, wft, retryCount); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/HTTPTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/HTTPTaskMapper.java index ef566d4980..ac1be5e0d1 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/HTTPTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/HTTPTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,32 +12,28 @@ */ package com.netflix.conductor.core.execution.mapper; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; +import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#HTTP} to a {@link Task} of type {@link TaskType#HTTP} with {@link Task.Status#SCHEDULED} + * TaskType#HTTP} to a {@link TaskModel} of type {@link TaskType#HTTP} with {@link + * TaskModel.Status#SCHEDULED} */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component public class HTTPTaskMapper implements TaskMapper { @@ -58,34 +54,29 @@ public TaskType getTaskType() { } /** - * This method maps a {@link WorkflowTask} of type {@link TaskType#HTTP} to a {@link Task} in a - * {@link Task.Status#SCHEDULED} state + * This method maps a {@link WorkflowTask} of type {@link TaskType#HTTP} to a {@link TaskModel} + * in a {@link TaskModel.Status#SCHEDULED} state * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId * @return a List with just one HTTP task * @throws TerminateWorkflowException In case if the task definition does not exist */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) + public List getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException { LOGGER.debug("TaskMapperContext {} in HTTPTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); taskToSchedule.getInputParameters().put("asyncComplete", taskToSchedule.isAsyncComplete()); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); int retryCount = taskMapperContext.getRetryCount(); TaskDef taskDefinition = Optional.ofNullable(taskMapperContext.getTaskDefinition()) - .orElseGet( - () -> - Optional.ofNullable( - metadataDAO.getTaskDef( - taskToSchedule.getName())) - .orElse(null)); + .orElseGet(() -> metadataDAO.getTaskDef(taskToSchedule.getName())); Map input = parametersUtils.getTaskInputV2( @@ -95,7 +86,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) taskDefinition); Boolean asynComplete = (Boolean) input.get("asyncComplete"); - Task httpTask = new Task(); + TaskModel httpTask = new TaskModel(); httpTask.setTaskType(taskToSchedule.getType()); httpTask.setTaskDefName(taskToSchedule.getName()); httpTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -106,7 +97,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) httpTask.setTaskId(taskId); httpTask.setInputData(input); httpTask.getInputData().put("asyncComplete", asynComplete); - httpTask.setStatus(Task.Status.SCHEDULED); + httpTask.setStatus(TaskModel.Status.SCHEDULED); httpTask.setRetryCount(retryCount); httpTask.setCallbackAfterSeconds(taskToSchedule.getStartDelay()); httpTask.setWorkflowTask(taskToSchedule); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/InlineTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/InlineTaskMapper.java index 73164cb7c5..3324e18dab 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/InlineTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/InlineTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,19 +21,19 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#INLINE} to a List {@link Task} starting with Task of type {@link TaskType#INLINE} which - * is marked as IN_PROGRESS, followed by the list of {@link Task} based on the case expression - * evaluation in the Inline task. + * TaskType#INLINE} to a List {@link TaskModel} starting with Task of type {@link TaskType#INLINE} + * which is marked as IN_PROGRESS, followed by the list of {@link TaskModel} based on the case + * expression evaluation in the Inline task. */ @Component public class InlineTaskMapper implements TaskMapper { @@ -53,22 +53,17 @@ public TaskType getTaskType() { } @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in InlineTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); TaskDef taskDefinition = Optional.ofNullable(taskMapperContext.getTaskDefinition()) - .orElseGet( - () -> - Optional.ofNullable( - metadataDAO.getTaskDef( - taskToSchedule.getName())) - .orElse(null)); + .orElseGet(() -> metadataDAO.getTaskDef(taskToSchedule.getName())); Map taskInput = parametersUtils.getTaskInputV2( @@ -77,7 +72,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { taskId, taskDefinition); - Task inlineTask = new Task(); + TaskModel inlineTask = new TaskModel(); inlineTask.setTaskType(TaskType.TASK_TYPE_INLINE); inlineTask.setTaskDefName(taskMapperContext.getTaskToSchedule().getName()); inlineTask.setReferenceTaskName( @@ -89,7 +84,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { inlineTask.setScheduledTime(System.currentTimeMillis()); inlineTask.setInputData(taskInput); inlineTask.setTaskId(taskId); - inlineTask.setStatus(Task.Status.IN_PROGRESS); + inlineTask.setStatus(TaskModel.Status.IN_PROGRESS); inlineTask.setWorkflowTask(taskToSchedule); inlineTask.setWorkflowPriority(workflowInstance.getPriority()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/JoinTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/JoinTaskMapper.java index e9363e1b68..698843afe4 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/JoinTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/JoinTaskMapper.java @@ -21,15 +21,15 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#JOIN} to a {@link Task} of type {@link TaskType#JOIN} + * TaskType#JOIN} to a {@link TaskModel} of type {@link TaskType#JOIN} */ @Component public class JoinTaskMapper implements TaskMapper { @@ -43,26 +43,26 @@ public TaskType getTaskType() { /** * This method maps {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#JOIN} to a {@link Task} of type {@link TaskType#JOIN} with a status of {@link - * Task.Status#IN_PROGRESS} + * TaskType#JOIN} to a {@link TaskModel} of type {@link TaskType#JOIN} with a status of {@link + * TaskModel.Status#IN_PROGRESS} * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId - * @return A {@link Task} of type {@link TaskType#JOIN} in a List + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId + * @return A {@link TaskModel} of type {@link TaskType#JOIN} in a List */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in JoinTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); Map joinInput = new HashMap<>(); joinInput.put("joinOn", taskToSchedule.getJoinOn()); - Task joinTask = new Task(); + TaskModel joinTask = new TaskModel(); joinTask.setTaskType(TaskType.TASK_TYPE_JOIN); joinTask.setTaskDefName(TaskType.TASK_TYPE_JOIN); joinTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -73,7 +73,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { joinTask.setStartTime(System.currentTimeMillis()); joinTask.setInputData(joinInput); joinTask.setTaskId(taskId); - joinTask.setStatus(Task.Status.IN_PROGRESS); + joinTask.setStatus(TaskModel.Status.IN_PROGRESS); joinTask.setWorkflowTask(taskToSchedule); joinTask.setWorkflowPriority(workflowInstance.getPriority()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/JsonJQTransformTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/JsonJQTransformTaskMapper.java index a2e1e54d0a..ca7891e11e 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/JsonJQTransformTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/JsonJQTransformTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,13 +21,13 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; @Component public class JsonJQTransformTaskMapper implements TaskMapper { @@ -47,22 +47,17 @@ public TaskType getTaskType() { } @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in JsonJQTransformTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); TaskDef taskDefinition = Optional.ofNullable(taskMapperContext.getTaskDefinition()) - .orElseGet( - () -> - Optional.ofNullable( - metadataDAO.getTaskDef( - taskToSchedule.getName())) - .orElse(null)); + .orElseGet(() -> metadataDAO.getTaskDef(taskToSchedule.getName())); Map taskInput = parametersUtils.getTaskInputV2( @@ -71,7 +66,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { taskId, taskDefinition); - Task jsonJQTransformTask = new Task(); + TaskModel jsonJQTransformTask = new TaskModel(); jsonJQTransformTask.setTaskType(taskToSchedule.getType()); jsonJQTransformTask.setTaskDefName(taskToSchedule.getName()); jsonJQTransformTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -82,7 +77,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { jsonJQTransformTask.setScheduledTime(System.currentTimeMillis()); jsonJQTransformTask.setInputData(taskInput); jsonJQTransformTask.setTaskId(taskId); - jsonJQTransformTask.setStatus(Task.Status.IN_PROGRESS); + jsonJQTransformTask.setStatus(TaskModel.Status.IN_PROGRESS); jsonJQTransformTask.setWorkflowTask(taskToSchedule); jsonJQTransformTask.setWorkflowPriority(workflowInstance.getPriority()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/KafkaPublishTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/KafkaPublishTaskMapper.java index 227442b259..77e4f5d730 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/KafkaPublishTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/KafkaPublishTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -23,17 +23,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component public class KafkaPublishTaskMapper implements TaskMapper { @@ -55,32 +54,27 @@ public TaskType getTaskType() { /** * This method maps a {@link WorkflowTask} of type {@link TaskType#KAFKA_PUBLISH} to a {@link - * Task} in a {@link Task.Status#SCHEDULED} state + * TaskModel} in a {@link TaskModel.Status#SCHEDULED} state * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId * @return a List with just one Kafka task * @throws TerminateWorkflowException In case if the task definition does not exist */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) + public List getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException { LOGGER.debug("TaskMapperContext {} in KafkaPublishTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); int retryCount = taskMapperContext.getRetryCount(); TaskDef taskDefinition = Optional.ofNullable(taskMapperContext.getTaskDefinition()) - .orElseGet( - () -> - Optional.ofNullable( - metadataDAO.getTaskDef( - taskToSchedule.getName())) - .orElse(null)); + .orElseGet(() -> metadataDAO.getTaskDef(taskToSchedule.getName())); Map input = parametersUtils.getTaskInputV2( @@ -89,7 +83,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) taskId, taskDefinition); - Task kafkaPublishTask = new Task(); + TaskModel kafkaPublishTask = new TaskModel(); kafkaPublishTask.setTaskType(taskToSchedule.getType()); kafkaPublishTask.setTaskDefName(taskToSchedule.getName()); kafkaPublishTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -99,7 +93,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) kafkaPublishTask.setScheduledTime(System.currentTimeMillis()); kafkaPublishTask.setTaskId(taskId); kafkaPublishTask.setInputData(input); - kafkaPublishTask.setStatus(Task.Status.SCHEDULED); + kafkaPublishTask.setStatus(TaskModel.Status.SCHEDULED); kafkaPublishTask.setRetryCount(retryCount); kafkaPublishTask.setCallbackAfterSeconds(taskToSchedule.getStartDelay()); kafkaPublishTask.setWorkflowTask(taskToSchedule); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/LambdaTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/LambdaTaskMapper.java index 02399bd1a1..83d7d0a4dd 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/LambdaTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/LambdaTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,13 +21,13 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * @author x-ultra @@ -54,22 +54,17 @@ public TaskType getTaskType() { } @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in LambdaTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); TaskDef taskDefinition = Optional.ofNullable(taskMapperContext.getTaskDefinition()) - .orElseGet( - () -> - Optional.ofNullable( - metadataDAO.getTaskDef( - taskToSchedule.getName())) - .orElse(null)); + .orElseGet(() -> metadataDAO.getTaskDef(taskToSchedule.getName())); Map taskInput = parametersUtils.getTaskInputV2( @@ -78,7 +73,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { taskId, taskDefinition); - Task lambdaTask = new Task(); + TaskModel lambdaTask = new TaskModel(); lambdaTask.setTaskType(TaskType.TASK_TYPE_LAMBDA); lambdaTask.setTaskDefName(taskMapperContext.getTaskToSchedule().getName()); lambdaTask.setReferenceTaskName( @@ -90,7 +85,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { lambdaTask.setScheduledTime(System.currentTimeMillis()); lambdaTask.setInputData(taskInput); lambdaTask.setTaskId(taskId); - lambdaTask.setStatus(Task.Status.IN_PROGRESS); + lambdaTask.setStatus(TaskModel.Status.IN_PROGRESS); lambdaTask.setWorkflowTask(taskToSchedule); lambdaTask.setWorkflowPriority(workflowInstance.getPriority()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/SetVariableTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/SetVariableTaskMapper.java index 3524cbccf2..b0a191eb89 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/SetVariableTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/SetVariableTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,11 +20,11 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.exception.TerminateWorkflowException; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; @Component public class SetVariableTaskMapper implements TaskMapper { @@ -37,16 +37,16 @@ public TaskType getTaskType() { } @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) + public List getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException { LOGGER.debug("TaskMapperContext {} in SetVariableMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); Map taskInput = taskMapperContext.getTaskInput(); String taskId = taskMapperContext.getTaskId(); - Task varTask = new Task(); + TaskModel varTask = new TaskModel(); varTask.setTaskType(taskToSchedule.getType()); varTask.setTaskDefName(taskToSchedule.getName()); varTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -57,7 +57,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) varTask.setScheduledTime(System.currentTimeMillis()); varTask.setInputData(taskInput); varTask.setTaskId(taskId); - varTask.setStatus(Task.Status.IN_PROGRESS); + varTask.setStatus(TaskModel.Status.IN_PROGRESS); varTask.setWorkflowTask(taskToSchedule); varTask.setWorkflowPriority(workflowInstance.getPriority()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/SimpleTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/SimpleTaskMapper.java index b5f4878160..3b99c1b2b4 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/SimpleTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/SimpleTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,19 +21,19 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#SIMPLE} to a {@link Task} with status {@link Task.Status#SCHEDULED}. NOTE: There - * is not type defined for simples task. + * TaskType#SIMPLE} to a {@link TaskModel} with status {@link TaskModel.Status#SCHEDULED}. + * NOTE: There is not type defined for simples task. */ @Component public class SimpleTaskMapper implements TaskMapper { @@ -54,18 +54,18 @@ public TaskType getTaskType() { * This method maps a {@link WorkflowTask} of type {@link TaskType#SIMPLE} to a {@link Task} * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId * @throws TerminateWorkflowException In case if the task definition does not exist * @return a List with just one simple task */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) + public List getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException { LOGGER.debug("TaskMapperContext {} in SimpleTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); int retryCount = taskMapperContext.getRetryCount(); String retriedTaskId = taskMapperContext.getRetryTaskId(); @@ -86,14 +86,14 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) workflowInstance, taskDefinition, taskMapperContext.getTaskId()); - Task simpleTask = new Task(); + TaskModel simpleTask = new TaskModel(); simpleTask.setStartDelayInSeconds(taskToSchedule.getStartDelay()); simpleTask.setTaskId(taskMapperContext.getTaskId()); simpleTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); simpleTask.setInputData(input); simpleTask.setWorkflowInstanceId(workflowInstance.getWorkflowId()); simpleTask.setWorkflowType(workflowInstance.getWorkflowName()); - simpleTask.setStatus(Task.Status.SCHEDULED); + simpleTask.setStatus(TaskModel.Status.SCHEDULED); simpleTask.setTaskType(taskToSchedule.getName()); simpleTask.setTaskDefName(taskToSchedule.getName()); simpleTask.setCorrelationId(workflowInstance.getCorrelationId()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/SubWorkflowTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/SubWorkflowTaskMapper.java index d6c3b105c0..a724482f8f 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/SubWorkflowTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/SubWorkflowTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,25 +12,21 @@ */ package com.netflix.conductor.core.execution.mapper; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.SubWorkflowParams; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.google.common.annotations.VisibleForTesting; @@ -56,12 +52,12 @@ public TaskType getTaskType() { @SuppressWarnings("rawtypes") @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in SubWorkflowTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); - // Check if the are sub workflow parameters, if not throw an exception, cannot initiate a + // Check if there are sub workflow parameters, if not throw an exception, cannot initiate a // sub-workflow without workflow params SubWorkflowParams subWorkflowParams = getSubWorkflowParams(taskToSchedule); @@ -79,7 +75,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { subWorkflowTaskToDomain = (Map) uncheckedTaskToDomain; } - Task subWorkflowTask = new Task(); + TaskModel subWorkflowTask = new TaskModel(); subWorkflowTask.setTaskType(TASK_TYPE_SUB_WORKFLOW); subWorkflowTask.setTaskDefName(taskToSchedule.getName()); subWorkflowTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -93,7 +89,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { subWorkflowTask.getInputData().put("subWorkflowDefinition", subWorkflowDefinition); subWorkflowTask.getInputData().put("workflowInput", taskMapperContext.getTaskInput()); subWorkflowTask.setTaskId(taskId); - subWorkflowTask.setStatus(Task.Status.SCHEDULED); + subWorkflowTask.setStatus(TaskModel.Status.SCHEDULED); subWorkflowTask.setWorkflowTask(taskToSchedule); subWorkflowTask.setWorkflowPriority(workflowInstance.getPriority()); subWorkflowTask.setCallbackAfterSeconds(taskToSchedule.getStartDelay()); @@ -117,7 +113,7 @@ SubWorkflowParams getSubWorkflowParams(WorkflowTask taskToSchedule) { } private Map getSubWorkflowInputParameters( - Workflow workflowInstance, SubWorkflowParams subWorkflowParams) { + WorkflowModel workflowInstance, SubWorkflowParams subWorkflowParams) { Map params = new HashMap<>(); params.put("name", subWorkflowParams.getName()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/SwitchTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/SwitchTaskMapper.java index c53a4595ab..7f4d70aa18 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/SwitchTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/SwitchTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -22,19 +22,19 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.execution.evaluators.Evaluator; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#SWITCH} to a List {@link Task} starting with Task of type {@link TaskType#SWITCH} which - * is marked as IN_PROGRESS, followed by the list of {@link Task} based on the case expression - * evaluation in the Switch task. + * TaskType#SWITCH} to a List {@link TaskModel} starting with Task of type {@link TaskType#SWITCH} + * which is marked as IN_PROGRESS, followed by the list of {@link TaskModel} based on the case + * expression evaluation in the Switch task. */ @Component public class SwitchTaskMapper implements TaskMapper { @@ -58,10 +58,10 @@ public TaskType getTaskType() { * type {@link TaskType#SWITCH}. * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId * @return List of tasks in the following order: *

      - *
    • {@link TaskType#SWITCH} with {@link Task.Status#IN_PROGRESS} + *
    • {@link TaskType#SWITCH} with {@link TaskModel.Status#IN_PROGRESS} *
    • List of tasks based on the evaluation of {@link WorkflowTask#getEvaluatorType()} * and {@link WorkflowTask#getExpression()} are scheduled. *
    • In the case of no matching {@link WorkflowTask#getEvaluatorType()}, workflow will @@ -71,11 +71,11 @@ public TaskType getTaskType() { *
    */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in SwitchTaskMapper", taskMapperContext); - List tasksToBeScheduled = new LinkedList<>(); + List tasksToBeScheduled = new LinkedList<>(); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); Map taskInput = taskMapperContext.getTaskInput(); int retryCount = taskMapperContext.getRetryCount(); String taskId = taskMapperContext.getTaskId(); @@ -91,7 +91,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { String evalResult = "" + evaluator.evaluate(taskToSchedule.getExpression(), taskInput); // QQ why is the case value and the caseValue passed and caseOutput passes as the same ?? - Task switchTask = new Task(); + TaskModel switchTask = new TaskModel(); switchTask.setTaskType(TaskType.TASK_TYPE_SWITCH); switchTask.setTaskDefName(TaskType.TASK_TYPE_SWITCH); switchTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -103,7 +103,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { switchTask.getOutputData().put("evaluationResult", Collections.singletonList(evalResult)); switchTask.setTaskId(taskId); switchTask.setStartTime(System.currentTimeMillis()); - switchTask.setStatus(Task.Status.IN_PROGRESS); + switchTask.setStatus(TaskModel.Status.IN_PROGRESS); switchTask.setWorkflowTask(taskToSchedule); switchTask.setWorkflowPriority(workflowInstance.getPriority()); tasksToBeScheduled.add(switchTask); @@ -116,14 +116,13 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { selectedTasks = taskToSchedule.getDefaultCase(); } // once there are selected tasks that need to proceeded as part of the switch, get the next - // task to be - // scheduled by using the decider service + // task to be scheduled by using the decider service if (selectedTasks != null && !selectedTasks.isEmpty()) { WorkflowTask selectedTask = selectedTasks.get(0); // Schedule the first task to be executed... // TODO break out this recursive call using function composition of what needs to be // done and then walk back the condition tree - List caseTasks = + List caseTasks = taskMapperContext .getDeciderService() .getTasksToBeScheduled( diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/TaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/TaskMapper.java index b4c0d68587..016fe231b4 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/TaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/TaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -14,14 +14,14 @@ import java.util.List; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.core.exception.TerminateWorkflowException; +import com.netflix.conductor.model.TaskModel; public interface TaskMapper { TaskType getTaskType(); - List getMappedTasks(TaskMapperContext taskMapperContext) + List getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException; } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/TaskMapperContext.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/TaskMapperContext.java index 34c4293aa8..8303ee2b81 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/TaskMapperContext.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/TaskMapperContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,13 +17,13 @@ import com.netflix.conductor.common.metadata.tasks.TaskDef; 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.core.execution.DeciderService; +import com.netflix.conductor.model.WorkflowModel; /** Business Object class used for interaction between the DeciderService and Different Mappers */ public class TaskMapperContext { - private final Workflow workflowInstance; + private final WorkflowModel workflowInstance; private final TaskDef taskDefinition; private final WorkflowTask taskToSchedule; private final Map taskInput; @@ -65,7 +65,7 @@ public WorkflowDef getWorkflowDefinition() { return workflowInstance.getWorkflowDefinition(); } - public Workflow getWorkflowInstance() { + public WorkflowModel getWorkflowInstance() { return workflowInstance; } @@ -169,7 +169,7 @@ public int hashCode() { public static final class Builder { private WorkflowDef workflowDefinition; - private Workflow workflowInstance; + private WorkflowModel workflowInstance; private TaskDef taskDefinition; private WorkflowTask taskToSchedule; private Map taskInput; @@ -199,7 +199,7 @@ public Builder withWorkflowDefinition(WorkflowDef val) { * @param val the {@code workflowInstance} to set * @return a reference to this Builder */ - public Builder withWorkflowInstance(Workflow val) { + public Builder withWorkflowInstance(WorkflowModel val) { workflowInstance = val; return this; } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/TerminateTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/TerminateTaskMapper.java index 970d9513aa..0cc3c0f312 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/TerminateTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/TerminateTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -19,11 +19,11 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_TERMINATE; @@ -45,12 +45,12 @@ public TaskType getTaskType() { } @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { logger.debug("TaskMapperContext {} in TerminateTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); Map taskInput = @@ -60,7 +60,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { taskId, null); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType(TASK_TYPE_TERMINATE); task.setTaskDefName(taskToSchedule.getName()); task.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -71,7 +71,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { task.setStartTime(System.currentTimeMillis()); task.setInputData(taskInput); task.setTaskId(taskId); - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); task.setWorkflowTask(taskToSchedule); task.setWorkflowPriority(workflowInstance.getPriority()); return singletonList(task); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/UserDefinedTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/UserDefinedTaskMapper.java index 773f5bdd78..5451d086ba 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/UserDefinedTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/UserDefinedTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,20 +21,20 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#USER_DEFINED} to a {@link Task} of type {@link TaskType#USER_DEFINED} with {@link - * Task.Status#SCHEDULED} + * TaskType#USER_DEFINED} to a {@link TaskModel} of type {@link TaskType#USER_DEFINED} with {@link + * TaskModel.Status#SCHEDULED} */ @Component public class UserDefinedTaskMapper implements TaskMapper { @@ -56,21 +56,21 @@ public TaskType getTaskType() { /** * This method maps a {@link WorkflowTask} of type {@link TaskType#USER_DEFINED} to a {@link - * Task} in a {@link Task.Status#SCHEDULED} state + * TaskModel} in a {@link TaskModel.Status#SCHEDULED} state * * @param taskMapperContext: A wrapper class containing the {@link WorkflowTask}, {@link - * WorkflowDef}, {@link Workflow} and a string representation of the TaskId + * WorkflowDef}, {@link WorkflowModel} and a string representation of the TaskId * @return a List with just one User defined task * @throws TerminateWorkflowException In case if the task definition does not exist */ @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) + public List getMappedTasks(TaskMapperContext taskMapperContext) throws TerminateWorkflowException { LOGGER.debug("TaskMapperContext {} in UserDefinedTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); int retryCount = taskMapperContext.getRetryCount(); @@ -99,7 +99,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) taskId, taskDefinition); - Task userDefinedTask = new Task(); + TaskModel userDefinedTask = new TaskModel(); userDefinedTask.setTaskType(taskToSchedule.getType()); userDefinedTask.setTaskDefName(taskToSchedule.getName()); userDefinedTask.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -109,7 +109,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) userDefinedTask.setScheduledTime(System.currentTimeMillis()); userDefinedTask.setTaskId(taskId); userDefinedTask.setInputData(input); - userDefinedTask.setStatus(Task.Status.SCHEDULED); + userDefinedTask.setStatus(TaskModel.Status.SCHEDULED); userDefinedTask.setRetryCount(retryCount); userDefinedTask.setCallbackAfterSeconds(taskToSchedule.getStartDelay()); userDefinedTask.setWorkflowTask(taskToSchedule); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/mapper/WaitTaskMapper.java b/core/src/main/java/com/netflix/conductor/core/execution/mapper/WaitTaskMapper.java index e2035e2dcd..334f43541c 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/mapper/WaitTaskMapper.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/mapper/WaitTaskMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,18 +20,19 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.tasks.Wait; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_WAIT; /** * An implementation of {@link TaskMapper} to map a {@link WorkflowTask} of type {@link - * TaskType#WAIT} to a {@link Task} of type {@link Wait} with {@link Task.Status#IN_PROGRESS} + * TaskType#WAIT} to a {@link TaskModel} of type {@link Wait} with {@link + * TaskModel.Status#IN_PROGRESS} */ @Component public class WaitTaskMapper implements TaskMapper { @@ -50,12 +51,12 @@ public TaskType getTaskType() { } @Override - public List getMappedTasks(TaskMapperContext taskMapperContext) { + public List getMappedTasks(TaskMapperContext taskMapperContext) { LOGGER.debug("TaskMapperContext {} in WaitTaskMapper", taskMapperContext); WorkflowTask taskToSchedule = taskMapperContext.getTaskToSchedule(); - Workflow workflowInstance = taskMapperContext.getWorkflowInstance(); + WorkflowModel workflowInstance = taskMapperContext.getWorkflowInstance(); String taskId = taskMapperContext.getTaskId(); Map waitTaskInput = @@ -65,7 +66,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { taskId, null); - Task waitTask = new Task(); + TaskModel waitTask = new TaskModel(); waitTask.setTaskType(TASK_TYPE_WAIT); waitTask.setTaskDefName(taskMapperContext.getTaskToSchedule().getName()); waitTask.setReferenceTaskName(taskMapperContext.getTaskToSchedule().getTaskReferenceName()); @@ -75,7 +76,7 @@ public List getMappedTasks(TaskMapperContext taskMapperContext) { waitTask.setScheduledTime(System.currentTimeMillis()); waitTask.setInputData(waitTaskInput); waitTask.setTaskId(taskId); - waitTask.setStatus(Task.Status.IN_PROGRESS); + waitTask.setStatus(TaskModel.Status.IN_PROGRESS); waitTask.setWorkflowTask(taskToSchedule); waitTask.setWorkflowPriority(workflowInstance.getPriority()); return Collections.singletonList(waitTask); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Decision.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Decision.java index 9a48d3a0fc..0a96845f7f 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Decision.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Decision.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -14,10 +14,9 @@ import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_DECISION; @@ -35,8 +34,9 @@ public Decision() { } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { - task.setStatus(Status.COMPLETED); + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { + task.setStatus(TaskModel.Status.COMPLETED); return true; } } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/DoWhile.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/DoWhile.java index 1c141e3724..acd54aa08a 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/DoWhile.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/DoWhile.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,11 +12,7 @@ */ package com.netflix.conductor.core.execution.tasks; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import javax.script.ScriptException; @@ -25,15 +21,14 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.utils.TaskUtils; import com.netflix.conductor.core.events.ScriptEvaluator; import com.netflix.conductor.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.google.common.annotations.VisibleForTesting; @@ -52,12 +47,13 @@ public DoWhile(ParametersUtils parametersUtils) { } @Override - public void cancel(Workflow workflow, Task task, WorkflowExecutor executor) { - task.setStatus(Status.CANCELED); + public void cancel(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { + task.setStatus(TaskModel.Status.CANCELED); } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { boolean allDone = true; boolean hasFailures = false; @@ -69,9 +65,9 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx * Get the latest set of tasks (the ones that have the highest retry count). We don't want to evaluate any tasks * that have already failed if there is a more current one (a later retry count). */ - Map relevantTasks = new LinkedHashMap<>(); - Task relevantTask = null; - for (Task t : workflow.getTasks()) { + Map relevantTasks = new LinkedHashMap<>(); + TaskModel relevantTask = null; + for (TaskModel t : workflow.getTasks()) { if (task.getWorkflowTask() .has(TaskUtils.removeIterationFromTaskRefName(t.getReferenceTaskName())) && !task.getReferenceTaskName().equals(t.getReferenceTaskName())) { @@ -81,10 +77,10 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx } } } - Collection loopOver = relevantTasks.values(); + Collection loopOver = relevantTasks.values(); - for (Task loopOverTask : loopOver) { - Status taskStatus = loopOverTask.getStatus(); + for (TaskModel loopOverTask : loopOver) { + TaskModel.Status taskStatus = loopOverTask.getStatus(); hasFailures = !taskStatus.isSuccessful(); if (hasFailures) { failureReason.append(loopOverTask.getReasonForIncompletion()).append(" "); @@ -101,7 +97,7 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx if (hasFailures) { LOGGER.debug( "taskid {} failed in {} iteration", task.getTaskId(), task.getIteration() + 1); - return updateLoopTask(task, Status.FAILED, failureReason.toString()); + return updateLoopTask(task, TaskModel.Status.FAILED, failureReason.toString()); } else if (!allDone) { return false; } @@ -126,11 +122,12 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx task.getWorkflowTask().getLoopCondition(), e.getMessage()); LOGGER.error(message); LOGGER.error("Marking task {} failed with error.", task.getTaskId()); - return updateLoopTask(task, Status.FAILED_WITH_TERMINAL_ERROR, message); + return updateLoopTask(task, TaskModel.Status.FAILED_WITH_TERMINAL_ERROR, message); } } - boolean scheduleNextIteration(Task task, Workflow workflow, WorkflowExecutor workflowExecutor) { + boolean scheduleNextIteration( + TaskModel task, WorkflowModel workflow, WorkflowExecutor workflowExecutor) { LOGGER.debug( "Scheduling loop tasks for taskid {} as condition {} evaluated to true", task.getTaskId(), @@ -140,23 +137,24 @@ boolean scheduleNextIteration(Task task, Workflow workflow, WorkflowExecutor wor // execution DAO. } - boolean updateLoopTask(Task task, Status status, String failureReason) { + boolean updateLoopTask(TaskModel task, TaskModel.Status status, String failureReason) { task.setReasonForIncompletion(failureReason); task.setStatus(status); return true; } - boolean markLoopTaskSuccess(Task task) { + boolean markLoopTaskSuccess(TaskModel task) { LOGGER.debug( "taskid {} took {} iterations to complete", task.getTaskId(), task.getIteration() + 1); - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); return true; } @VisibleForTesting - boolean getEvaluatedCondition(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) + boolean getEvaluatedCondition( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) throws ScriptException { TaskDef taskDefinition = null; try { @@ -172,7 +170,7 @@ boolean getEvaluatedCondition(Workflow workflow, Task task, WorkflowExecutor wor task.getTaskId(), taskDefinition); taskInput.put(task.getReferenceTaskName(), task.getOutputData()); - List loopOver = + List loopOver = workflow.getTasks().stream() .filter( t -> @@ -186,7 +184,7 @@ boolean getEvaluatedCondition(Workflow workflow, Task task, WorkflowExecutor wor .equals(t.getReferenceTaskName()))) .collect(Collectors.toList()); - for (Task loopOverTask : loopOver) { + for (TaskModel loopOverTask : loopOver) { taskInput.put( TaskUtils.removeIterationFromTaskRefName(loopOverTask.getReferenceTaskName()), loopOverTask.getOutputData()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Event.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Event.java index b5e6b05e3e..2c18a5d4a7 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Event.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Event.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,15 +20,14 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.events.EventQueues; import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.core.events.queue.ObservableQueue; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -55,7 +54,7 @@ public Event( } @Override - public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public void start(WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { Map payload = new HashMap<>(task.getInputData()); payload.put("workflowInstanceId", workflow.getWorkflowId()); payload.put("workflowType", workflow.getWorkflowName()); @@ -69,14 +68,17 @@ public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecuto queue.publish(List.of(message)); LOGGER.debug("Published message:{} to queue:{}", message.getId(), queue.getName()); task.getOutputData().putAll(payload); - task.setStatus(isAsyncComplete(task) ? Status.IN_PROGRESS : Status.COMPLETED); + task.setStatus( + isAsyncComplete(task) + ? TaskModel.Status.IN_PROGRESS + : TaskModel.Status.COMPLETED); } catch (ApplicationException ae) { if (ae.isRetryable()) { LOGGER.info( "A transient backend error happened when task {} tried to publish an event.", task.getTaskId()); } else { - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setReasonForIncompletion(ae.getMessage()); LOGGER.error( "Error executing task: {}, workflow: {}", @@ -85,14 +87,14 @@ public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecuto ae); } } catch (JsonProcessingException jpe) { - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setReasonForIncompletion("Error serializing JSON payload: " + jpe.getMessage()); LOGGER.error( "Error serializing JSON payload for task: {}, workflow: {}", task.getTaskId(), workflow.getWorkflowId()); } catch (Exception e) { - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setReasonForIncompletion(e.getMessage()); LOGGER.error( "Error executing task: {}, workflow: {}", @@ -103,7 +105,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecuto } @Override - public void cancel(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public void cancel(WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { Message message = new Message(task.getTaskId(), null, task.getTaskId()); ObservableQueue queue = getQueue(workflow, task); queue.ack(List.of(message)); @@ -115,7 +117,7 @@ public boolean isAsync() { } @VisibleForTesting - ObservableQueue getQueue(Workflow workflow, Task task) { + ObservableQueue getQueue(WorkflowModel workflow, TaskModel task) { String sinkValueRaw = (String) task.getInputData().get("sink"); Map input = new HashMap<>(); input.put("sink", sinkValueRaw); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/ExclusiveJoin.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/ExclusiveJoin.java index 5a1e3a1dcb..e2bf0ac0bf 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/ExclusiveJoin.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/ExclusiveJoin.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -19,10 +19,10 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.utils.TaskUtils; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_EXCLUSIVE_JOIN; @@ -39,12 +39,13 @@ public ExclusiveJoin() { @Override @SuppressWarnings("unchecked") - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { boolean foundExlusiveJoinOnTask = false; boolean hasFailures = false; StringBuilder failureReason = new StringBuilder(); - Task.Status taskStatus; + TaskModel.Status taskStatus; List joinOn = (List) task.getInputData().get("joinOn"); if (task.isLoopOverTask()) { // If exclusive join is part of loop over task, wait for specific iteration to get @@ -54,11 +55,11 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx .map(name -> TaskUtils.appendIteration(name, task.getIteration())) .collect(Collectors.toList()); } - Task exclusiveTask = null; + TaskModel exclusiveTask = null; for (String joinOnRef : joinOn) { LOGGER.debug("Exclusive Join On Task {} ", joinOnRef); exclusiveTask = workflow.getTaskByRefName(joinOnRef); - if (exclusiveTask == null || exclusiveTask.getStatus() == Task.Status.SKIPPED) { + if (exclusiveTask == null || exclusiveTask.getStatus() == TaskModel.Status.SKIPPED) { LOGGER.debug("The task {} is either not scheduled or skipped.", joinOnRef); continue; } @@ -83,7 +84,8 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx for (String defaultExclusiveJoinTask : defaultExclusiveJoinTasks) { // Pick the first task that we should join on and break. exclusiveTask = workflow.getTaskByRefName(defaultExclusiveJoinTask); - if (exclusiveTask == null || exclusiveTask.getStatus() == Task.Status.SKIPPED) { + if (exclusiveTask == null + || exclusiveTask.getStatus() == TaskModel.Status.SKIPPED) { LOGGER.debug( "The task {} is either not scheduled or skipped.", defaultExclusiveJoinTask); @@ -111,10 +113,10 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx if (foundExlusiveJoinOnTask || hasFailures) { if (hasFailures) { task.setReasonForIncompletion(failureReason.toString()); - task.setStatus(Task.Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); } else { task.setOutputData(exclusiveTask.getOutputData()); - task.setStatus(Task.Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); } LOGGER.debug("Task: {} status is: {}", task.getTaskId(), task.getStatus()); return true; diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/ExecutionConfig.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/ExecutionConfig.java index 2add1390c6..890a33ebf5 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/ExecutionConfig.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/ExecutionConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Fork.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Fork.java index 3733839a09..9f31af7500 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Fork.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Fork.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Inline.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Inline.java index d6f6718ed8..ecfdbd7f6a 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Inline.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Inline.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -19,11 +19,11 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.evaluators.Evaluator; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_INLINE; @@ -67,7 +67,8 @@ public Inline(Map evaluators) { } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { Map taskInput = task.getInputData(); Map taskOutput = task.getOutputData(); String evaluatorType = (String) taskInput.get(QUERY_EVALUATOR_TYPE); @@ -79,14 +80,14 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx Evaluator evaluator = evaluators.get(evaluatorType); Object evalResult = evaluator.evaluate(expression, taskInput); taskOutput.put("result", evalResult); - task.setStatus(Task.Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); } catch (Exception e) { LOGGER.error( "Failed to execute Inline Task: {} in workflow: {}", task.getTaskId(), workflow.getWorkflowId(), e); - task.setStatus(Task.Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setReasonForIncompletion(e.getMessage()); taskOutput.put( "error", e.getCause() != null ? e.getCause().getMessage() : e.getMessage()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/IsolatedTaskQueueProducer.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/IsolatedTaskQueueProducer.java index da6427e406..9c8676b6e2 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/IsolatedTaskQueueProducer.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/IsolatedTaskQueueProducer.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Join.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Join.java index 04c87097f4..91c8ea94e2 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Join.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Join.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,11 +17,10 @@ import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.utils.TaskUtils; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_JOIN; @@ -34,7 +33,8 @@ public Join() { @Override @SuppressWarnings("unchecked") - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { boolean allDone = true; boolean hasFailures = false; @@ -48,13 +48,13 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx .collect(Collectors.toList()); } for (String joinOnRef : joinOn) { - Task forkedTask = workflow.getTaskByRefName(joinOnRef); + TaskModel forkedTask = workflow.getTaskByRefName(joinOnRef); if (forkedTask == null) { // Task is not even scheduled yet allDone = false; break; } - Status taskStatus = forkedTask.getStatus(); + TaskModel.Status taskStatus = forkedTask.getStatus(); hasFailures = !taskStatus.isSuccessful() && !forkedTask.getWorkflowTask().isOptional(); if (hasFailures) { failureReason.append(forkedTask.getReasonForIncompletion()).append(" "); @@ -70,9 +70,9 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx if (allDone || hasFailures) { if (hasFailures) { task.setReasonForIncompletion(failureReason.toString()); - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); } else { - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); } return true; } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Lambda.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Lambda.java index 8b9a9b82d7..8f8aae6b7b 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Lambda.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Lambda.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -19,10 +19,10 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.events.ScriptEvaluator; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_LAMBDA; @@ -63,7 +63,8 @@ public Lambda() { } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { Map taskInput = task.getInputData(); Map taskOutput = task.getOutputData(); String scriptExpression; @@ -79,14 +80,14 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx task.getTaskId()); Object returnValue = ScriptEvaluator.eval(scriptExpressionBuilder, taskInput); taskOutput.put("result", returnValue); - task.setStatus(Task.Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); } else { LOGGER.error("Empty {} in Lambda task. ", QUERY_EXPRESSION_PARAMETER); task.setReasonForIncompletion( "Empty '" + QUERY_EXPRESSION_PARAMETER + "' in Lambda task's input parameters. A non-empty String value must be provided."); - task.setStatus(Task.Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); } } catch (Exception e) { LOGGER.error( @@ -94,7 +95,7 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx task.getTaskId(), workflow.getWorkflowId(), e); - task.setStatus(Task.Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setReasonForIncompletion(e.getMessage()); taskOutput.put( "error", e.getCause() != null ? e.getCause().getMessage() : e.getMessage()); diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SetVariable.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SetVariable.java index fa9fb9455c..2bdcbfb7d0 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SetVariable.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SetVariable.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -22,11 +22,11 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -47,7 +47,7 @@ public SetVariable(ConductorProperties properties, ObjectMapper objectMapper) { } private boolean validateVariablesSize( - Workflow workflow, Task task, Map variables) { + WorkflowModel workflow, TaskModel task, Map variables) { String workflowId = workflow.getWorkflowId(); long maxThreshold = properties.getMaxWorkflowVariablesPayloadSizeThreshold().toKilobytes(); @@ -74,7 +74,7 @@ private boolean validateVariablesSize( } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor provider) { + public boolean execute(WorkflowModel workflow, TaskModel task, WorkflowExecutor provider) { Map variables = workflow.getVariables(); Map input = task.getInputData(); String taskId = task.getTaskId(); @@ -105,12 +105,12 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor provider) variables.put(key, previousValues.get(key)); }); newKeys.forEach(variables::remove); - task.setStatus(Task.Status.FAILED_WITH_TERMINAL_ERROR); + task.setStatus(TaskModel.Status.FAILED_WITH_TERMINAL_ERROR); return true; } } - task.setStatus(Task.Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); return true; } } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SubWorkflow.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SubWorkflow.java index 8bc6514dd3..e4c0497561 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SubWorkflow.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SubWorkflow.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -19,13 +19,11 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; -import com.netflix.conductor.common.run.Workflow.WorkflowStatus; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -46,7 +44,7 @@ public SubWorkflow(ObjectMapper objectMapper) { @SuppressWarnings("unchecked") @Override - public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public void start(WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { Map input = task.getInputData(); String name = input.get("subWorkflowName").toString(); int version = (int) input.get("subWorkflowVersion"); @@ -105,7 +103,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecuto // Set task status based on current sub-workflow status, as the status can change in // recursion by the time we update here. - Workflow subWorkflow = workflowExecutor.getWorkflow(subWorkflowId, false); + WorkflowModel subWorkflow = workflowExecutor.getWorkflow(subWorkflowId, false); updateTaskStatus(subWorkflow, task); } catch (ApplicationException ae) { if (ae.isRetryable()) { @@ -115,7 +113,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecuto workflow.toShortString(), name); } else { - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setReasonForIncompletion(ae.getMessage()); LOGGER.error( "Error starting sub workflow: {} from workflow: {}", @@ -124,7 +122,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecuto ae); } } catch (Exception e) { - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setReasonForIncompletion(e.getMessage()); LOGGER.error( "Error starting sub workflow: {} from workflow: {}", @@ -135,14 +133,15 @@ public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecuto } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { String workflowId = task.getSubWorkflowId(); if (StringUtils.isEmpty(workflowId)) { return false; } - Workflow subWorkflow = workflowExecutor.getWorkflow(workflowId, false); - WorkflowStatus subWorkflowStatus = subWorkflow.getStatus(); + WorkflowModel subWorkflow = workflowExecutor.getWorkflow(workflowId, false); + WorkflowModel.Status subWorkflowStatus = subWorkflow.getStatus(); if (!subWorkflowStatus.isTerminal()) { return false; } @@ -152,13 +151,13 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx } @Override - public void cancel(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public void cancel(WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { String workflowId = task.getSubWorkflowId(); if (StringUtils.isEmpty(workflowId)) { return; } - Workflow subWorkflow = workflowExecutor.getWorkflow(workflowId, true); - subWorkflow.setStatus(WorkflowStatus.TERMINATED); + WorkflowModel subWorkflow = workflowExecutor.getWorkflow(workflowId, true); + subWorkflow.setStatus(WorkflowModel.Status.TERMINATED); String reason = StringUtils.isEmpty(workflow.getReasonForIncompletion()) ? "Parent workflow has been terminated with status " + workflow.getStatus() @@ -181,28 +180,28 @@ public boolean isAsync() { * @return */ @Override - public boolean isAsyncComplete(Task task) { + public boolean isAsyncComplete(TaskModel task) { return true; } - private void updateTaskStatus(Workflow subworkflow, Task task) { - WorkflowStatus status = subworkflow.getStatus(); + private void updateTaskStatus(WorkflowModel subworkflow, TaskModel task) { + WorkflowModel.Status status = subworkflow.getStatus(); switch (status) { case RUNNING: case PAUSED: - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); break; case COMPLETED: - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); break; case FAILED: - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); break; case TERMINATED: - task.setStatus(Status.CANCELED); + task.setStatus(TaskModel.Status.CANCELED); break; case TIMED_OUT: - task.setStatus(Status.TIMED_OUT); + task.setStatus(TaskModel.Status.TIMED_OUT); break; default: throw new ApplicationException( diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Switch.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Switch.java index 3b6bedac58..2d3d040a25 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Switch.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Switch.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -14,10 +14,9 @@ import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_SWITCH; @@ -30,8 +29,9 @@ public Switch() { } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { - task.setStatus(Status.COMPLETED); + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { + task.setStatus(TaskModel.Status.COMPLETED); return true; } } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskRegistry.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskRegistry.java index 3fa78a7dcb..4486680e85 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskRegistry.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskWorker.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskWorker.java index 4d12eaa7aa..04ac69d555 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskWorker.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskWorker.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskWorkerCoordinator.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskWorkerCoordinator.java index a7acd1332c..6992727a14 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskWorkerCoordinator.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/SystemTaskWorkerCoordinator.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Terminate.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Terminate.java index a950b3380f..4d3481a246 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Terminate.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Terminate.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,9 +17,9 @@ import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_TERMINATE; import static com.netflix.conductor.common.run.Workflow.WorkflowStatus.COMPLETED; @@ -66,16 +66,17 @@ public Terminate() { } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { String returnStatus = (String) task.getInputData().get(TERMINATION_STATUS_PARAMETER); if (validateInputStatus(returnStatus)) { task.setOutputData(getInputFromParam(task.getInputData())); - task.setStatus(Task.Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); return true; } task.setReasonForIncompletion("given termination status is not valid"); - task.setStatus(Task.Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); return false; } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Wait.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Wait.java index f43b748a50..1cbf76b229 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/Wait.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/Wait.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -14,10 +14,9 @@ import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_WAIT; @@ -29,17 +28,18 @@ public Wait() { } @Override - public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { - task.setStatus(Status.IN_PROGRESS); + public void start(WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { + task.setStatus(TaskModel.Status.IN_PROGRESS); } @Override - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { return false; } @Override - public void cancel(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { - task.setStatus(Status.CANCELED); + public void cancel(WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { + task.setStatus(TaskModel.Status.CANCELED); } } diff --git a/core/src/main/java/com/netflix/conductor/core/execution/tasks/WorkflowSystemTask.java b/core/src/main/java/com/netflix/conductor/core/execution/tasks/WorkflowSystemTask.java index 64098e11ee..b23b77c6e5 100644 --- a/core/src/main/java/com/netflix/conductor/core/execution/tasks/WorkflowSystemTask.java +++ b/core/src/main/java/com/netflix/conductor/core/execution/tasks/WorkflowSystemTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -14,10 +14,10 @@ import java.util.Optional; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; public abstract class WorkflowSystemTask { @@ -36,22 +36,23 @@ public WorkflowSystemTask(String taskType) { * @param task Instance of the Task * @param workflowExecutor Workflow Executor */ - public void start(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public void start(WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { // Do nothing unless overridden by the task implementation } /** * "Execute" the task. * - *

    Called after {@link #start(Workflow, Task, WorkflowExecutor)}, if the task status is not - * terminal. Can be called more than once. + *

    Called after {@link #start(WorkflowModel, TaskModel, WorkflowExecutor)}, if the task + * status is not terminal. Can be called more than once. * * @param workflow Workflow for which the task is being started * @param task Instance of the Task * @param workflowExecutor Workflow Executor * @return true, if the execution has changed the task status. return false otherwise. */ - public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) { + public boolean execute( + WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) { return false; } @@ -62,7 +63,7 @@ public boolean execute(Workflow workflow, Task task, WorkflowExecutor workflowEx * @param task Instance of the Task * @param workflowExecutor Workflow Executor */ - public void cancel(Workflow workflow, Task task, WorkflowExecutor workflowExecutor) {} + public void cancel(WorkflowModel workflow, TaskModel task, WorkflowExecutor workflowExecutor) {} /** @return True if the task is supposed to be started asynchronously using internal queues. */ public boolean isAsync() { @@ -73,7 +74,7 @@ public boolean isAsync() { * @return True to keep task in 'IN_PROGRESS' state, and 'COMPLETE' later by an external * message. */ - public boolean isAsyncComplete(Task task) { + public boolean isAsyncComplete(TaskModel task) { if (task.getInputData().containsKey("asyncComplete")) { return Optional.ofNullable(task.getInputData().get("asyncComplete")) .map(result -> (Boolean) result) diff --git a/core/src/main/java/com/netflix/conductor/core/listener/WorkflowStatusListener.java b/core/src/main/java/com/netflix/conductor/core/listener/WorkflowStatusListener.java index 2507c86d65..1c0c4395a2 100644 --- a/core/src/main/java/com/netflix/conductor/core/listener/WorkflowStatusListener.java +++ b/core/src/main/java/com/netflix/conductor/core/listener/WorkflowStatusListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,32 +12,32 @@ */ package com.netflix.conductor.core.listener; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.model.WorkflowModel; /** Listener for the completed and terminated workflows */ public interface WorkflowStatusListener { - default void onWorkflowCompletedIfEnabled(Workflow workflow) { + default void onWorkflowCompletedIfEnabled(WorkflowModel workflow) { if (workflow.getWorkflowDefinition().isWorkflowStatusListenerEnabled()) { onWorkflowCompleted(workflow); } } - default void onWorkflowTerminatedIfEnabled(Workflow workflow) { + default void onWorkflowTerminatedIfEnabled(WorkflowModel workflow) { if (workflow.getWorkflowDefinition().isWorkflowStatusListenerEnabled()) { onWorkflowTerminated(workflow); } } - default void onWorkflowFinalizedIfEnabled(Workflow workflow) { + default void onWorkflowFinalizedIfEnabled(WorkflowModel workflow) { if (workflow.getWorkflowDefinition().isWorkflowStatusListenerEnabled()) { onWorkflowFinalized(workflow); } } - void onWorkflowCompleted(Workflow workflow); + void onWorkflowCompleted(WorkflowModel workflow); - void onWorkflowTerminated(Workflow workflow); + void onWorkflowTerminated(WorkflowModel workflow); - default void onWorkflowFinalized(Workflow workflow) {} + default void onWorkflowFinalized(WorkflowModel workflow) {} } diff --git a/core/src/main/java/com/netflix/conductor/core/listener/WorkflowStatusListenerStub.java b/core/src/main/java/com/netflix/conductor/core/listener/WorkflowStatusListenerStub.java index 1c72942297..36bb5e6998 100644 --- a/core/src/main/java/com/netflix/conductor/core/listener/WorkflowStatusListenerStub.java +++ b/core/src/main/java/com/netflix/conductor/core/listener/WorkflowStatusListenerStub.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -15,7 +15,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.model.WorkflowModel; /** Stub listener default implementation */ public class WorkflowStatusListenerStub implements WorkflowStatusListener { @@ -23,17 +23,17 @@ public class WorkflowStatusListenerStub implements WorkflowStatusListener { private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowStatusListenerStub.class); @Override - public void onWorkflowCompleted(Workflow workflow) { + public void onWorkflowCompleted(WorkflowModel workflow) { LOGGER.debug("Workflow {} is completed", workflow.getWorkflowId()); } @Override - public void onWorkflowTerminated(Workflow workflow) { + public void onWorkflowTerminated(WorkflowModel workflow) { LOGGER.debug("Workflow {} is terminated", workflow.getWorkflowId()); } @Override - public void onWorkflowFinalized(Workflow workflow) { + public void onWorkflowFinalized(WorkflowModel workflow) { LOGGER.debug("Workflow {} is finalized", workflow.getWorkflowId()); } } diff --git a/core/src/main/java/com/netflix/conductor/core/metadata/MetadataMapperService.java b/core/src/main/java/com/netflix/conductor/core/metadata/MetadataMapperService.java index 7166d72b1f..bd761c3b25 100644 --- a/core/src/main/java/com/netflix/conductor/core/metadata/MetadataMapperService.java +++ b/core/src/main/java/com/netflix/conductor/core/metadata/MetadataMapperService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,17 +21,17 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.SubWorkflowParams; 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.core.WorkflowContext; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.exception.TerminateWorkflowException; import com.netflix.conductor.dao.MetadataDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; @@ -93,7 +93,7 @@ Optional lookupLatestWorkflowDefinition(String workflowName) { return metadataDAO.getLatestWorkflowDef(workflowName); } - public Workflow populateWorkflowWithDefinitions(Workflow workflow) { + public WorkflowModel populateWorkflowWithDefinitions(WorkflowModel workflow) { Preconditions.checkNotNull(workflow, "workflow cannot be null"); WorkflowDef workflowDefinition = Optional.ofNullable(workflow.getWorkflowDefinition()) @@ -178,7 +178,7 @@ private void checkNotEmptyDefinitions(WorkflowDef workflowDefinition) { } } - public Task populateTaskWithDefinition(Task task) { + public TaskModel populateTaskWithDefinition(TaskModel task) { Preconditions.checkNotNull(task, "Task cannot be null"); populateWorkflowTaskWithDefinition(task.getWorkflowTask()); return task; diff --git a/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowReconciler.java b/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowReconciler.java index 88cafc6b69..05086f341e 100644 --- a/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowReconciler.java +++ b/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowReconciler.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -26,13 +26,12 @@ import com.netflix.conductor.dao.QueueDAO; import com.netflix.conductor.metrics.Monitors; -import static com.netflix.conductor.core.execution.WorkflowExecutor.DECIDER_QUEUE; +import static com.netflix.conductor.core.utils.Utils.DECIDER_QUEUE; /** * Periodically polls all running workflows in the system and evaluates them for timeouts and/or * maintain consistency. */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component @ConditionalOnProperty( name = "conductor.workflow-reconciler.enabled", diff --git a/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowRepairService.java b/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowRepairService.java index 4f148ffd4b..5ac05e24f0 100644 --- a/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowRepairService.java +++ b/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowRepairService.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,16 +21,16 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.config.ConductorProperties; -import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.tasks.SystemTaskRegistry; import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; import com.netflix.conductor.core.utils.QueueUtils; +import com.netflix.conductor.core.utils.Utils; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.dao.QueueDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.google.common.annotations.VisibleForTesting; @@ -42,7 +42,6 @@ * QueueDAO#containsMessage(String, String)} method. This can be controlled with * conductor.workflow-repair-service.enabled property. */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Service @ConditionalOnProperty(name = "conductor.workflow-repair-service.enabled", havingValue = "true") public class WorkflowRepairService { @@ -58,7 +57,7 @@ public class WorkflowRepairService { and in SCHEDULED or IN_PROGRESS state. (Example: SUB_WORKFLOW tasks in SCHEDULED state) For simple task -> Verify the task is in SCHEDULED state. */ - private final Predicate isTaskRepairable = + private final Predicate isTaskRepairable = task -> { if (systemTaskRegistry.isSystemTask(task.getTaskType())) { // If system task WorkflowSystemTask workflowSystemTask = @@ -66,11 +65,11 @@ public class WorkflowRepairService { return workflowSystemTask.isAsync() && (!workflowSystemTask.isAsyncComplete(task) || (workflowSystemTask.isAsyncComplete(task) - && task.getStatus() == Task.Status.SCHEDULED)) - && (task.getStatus() == Task.Status.IN_PROGRESS - || task.getStatus() == Task.Status.SCHEDULED); + && task.getStatus() == TaskModel.Status.SCHEDULED)) + && (task.getStatus() == TaskModel.Status.IN_PROGRESS + || task.getStatus() == TaskModel.Status.SCHEDULED); } else { // Else if simple task - return task.getStatus() == Task.Status.SCHEDULED; + return task.getStatus() == TaskModel.Status.SCHEDULED; } }; @@ -91,22 +90,18 @@ public WorkflowRepairService( * has relevant message in the queue. */ public boolean verifyAndRepairWorkflow(String workflowId, boolean includeTasks) { - Workflow workflow = executionDAO.getWorkflow(workflowId, includeTasks); + WorkflowModel workflow = executionDAO.getWorkflow(workflowId, includeTasks); AtomicBoolean repaired = new AtomicBoolean(false); repaired.set(verifyAndRepairDeciderQueue(workflow)); if (includeTasks) { - workflow.getTasks() - .forEach( - task -> { - repaired.set(verifyAndRepairTask(task)); - }); + workflow.getTasks().forEach(task -> repaired.set(verifyAndRepairTask(task))); } return repaired.get(); } /** Verify and repair tasks in a workflow. */ public void verifyAndRepairWorkflowTasks(String workflowId) { - Workflow workflow = executionDAO.getWorkflow(workflowId, true); + WorkflowModel workflow = executionDAO.getWorkflow(workflowId, true); workflow.getTasks().forEach(this::verifyAndRepairTask); // repair the parent workflow if needed verifyAndRepairWorkflow(workflow.getParentWorkflowId()); @@ -117,7 +112,7 @@ public void verifyAndRepairWorkflowTasks(String workflowId) { * * @return true - if the workflow was queued for repair */ - private boolean verifyAndRepairDeciderQueue(Workflow workflow) { + private boolean verifyAndRepairDeciderQueue(WorkflowModel workflow) { if (!workflow.getStatus().isTerminal()) { return verifyAndRepairWorkflow(workflow.getWorkflowId()); } @@ -127,11 +122,11 @@ private boolean verifyAndRepairDeciderQueue(Workflow workflow) { /** * Verify if ExecutionDAO and QueueDAO agree for the provided task. * - * @param task + * @param task the task to be repaired * @return true - if the task was queued for repair */ @VisibleForTesting - boolean verifyAndRepairTask(Task task) { + boolean verifyAndRepairTask(TaskModel task) { if (isTaskRepairable.test(task)) { // Ensure QueueDAO contains this taskId String taskQueueName = QueueUtils.getQueueName(task); @@ -150,7 +145,7 @@ boolean verifyAndRepairTask(Task task) { private boolean verifyAndRepairWorkflow(String workflowId) { if (StringUtils.isNotEmpty(workflowId)) { - String queueName = WorkflowExecutor.DECIDER_QUEUE; + String queueName = Utils.DECIDER_QUEUE; if (!queueDAO.containsMessage(queueName, workflowId)) { queueDAO.push( queueName, workflowId, properties.getWorkflowOffsetTimeout().getSeconds()); diff --git a/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowSweeper.java b/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowSweeper.java index 8168c3a7d5..e21894da1b 100644 --- a/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowSweeper.java +++ b/core/src/main/java/com/netflix/conductor/core/reconciliation/WorkflowSweeper.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -29,9 +29,8 @@ import com.netflix.conductor.metrics.Monitors; import static com.netflix.conductor.core.config.SchedulerConfiguration.SWEEPER_EXECUTOR_NAME; -import static com.netflix.conductor.core.execution.WorkflowExecutor.DECIDER_QUEUE; +import static com.netflix.conductor.core.utils.Utils.DECIDER_QUEUE; -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component public class WorkflowSweeper { diff --git a/core/src/main/java/com/netflix/conductor/core/storage/DummyPayloadStorage.java b/core/src/main/java/com/netflix/conductor/core/storage/DummyPayloadStorage.java index 802d6979fa..47c94c761f 100644 --- a/core/src/main/java/com/netflix/conductor/core/storage/DummyPayloadStorage.java +++ b/core/src/main/java/com/netflix/conductor/core/storage/DummyPayloadStorage.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/sync/Lock.java b/core/src/main/java/com/netflix/conductor/core/sync/Lock.java index b77a4caa0d..cb8d5ccd43 100644 --- a/core/src/main/java/com/netflix/conductor/core/sync/Lock.java +++ b/core/src/main/java/com/netflix/conductor/core/sync/Lock.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -43,7 +43,7 @@ public interface Lock { * @param lockId resource to lock on * @param timeToTry blocks up to timeToTry duration in attempt to acquire the lock * @param unit time unit - * @return + * @return true, if successfully acquired */ boolean acquireLock(String lockId, long timeToTry, TimeUnit unit); @@ -55,7 +55,7 @@ public interface Lock { * @param timeToTry blocks up to timeToTry duration in attempt to acquire the lock * @param leaseTime Lock lease expiration duration. * @param unit time unit - * @return + * @return true, if successfully acquired */ boolean acquireLock(String lockId, long timeToTry, long leaseTime, TimeUnit unit); diff --git a/core/src/main/java/com/netflix/conductor/core/sync/NoopLock.java b/core/src/main/java/com/netflix/conductor/core/sync/NoopLock.java index 9990d37e62..912a23c429 100644 --- a/core/src/main/java/com/netflix/conductor/core/sync/NoopLock.java +++ b/core/src/main/java/com/netflix/conductor/core/sync/NoopLock.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/utils/ExternalPayloadStorageUtils.java b/core/src/main/java/com/netflix/conductor/core/utils/ExternalPayloadStorageUtils.java index 605c1bc5d9..fb0b137353 100644 --- a/core/src/main/java/com/netflix/conductor/core/utils/ExternalPayloadStorageUtils.java +++ b/core/src/main/java/com/netflix/conductor/core/utils/ExternalPayloadStorageUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -25,21 +25,20 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.run.ExternalStorageLocation; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.utils.ExternalPayloadStorage; import com.netflix.conductor.common.utils.ExternalPayloadStorage.PayloadType; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.exception.TerminateWorkflowException; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.annotations.VisibleForTesting; /** Provides utility functions to upload and download payloads to {@link ExternalPayloadStorage} */ -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Component public class ExternalPayloadStorageUtils { @@ -81,7 +80,7 @@ public Map downloadPayload(String path) { * * @param entity the task or workflow for which the payload is to be verified and uploaded * @param payloadType the {@link PayloadType} of the payload - * @param {@link Task} or {@link Workflow} + * @param {@link TaskModel} or {@link WorkflowModel} * @throws ApplicationException in case of JSON parsing errors or upload errors * @throws TerminateWorkflowException if the payload size is bigger than permissible limit as * per {@link ConductorProperties} @@ -95,26 +94,26 @@ public void verifyAndUpload(T entity, PayloadType payloadType) { case TASK_INPUT: threshold = properties.getTaskInputPayloadSizeThreshold().toKilobytes(); maxThreshold = properties.getMaxTaskInputPayloadSizeThreshold().toKilobytes(); - payload = ((Task) entity).getInputData(); - workflowId = ((Task) entity).getWorkflowInstanceId(); + payload = ((TaskModel) entity).getInputData(); + workflowId = ((TaskModel) entity).getWorkflowInstanceId(); break; case TASK_OUTPUT: threshold = properties.getTaskOutputPayloadSizeThreshold().toKilobytes(); maxThreshold = properties.getMaxTaskOutputPayloadSizeThreshold().toKilobytes(); - payload = ((Task) entity).getOutputData(); - workflowId = ((Task) entity).getWorkflowInstanceId(); + payload = ((TaskModel) entity).getOutputData(); + workflowId = ((TaskModel) entity).getWorkflowInstanceId(); break; case WORKFLOW_INPUT: threshold = properties.getWorkflowInputPayloadSizeThreshold().toKilobytes(); maxThreshold = properties.getMaxWorkflowInputPayloadSizeThreshold().toKilobytes(); - payload = ((Workflow) entity).getInput(); - workflowId = ((Workflow) entity).getWorkflowId(); + payload = ((WorkflowModel) entity).getInput(); + workflowId = ((WorkflowModel) entity).getWorkflowId(); break; case WORKFLOW_OUTPUT: threshold = properties.getWorkflowOutputPayloadSizeThreshold().toKilobytes(); maxThreshold = properties.getMaxWorkflowOutputPayloadSizeThreshold().toKilobytes(); - payload = ((Workflow) entity).getOutput(); - workflowId = ((Workflow) entity).getWorkflowId(); + payload = ((WorkflowModel) entity).getOutput(); + workflowId = ((WorkflowModel) entity).getWorkflowId(); break; } @@ -124,71 +123,73 @@ public void verifyAndUpload(T entity, PayloadType payloadType) { long payloadSize = payloadBytes.length; if (payloadSize > maxThreshold * 1024) { - if (entity instanceof Task) { + if (entity instanceof TaskModel) { String errorMsg = String.format( "The payload size: %dB of task: %s in workflow: %s is greater than the permissible limit: %dKB", payloadSize, - ((Task) entity).getTaskId(), - ((Task) entity).getWorkflowInstanceId(), + ((TaskModel) entity).getTaskId(), + ((TaskModel) entity).getWorkflowInstanceId(), maxThreshold); - failTask(((Task) entity), payloadType, errorMsg); + failTask(((TaskModel) entity), payloadType, errorMsg); } else { String errorMsg = String.format( "The output payload size: %dB of workflow: %s is greater than the permissible limit: %dKB", - payloadSize, ((Workflow) entity).getWorkflowId(), maxThreshold); - failWorkflow(((Workflow) entity), payloadType, errorMsg); + payloadSize, + ((WorkflowModel) entity).getWorkflowId(), + maxThreshold); + failWorkflow(((WorkflowModel) entity), payloadType, errorMsg); } } else if (payloadSize > threshold * 1024) { switch (payloadType) { case TASK_INPUT: - ((Task) entity).setInputData(new HashMap<>()); - ((Task) entity) + ((TaskModel) entity).setInputData(new HashMap<>()); + ((TaskModel) entity) .setExternalInputPayloadStoragePath( uploadHelper( payloadBytes, payloadSize, PayloadType.TASK_INPUT)); Monitors.recordExternalPayloadStorageUsage( - ((Task) entity).getTaskDefName(), + ((TaskModel) entity).getTaskDefName(), ExternalPayloadStorage.Operation.WRITE.toString(), PayloadType.TASK_INPUT.toString()); break; case TASK_OUTPUT: - ((Task) entity).setOutputData(new HashMap<>()); - ((Task) entity) + ((TaskModel) entity).setOutputData(new HashMap<>()); + ((TaskModel) entity) .setExternalOutputPayloadStoragePath( uploadHelper( payloadBytes, payloadSize, PayloadType.TASK_OUTPUT)); Monitors.recordExternalPayloadStorageUsage( - ((Task) entity).getTaskDefName(), + ((TaskModel) entity).getTaskDefName(), ExternalPayloadStorage.Operation.WRITE.toString(), PayloadType.TASK_OUTPUT.toString()); break; case WORKFLOW_INPUT: - ((Workflow) entity).setInput(new HashMap<>()); - ((Workflow) entity) + ((WorkflowModel) entity).setInput(new HashMap<>()); + ((WorkflowModel) entity) .setExternalInputPayloadStoragePath( uploadHelper( payloadBytes, payloadSize, PayloadType.WORKFLOW_INPUT)); Monitors.recordExternalPayloadStorageUsage( - ((Workflow) entity).getWorkflowName(), + ((WorkflowModel) entity).getWorkflowName(), ExternalPayloadStorage.Operation.WRITE.toString(), PayloadType.WORKFLOW_INPUT.toString()); break; case WORKFLOW_OUTPUT: - ((Workflow) entity).setOutput(new HashMap<>()); - ((Workflow) entity) + ((WorkflowModel) entity).setOutput(new HashMap<>()); + ((WorkflowModel) entity) .setExternalOutputPayloadStoragePath( uploadHelper( payloadBytes, payloadSize, PayloadType.WORKFLOW_OUTPUT)); Monitors.recordExternalPayloadStorageUsage( - ((Workflow) entity).getWorkflowName(), + ((WorkflowModel) entity).getWorkflowName(), ExternalPayloadStorage.Operation.WRITE.toString(), PayloadType.WORKFLOW_OUTPUT.toString()); break; @@ -213,20 +214,20 @@ String uploadHelper( } @VisibleForTesting - void failTask(Task task, PayloadType payloadType, String errorMsg) { + void failTask(TaskModel task, PayloadType payloadType, String errorMsg) { LOGGER.error(errorMsg); task.setReasonForIncompletion(errorMsg); - task.setStatus(Task.Status.FAILED_WITH_TERMINAL_ERROR); + task.setStatus(TaskModel.Status.FAILED_WITH_TERMINAL_ERROR); if (payloadType == PayloadType.TASK_INPUT) { task.setInputData(new HashMap<>()); } else { task.setOutputData(new HashMap<>()); } - throw new TerminateWorkflowException(errorMsg, Workflow.WorkflowStatus.FAILED, task); + throw new TerminateWorkflowException(errorMsg, WorkflowModel.Status.FAILED, task); } @VisibleForTesting - void failWorkflow(Workflow workflow, PayloadType payloadType, String errorMsg) { + void failWorkflow(WorkflowModel workflow, PayloadType payloadType, String errorMsg) { LOGGER.error(errorMsg); if (payloadType == PayloadType.WORKFLOW_INPUT) { workflow.setInput(new HashMap<>()); diff --git a/core/src/main/java/com/netflix/conductor/core/utils/IDGenerator.java b/core/src/main/java/com/netflix/conductor/core/utils/IDGenerator.java index 4502b2d7e8..bc09f10112 100644 --- a/core/src/main/java/com/netflix/conductor/core/utils/IDGenerator.java +++ b/core/src/main/java/com/netflix/conductor/core/utils/IDGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/utils/JsonUtils.java b/core/src/main/java/com/netflix/conductor/core/utils/JsonUtils.java index 1eb5ae30fa..38f70218c7 100644 --- a/core/src/main/java/com/netflix/conductor/core/utils/JsonUtils.java +++ b/core/src/main/java/com/netflix/conductor/core/utils/JsonUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/utils/ParametersUtils.java b/core/src/main/java/com/netflix/conductor/core/utils/ParametersUtils.java index bb64e01b17..b7397807df 100644 --- a/core/src/main/java/com/netflix/conductor/core/utils/ParametersUtils.java +++ b/core/src/main/java/com/netflix/conductor/core/utils/ParametersUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -25,12 +25,12 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.utils.EnvUtils; import com.netflix.conductor.common.utils.TaskUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -47,8 +47,7 @@ public class ParametersUtils { private static final Logger LOGGER = LoggerFactory.getLogger(ParametersUtils.class); private final ObjectMapper objectMapper; - private final TypeReference> map = - new TypeReference>() {}; + private final TypeReference> map = new TypeReference<>() {}; public ParametersUtils(ObjectMapper objectMapper) { this.objectMapper = objectMapper; @@ -56,7 +55,7 @@ public ParametersUtils(ObjectMapper objectMapper) { public Map getTaskInput( Map inputParams, - Workflow workflow, + WorkflowModel workflow, TaskDef taskDefinition, String taskId) { if (workflow.getWorkflowDefinition().getSchemaVersion() > 1) { @@ -66,7 +65,10 @@ public Map getTaskInput( } public Map getTaskInputV2( - Map input, Workflow workflow, String taskId, TaskDef taskDefinition) { + Map input, + WorkflowModel workflow, + String taskId, + TaskDef taskDefinition) { Map inputParams; if (input != null) { @@ -98,7 +100,7 @@ public Map getTaskInputV2( // For new workflow being started the list of tasks will be empty workflow.getTasks().stream() - .map(Task::getReferenceTaskName) + .map(TaskModel::getReferenceTaskName) .map(workflow::getTaskByRefName) .forEach( task -> { @@ -273,45 +275,42 @@ private Object replaceVariables( @Deprecated // Workflow schema version 1 is deprecated and new workflows should be using version 2 - private Map getTaskInputV1(Workflow workflow, Map inputParams) { + private Map getTaskInputV1( + WorkflowModel workflow, Map inputParams) { Map input = new HashMap<>(); if (inputParams == null) { return input; } Map workflowInput = workflow.getInput(); - inputParams - .entrySet() - .forEach( - e -> { - String paramName = e.getKey(); - String paramPath = "" + e.getValue(); - String[] paramPathComponents = paramPath.split("\\."); - Preconditions.checkArgument( - paramPathComponents.length == 3, - "Invalid input expression for " - + paramName - + ", paramPathComponents.size=" - + paramPathComponents.length - + ", expression=" - + paramPath); + inputParams.forEach( + (paramName, value) -> { + String paramPath = "" + value; + String[] paramPathComponents = paramPath.split("\\."); + Preconditions.checkArgument( + paramPathComponents.length == 3, + "Invalid input expression for " + + paramName + + ", paramPathComponents.size=" + + paramPathComponents.length + + ", expression=" + + paramPath); - String source = - paramPathComponents[0]; // workflow, or task reference name - String type = paramPathComponents[1]; // input/output - String name = paramPathComponents[2]; // name of the parameter - if ("workflow".equals(source)) { - input.put(paramName, workflowInput.get(name)); + String source = paramPathComponents[0]; // workflow, or task reference name + String type = paramPathComponents[1]; // input/output + String name = paramPathComponents[2]; // name of the parameter + if ("workflow".equals(source)) { + input.put(paramName, workflowInput.get(name)); + } else { + TaskModel task = workflow.getTaskByRefName(source); + if (task != null) { + if ("input".equals(type)) { + input.put(paramName, task.getInputData().get(name)); } else { - Task task = workflow.getTaskByRefName(source); - if (task != null) { - if ("input".equals(type)) { - input.put(paramName, task.getInputData().get(name)); - } else { - input.put(paramName, task.getOutputData().get(name)); - } - } + input.put(paramName, task.getOutputData().get(name)); } - }); + } + } + }); return input; } diff --git a/core/src/main/java/com/netflix/conductor/core/utils/QueueUtils.java b/core/src/main/java/com/netflix/conductor/core/utils/QueueUtils.java index 8b457c3f04..b381ec4685 100644 --- a/core/src/main/java/com/netflix/conductor/core/utils/QueueUtils.java +++ b/core/src/main/java/com/netflix/conductor/core/utils/QueueUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -15,6 +15,7 @@ import org.apache.commons.lang3.StringUtils; import com.netflix.conductor.common.metadata.tasks.Task; +import com.netflix.conductor.model.TaskModel; public class QueueUtils { @@ -22,6 +23,14 @@ public class QueueUtils { private static final String ISOLATION_SEPARATOR = "-"; private static final String EXECUTION_NAME_SPACE_SEPARATOR = "@"; + public static String getQueueName(TaskModel taskModel) { + return getQueueName( + taskModel.getTaskType(), + taskModel.getDomain(), + taskModel.getIsolationGroupId(), + taskModel.getExecutionNameSpace()); + } + public static String getQueueName(Task task) { return getQueueName( task.getTaskType(), diff --git a/core/src/main/java/com/netflix/conductor/core/utils/SemaphoreUtil.java b/core/src/main/java/com/netflix/conductor/core/utils/SemaphoreUtil.java index 2acdc91a4b..001067d06f 100644 --- a/core/src/main/java/com/netflix/conductor/core/utils/SemaphoreUtil.java +++ b/core/src/main/java/com/netflix/conductor/core/utils/SemaphoreUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/core/utils/Utils.java b/core/src/main/java/com/netflix/conductor/core/utils/Utils.java index 83b2d2a175..013f7dc950 100644 --- a/core/src/main/java/com/netflix/conductor/core/utils/Utils.java +++ b/core/src/main/java/com/netflix/conductor/core/utils/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -28,6 +28,8 @@ public class Utils { + public static final String DECIDER_QUEUE = "_deciderQueue"; + /** * ID of the server. Can be host name, IP address or any other meaningful identifier * diff --git a/core/src/main/java/com/netflix/conductor/dao/ConcurrentExecutionLimitDAO.java b/core/src/main/java/com/netflix/conductor/dao/ConcurrentExecutionLimitDAO.java index 64f0e43b3d..853a72e633 100644 --- a/core/src/main/java/com/netflix/conductor/dao/ConcurrentExecutionLimitDAO.java +++ b/core/src/main/java/com/netflix/conductor/dao/ConcurrentExecutionLimitDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,8 +12,8 @@ */ package com.netflix.conductor.dao; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; +import com.netflix.conductor.model.TaskModel; /** * A contract to support concurrency limits of tasks. @@ -22,12 +22,12 @@ */ public interface ConcurrentExecutionLimitDAO { - default void addTaskToLimit(Task task) { + default void addTaskToLimit(TaskModel task) { throw new UnsupportedOperationException( getClass() + " does not support addTaskToLimit method."); } - default void removeTaskFromLimit(Task task) { + default void removeTaskFromLimit(TaskModel task) { throw new UnsupportedOperationException( getClass() + " does not support removeTaskFromLimit method."); } @@ -41,5 +41,5 @@ default void removeTaskFromLimit(Task task) { * @return true if by executing this task, the limit is breached. false otherwise. * @see TaskDef#concurrencyLimit() */ - boolean exceedsLimit(Task task); + boolean exceedsLimit(TaskModel task); } diff --git a/core/src/main/java/com/netflix/conductor/dao/EventHandlerDAO.java b/core/src/main/java/com/netflix/conductor/dao/EventHandlerDAO.java index 8918a54b7f..fa32024db8 100644 --- a/core/src/main/java/com/netflix/conductor/dao/EventHandlerDAO.java +++ b/core/src/main/java/com/netflix/conductor/dao/EventHandlerDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/dao/ExecutionDAO.java b/core/src/main/java/com/netflix/conductor/dao/ExecutionDAO.java index fdb4dd42b7..967551e6be 100644 --- a/core/src/main/java/com/netflix/conductor/dao/ExecutionDAO.java +++ b/core/src/main/java/com/netflix/conductor/dao/ExecutionDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -15,9 +15,9 @@ import java.util.List; import com.netflix.conductor.common.metadata.events.EventExecution; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; /** Data access layer for storing workflow executions */ public interface ExecutionDAO { @@ -27,7 +27,7 @@ public interface ExecutionDAO { * @param workflowId Workflow instance id * @return List of pending tasks (in_progress) */ - List getPendingTasksByWorkflow(String taskName, String workflowId); + List getPendingTasksByWorkflow(String taskName, String workflowId); /** * @param taskType Type of task @@ -35,7 +35,7 @@ public interface ExecutionDAO { * @param count number of tasks to return * @return List of tasks starting from startKey */ - List getTasks(String taskType, String startKey, int count); + List getTasks(String taskType, String startKey, int count); /** * @param tasks tasks to be created @@ -45,10 +45,10 @@ public interface ExecutionDAO { * key. Given two tasks with the same reference name and retryCount only one should be added * to the database. */ - List createTasks(List tasks); + List createTasks(List tasks); /** @param task Task to be updated */ - void updateTask(Task task); + void updateTask(TaskModel task); /** * Checks if the number of tasks in progress for the given taskDef will exceed the limit if the @@ -58,10 +58,10 @@ public interface ExecutionDAO { * @param task The task to be executed. Limit is set in the Task's definition * @return true if by executing this task, the limit is breached. false otherwise. * @see TaskDef#concurrencyLimit() - * @deprecated Since v3.3.5. Use {@link ConcurrentExecutionLimitDAO#exceedsLimit(Task)}. + * @deprecated Since v3.3.5. Use {@link ConcurrentExecutionLimitDAO#exceedsLimit(TaskModel)}. */ @Deprecated - default boolean exceedsInProgressLimit(Task task) { + default boolean exceedsInProgressLimit(TaskModel task) { throw new UnsupportedOperationException( getClass() + "does not support exceedsInProgressLimit"); } @@ -76,37 +76,37 @@ default boolean exceedsInProgressLimit(Task task) { * @param taskId Task instance id * @return Task */ - Task getTask(String taskId); + TaskModel getTask(String taskId); /** * @param taskIds Task instance ids * @return List of tasks */ - List getTasks(List taskIds); + List getTasks(List taskIds); /** * @param taskType Type of the task for which to retrieve the list of pending tasks * @return List of pending tasks */ - List getPendingTasksForTaskType(String taskType); + List getPendingTasksForTaskType(String taskType); /** * @param workflowId Workflow instance id * @return List of tasks for the given workflow instance id */ - List getTasksForWorkflow(String workflowId); + List getTasksForWorkflow(String workflowId); /** * @param workflow Workflow to be created * @return Id of the newly created workflow */ - String createWorkflow(Workflow workflow); + String createWorkflow(WorkflowModel workflow); /** * @param workflow Workflow to be updated * @return Id of the updated workflow */ - String updateWorkflow(Workflow workflow); + String updateWorkflow(WorkflowModel workflow); /** * @param workflowId workflow instance id @@ -133,7 +133,7 @@ default boolean exceedsInProgressLimit(Task task) { * @param workflowId workflow instance id * @return Workflow */ - Workflow getWorkflow(String workflowId); + WorkflowModel getWorkflow(String workflowId); /** * @param workflowId workflow instance id @@ -141,7 +141,7 @@ default boolean exceedsInProgressLimit(Task task) { * Sequence number in Workflow. * @return Workflow instance details */ - Workflow getWorkflow(String workflowId, boolean includeTasks); + WorkflowModel getWorkflow(String workflowId, boolean includeTasks); /** * @param workflowName name of the workflow @@ -155,7 +155,7 @@ default boolean exceedsInProgressLimit(Task task) { * @param version the workflow version * @return List of workflows that are running */ - List getPendingWorkflowsByType(String workflowName, int version); + List getPendingWorkflowsByType(String workflowName, int version); /** * @param workflowName Name of the workflow @@ -175,7 +175,7 @@ default boolean exceedsInProgressLimit(Task task) { * @param endTime epoch time * @return List of workflows between start and end time */ - List getWorkflowsByType(String workflowName, Long startTime, Long endTime); + List getWorkflowsByType(String workflowName, Long startTime, Long endTime); /** * @param workflowName workflow name @@ -183,7 +183,7 @@ default boolean exceedsInProgressLimit(Task task) { * @param includeTasks Option to includeTasks in results * @return List of workflows by correlation id */ - List getWorkflowsByCorrelationId( + List getWorkflowsByCorrelationId( String workflowName, String correlationId, boolean includeTasks); /** diff --git a/core/src/main/java/com/netflix/conductor/dao/IndexDAO.java b/core/src/main/java/com/netflix/conductor/dao/IndexDAO.java index 9f84a1457b..876f0d8dc2 100644 --- a/core/src/main/java/com/netflix/conductor/dao/IndexDAO.java +++ b/core/src/main/java/com/netflix/conductor/dao/IndexDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -16,10 +16,10 @@ import java.util.concurrent.CompletableFuture; import com.netflix.conductor.common.metadata.events.EventExecution; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.run.SearchResult; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.common.run.TaskSummary; +import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.core.events.queue.Message; /** DAO to index the workflow and task details for searching. */ @@ -33,7 +33,7 @@ public interface IndexDAO { * * @param workflow Workflow to be indexed */ - void indexWorkflow(Workflow workflow); + void indexWorkflow(WorkflowSummary workflow); /** * This method should return an unique identifier of the indexed doc @@ -41,16 +41,16 @@ public interface IndexDAO { * @param workflow Workflow to be indexed * @return CompletableFuture of type void */ - CompletableFuture asyncIndexWorkflow(Workflow workflow); + CompletableFuture asyncIndexWorkflow(WorkflowSummary workflow); /** @param task Task to be indexed */ - void indexTask(Task task); + void indexTask(TaskSummary task); /** * @param task Task to be indexed asynchronously * @return CompletableFuture of type void */ - CompletableFuture asyncIndexTask(Task task); + CompletableFuture asyncIndexTask(TaskSummary task); /** * @param query SQL like query for workflow search parameters. diff --git a/core/src/main/java/com/netflix/conductor/dao/MetadataDAO.java b/core/src/main/java/com/netflix/conductor/dao/MetadataDAO.java index 247e6575ce..e6e203c6df 100644 --- a/core/src/main/java/com/netflix/conductor/dao/MetadataDAO.java +++ b/core/src/main/java/com/netflix/conductor/dao/MetadataDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/dao/PollDataDAO.java b/core/src/main/java/com/netflix/conductor/dao/PollDataDAO.java index 2d06f9af1e..d53d6660db 100644 --- a/core/src/main/java/com/netflix/conductor/dao/PollDataDAO.java +++ b/core/src/main/java/com/netflix/conductor/dao/PollDataDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/dao/QueueDAO.java b/core/src/main/java/com/netflix/conductor/dao/QueueDAO.java index fbcd614f7e..d14c7cfb43 100644 --- a/core/src/main/java/com/netflix/conductor/dao/QueueDAO.java +++ b/core/src/main/java/com/netflix/conductor/dao/QueueDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/dao/RateLimitingDAO.java b/core/src/main/java/com/netflix/conductor/dao/RateLimitingDAO.java index 2d465b0f47..6ef4b48593 100644 --- a/core/src/main/java/com/netflix/conductor/dao/RateLimitingDAO.java +++ b/core/src/main/java/com/netflix/conductor/dao/RateLimitingDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,19 +12,19 @@ */ package com.netflix.conductor.dao; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; +import com.netflix.conductor.model.TaskModel; /** An abstraction to enable different Rate Limiting implementations */ public interface RateLimitingDAO { /** * Checks if the Task is rate limited or not based on the {@link - * Task#getRateLimitPerFrequency()} and {@link Task#getRateLimitFrequencyInSeconds()} + * TaskModel#getRateLimitPerFrequency()} and {@link TaskModel#getRateLimitFrequencyInSeconds()} * * @param task: which needs to be evaluated whether it is rateLimited or not - * @return true: If the {@link Task} is rateLimited false: If the {@link Task} is not + * @return true: If the {@link TaskModel} is rateLimited false: If the {@link TaskModel} is not * rateLimited */ - boolean exceedsRateLimitPerFrequency(Task task, TaskDef taskDef); + boolean exceedsRateLimitPerFrequency(TaskModel task, TaskDef taskDef); } diff --git a/core/src/main/java/com/netflix/conductor/metrics/Monitors.java b/core/src/main/java/com/netflix/conductor/metrics/Monitors.java index f65c42078a..5dc6d0fc75 100644 --- a/core/src/main/java/com/netflix/conductor/metrics/Monitors.java +++ b/core/src/main/java/com/netflix/conductor/metrics/Monitors.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -19,9 +19,8 @@ import org.apache.commons.lang3.StringUtils; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow.WorkflowStatus; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.spectator.api.Counter; import com.netflix.spectator.api.DistributionSummary; import com.netflix.spectator.api.Gauge; @@ -175,7 +174,7 @@ public static void recordQueueWaitTime(String taskType, long queueWaitTime) { } public static void recordTaskExecutionTime( - String taskType, long duration, boolean includesRetries, Task.Status status) { + String taskType, long duration, boolean includesRetries, TaskModel.Status status) { getTimer( classQualifier, "task_execution", @@ -284,7 +283,7 @@ public static void recordTaskPendingTime(String taskType, String workflowType, l } public static void recordWorkflowTermination( - String workflowType, WorkflowStatus status, String ownerApp) { + String workflowType, WorkflowModel.Status status, String ownerApp) { counter( classQualifier, "workflow_failure", @@ -320,7 +319,7 @@ public static void recordWorkflowStartError(String workflowType, String ownerApp } public static void recordUpdateConflict( - String taskType, String workflowType, WorkflowStatus status) { + String taskType, String workflowType, WorkflowModel.Status status) { counter( classQualifier, "task_update_conflict", @@ -332,7 +331,8 @@ public static void recordUpdateConflict( status.name()); } - public static void recordUpdateConflict(String taskType, String workflowType, Status status) { + public static void recordUpdateConflict( + String taskType, String workflowType, TaskModel.Status status) { counter( classQualifier, "task_update_conflict", @@ -536,7 +536,7 @@ public static void recordAcquireLockFailure(String exceptionClassName) { counter(classQualifier, "acquire_lock_failure", "exceptionType", exceptionClassName); } - public static void recordWorkflowArchived(String workflowType, WorkflowStatus status) { + public static void recordWorkflowArchived(String workflowType, WorkflowModel.Status status) { counter( classQualifier, "workflow_archived", diff --git a/core/src/main/java/com/netflix/conductor/metrics/WorkflowMonitor.java b/core/src/main/java/com/netflix/conductor/metrics/WorkflowMonitor.java index 52ea65b502..fdcb39ee00 100644 --- a/core/src/main/java/com/netflix/conductor/metrics/WorkflowMonitor.java +++ b/core/src/main/java/com/netflix/conductor/metrics/WorkflowMonitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -26,8 +26,8 @@ import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; import com.netflix.conductor.dao.QueueDAO; import com.netflix.conductor.service.MetadataService; diff --git a/core/src/main/java/com/netflix/conductor/model/TaskModel.java b/core/src/main/java/com/netflix/conductor/model/TaskModel.java new file mode 100644 index 0000000000..6b3c1573ae --- /dev/null +++ b/core/src/main/java/com/netflix/conductor/model/TaskModel.java @@ -0,0 +1,735 @@ +/* + * Copyright 2022 Netflix, Inc. + *

    + * 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.model; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; + +import com.netflix.conductor.common.metadata.tasks.Task; +import com.netflix.conductor.common.metadata.tasks.TaskDef; +import com.netflix.conductor.common.metadata.workflow.WorkflowTask; + +import com.google.protobuf.Any; + +public class TaskModel { + + public enum Status { + IN_PROGRESS(false, true, true), + CANCELED(true, false, false), + FAILED(true, false, true), + FAILED_WITH_TERMINAL_ERROR(true, false, false), + COMPLETED(true, true, true), + COMPLETED_WITH_ERRORS(true, true, true), + SCHEDULED(false, true, true), + TIMED_OUT(true, false, true), + SKIPPED(true, true, false); + + private final boolean terminal; + + private final boolean successful; + + private final boolean retriable; + + Status(boolean terminal, boolean successful, boolean retriable) { + this.terminal = terminal; + this.successful = successful; + this.retriable = retriable; + } + + public boolean isTerminal() { + return terminal; + } + + public boolean isSuccessful() { + return successful; + } + + public boolean isRetriable() { + return retriable; + } + + public static Task.Status getTaskStatusDTO(Status status) { + return Task.Status.valueOf(status.name()); + } + } + + private String taskType; + + private Status status; + + private Map inputData = new HashMap<>(); + + private String referenceTaskName; + + private int retryCount; + + private int seq; + + private String correlationId; + + private int pollCount; + + private String taskDefName; + + /** Time when the task was scheduled */ + private long scheduledTime; + + /** Time when the task was first polled */ + private long startTime; + + /** Time when the task completed executing */ + private long endTime; + + /** Time when the task was last updated */ + private long updateTime; + + private int startDelayInSeconds; + + private String retriedTaskId; + + private boolean retried; + + private boolean executed; + + private boolean callbackFromWorker = true; + + private long responseTimeoutSeconds; + + private String workflowInstanceId; + + private String workflowType; + + private String taskId; + + private String reasonForIncompletion; + + private long callbackAfterSeconds; + + private String workerId; + + private Map outputData = new HashMap<>(); + + private WorkflowTask workflowTask; + + private String domain; + + private Any inputMessage; + + private Any outputMessage; + + // id 31 is reserved + + private int rateLimitPerFrequency; + + private int rateLimitFrequencyInSeconds; + + private String externalInputPayloadStoragePath; + + private String externalOutputPayloadStoragePath; + + private int workflowPriority; + + private String executionNameSpace; + + private String isolationGroupId; + + private int iteration; + + private String subWorkflowId; + + /** + * Use to note that a sub workflow associated with SUB_WORKFLOW task has an action performed on + * it directly. + */ + private boolean subworkflowChanged; + + public String getTaskType() { + return taskType; + } + + public void setTaskType(String taskType) { + this.taskType = taskType; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public Map getInputData() { + return inputData; + } + + public void setInputData(Map inputData) { + if (inputData == null) { + inputData = new HashMap<>(); + } + this.inputData = inputData; + } + + public String getReferenceTaskName() { + return referenceTaskName; + } + + public void setReferenceTaskName(String referenceTaskName) { + this.referenceTaskName = referenceTaskName; + } + + public int getRetryCount() { + return retryCount; + } + + public void setRetryCount(int retryCount) { + this.retryCount = retryCount; + } + + public int getSeq() { + return seq; + } + + public void setSeq(int seq) { + this.seq = seq; + } + + public String getCorrelationId() { + return correlationId; + } + + public void setCorrelationId(String correlationId) { + this.correlationId = correlationId; + } + + public int getPollCount() { + return pollCount; + } + + public void setPollCount(int pollCount) { + this.pollCount = pollCount; + } + + public String getTaskDefName() { + if (taskDefName == null || "".equals(taskDefName)) { + taskDefName = taskType; + } + return taskDefName; + } + + public void setTaskDefName(String taskDefName) { + this.taskDefName = taskDefName; + } + + public long getScheduledTime() { + return scheduledTime; + } + + public void setScheduledTime(long scheduledTime) { + this.scheduledTime = scheduledTime; + } + + public long getStartTime() { + return startTime; + } + + public void setStartTime(long startTime) { + this.startTime = startTime; + } + + public long getEndTime() { + return endTime; + } + + public void setEndTime(long endTime) { + this.endTime = endTime; + } + + public long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(long updateTime) { + this.updateTime = updateTime; + } + + public int getStartDelayInSeconds() { + return startDelayInSeconds; + } + + public void setStartDelayInSeconds(int startDelayInSeconds) { + this.startDelayInSeconds = startDelayInSeconds; + } + + public String getRetriedTaskId() { + return retriedTaskId; + } + + public void setRetriedTaskId(String retriedTaskId) { + this.retriedTaskId = retriedTaskId; + } + + public boolean isRetried() { + return retried; + } + + public void setRetried(boolean retried) { + this.retried = retried; + } + + public boolean isExecuted() { + return executed; + } + + public void setExecuted(boolean executed) { + this.executed = executed; + } + + public boolean isCallbackFromWorker() { + return callbackFromWorker; + } + + public void setCallbackFromWorker(boolean callbackFromWorker) { + this.callbackFromWorker = callbackFromWorker; + } + + public long getResponseTimeoutSeconds() { + return responseTimeoutSeconds; + } + + public void setResponseTimeoutSeconds(long responseTimeoutSeconds) { + this.responseTimeoutSeconds = responseTimeoutSeconds; + } + + public String getWorkflowInstanceId() { + return workflowInstanceId; + } + + public void setWorkflowInstanceId(String workflowInstanceId) { + this.workflowInstanceId = workflowInstanceId; + } + + public String getWorkflowType() { + return workflowType; + } + + public void setWorkflowType(String workflowType) { + this.workflowType = workflowType; + } + + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } + + public String getReasonForIncompletion() { + return reasonForIncompletion; + } + + public void setReasonForIncompletion(String reasonForIncompletion) { + this.reasonForIncompletion = reasonForIncompletion; + } + + public long getCallbackAfterSeconds() { + return callbackAfterSeconds; + } + + public void setCallbackAfterSeconds(long callbackAfterSeconds) { + this.callbackAfterSeconds = callbackAfterSeconds; + } + + public String getWorkerId() { + return workerId; + } + + public void setWorkerId(String workerId) { + this.workerId = workerId; + } + + public Map getOutputData() { + return outputData; + } + + public void setOutputData(Map outputData) { + if (outputData == null) { + outputData = new HashMap<>(); + } + this.outputData = outputData; + } + + public WorkflowTask getWorkflowTask() { + return workflowTask; + } + + public void setWorkflowTask(WorkflowTask workflowTask) { + this.workflowTask = workflowTask; + } + + public String getDomain() { + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public Any getInputMessage() { + return inputMessage; + } + + public void setInputMessage(Any inputMessage) { + this.inputMessage = inputMessage; + } + + public Any getOutputMessage() { + return outputMessage; + } + + public void setOutputMessage(Any outputMessage) { + this.outputMessage = outputMessage; + } + + public int getRateLimitPerFrequency() { + return rateLimitPerFrequency; + } + + public void setRateLimitPerFrequency(int rateLimitPerFrequency) { + this.rateLimitPerFrequency = rateLimitPerFrequency; + } + + public int getRateLimitFrequencyInSeconds() { + return rateLimitFrequencyInSeconds; + } + + public void setRateLimitFrequencyInSeconds(int rateLimitFrequencyInSeconds) { + this.rateLimitFrequencyInSeconds = rateLimitFrequencyInSeconds; + } + + public String getExternalInputPayloadStoragePath() { + return externalInputPayloadStoragePath; + } + + public void setExternalInputPayloadStoragePath(String externalInputPayloadStoragePath) { + this.externalInputPayloadStoragePath = externalInputPayloadStoragePath; + } + + public String getExternalOutputPayloadStoragePath() { + return externalOutputPayloadStoragePath; + } + + public void setExternalOutputPayloadStoragePath(String externalOutputPayloadStoragePath) { + this.externalOutputPayloadStoragePath = externalOutputPayloadStoragePath; + } + + public int getWorkflowPriority() { + return workflowPriority; + } + + public void setWorkflowPriority(int workflowPriority) { + this.workflowPriority = workflowPriority; + } + + public String getExecutionNameSpace() { + return executionNameSpace; + } + + public void setExecutionNameSpace(String executionNameSpace) { + this.executionNameSpace = executionNameSpace; + } + + public String getIsolationGroupId() { + return isolationGroupId; + } + + public void setIsolationGroupId(String isolationGroupId) { + this.isolationGroupId = isolationGroupId; + } + + public int getIteration() { + return iteration; + } + + public void setIteration(int iteration) { + this.iteration = iteration; + } + + public String getSubWorkflowId() { + // For backwards compatibility + if (StringUtils.isNotBlank(subWorkflowId)) { + return subWorkflowId; + } else { + return this.getOutputData() != null && this.getOutputData().get("subWorkflowId") != null + ? (String) this.getOutputData().get("subWorkflowId") + : this.getInputData() != null + ? (String) this.getInputData().get("subWorkflowId") + : null; + } + } + + public void setSubWorkflowId(String subWorkflowId) { + this.subWorkflowId = subWorkflowId; + // For backwards compatibility + if (this.getOutputData() != null && this.getOutputData().containsKey("subWorkflowId")) { + this.getOutputData().put("subWorkflowId", subWorkflowId); + } + } + + public boolean isSubworkflowChanged() { + return subworkflowChanged; + } + + public void setSubworkflowChanged(boolean subworkflowChanged) { + this.subworkflowChanged = subworkflowChanged; + } + + public void incrementPollCount() { + ++this.pollCount; + } + + /** @return {@link Optional} containing the task definition if available */ + public Optional getTaskDefinition() { + return Optional.ofNullable(this.getWorkflowTask()).map(WorkflowTask::getTaskDefinition); + } + + public boolean isLoopOverTask() { + return iteration > 0; + } + + /** @return the queueWaitTime */ + public long getQueueWaitTime() { + if (this.startTime > 0 && this.scheduledTime > 0) { + if (this.updateTime > 0 && getCallbackAfterSeconds() > 0) { + long waitTime = + System.currentTimeMillis() + - (this.updateTime + (getCallbackAfterSeconds() * 1000)); + return waitTime > 0 ? waitTime : 0; + } else { + return this.startTime - this.scheduledTime; + } + } + return 0L; + } + + /** @return a deep copy of the task instance */ + public TaskModel copy() { + TaskModel copy = new TaskModel(); + BeanUtils.copyProperties(this, copy); + return copy; + } + + @Override + public String toString() { + return "TaskModel{" + + "taskType='" + + taskType + + '\'' + + ", status=" + + status + + ", inputData=" + + inputData + + ", referenceTaskName='" + + referenceTaskName + + '\'' + + ", retryCount=" + + retryCount + + ", seq=" + + seq + + ", correlationId='" + + correlationId + + '\'' + + ", pollCount=" + + pollCount + + ", taskDefName='" + + taskDefName + + '\'' + + ", scheduledTime=" + + scheduledTime + + ", startTime=" + + startTime + + ", endTime=" + + endTime + + ", updateTime=" + + updateTime + + ", startDelayInSeconds=" + + startDelayInSeconds + + ", retriedTaskId='" + + retriedTaskId + + '\'' + + ", retried=" + + retried + + ", executed=" + + executed + + ", callbackFromWorker=" + + callbackFromWorker + + ", responseTimeoutSeconds=" + + responseTimeoutSeconds + + ", workflowInstanceId='" + + workflowInstanceId + + '\'' + + ", workflowType='" + + workflowType + + '\'' + + ", taskId='" + + taskId + + '\'' + + ", reasonForIncompletion='" + + reasonForIncompletion + + '\'' + + ", callbackAfterSeconds=" + + callbackAfterSeconds + + ", workerId='" + + workerId + + '\'' + + ", outputData=" + + outputData + + ", workflowTask=" + + workflowTask + + ", domain='" + + domain + + '\'' + + ", inputMessage=" + + inputMessage + + ", outputMessage=" + + outputMessage + + ", rateLimitPerFrequency=" + + rateLimitPerFrequency + + ", rateLimitFrequencyInSeconds=" + + rateLimitFrequencyInSeconds + + ", externalInputPayloadStoragePath='" + + externalInputPayloadStoragePath + + '\'' + + ", externalOutputPayloadStoragePath='" + + externalOutputPayloadStoragePath + + '\'' + + ", workflowPriority=" + + workflowPriority + + ", executionNameSpace='" + + executionNameSpace + + '\'' + + ", isolationGroupId='" + + isolationGroupId + + '\'' + + ", iteration=" + + iteration + + ", subWorkflowId='" + + subWorkflowId + + '\'' + + ", subworkflowChanged=" + + subworkflowChanged + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + TaskModel taskModel = (TaskModel) o; + return getRetryCount() == taskModel.getRetryCount() + && getSeq() == taskModel.getSeq() + && getPollCount() == taskModel.getPollCount() + && getScheduledTime() == taskModel.getScheduledTime() + && getStartTime() == taskModel.getStartTime() + && getEndTime() == taskModel.getEndTime() + && getUpdateTime() == taskModel.getUpdateTime() + && getStartDelayInSeconds() == taskModel.getStartDelayInSeconds() + && isRetried() == taskModel.isRetried() + && isExecuted() == taskModel.isExecuted() + && isCallbackFromWorker() == taskModel.isCallbackFromWorker() + && getResponseTimeoutSeconds() == taskModel.getResponseTimeoutSeconds() + && getCallbackAfterSeconds() == taskModel.getCallbackAfterSeconds() + && getRateLimitPerFrequency() == taskModel.getRateLimitPerFrequency() + && getRateLimitFrequencyInSeconds() == taskModel.getRateLimitFrequencyInSeconds() + && getWorkflowPriority() == taskModel.getWorkflowPriority() + && getIteration() == taskModel.getIteration() + && isSubworkflowChanged() == taskModel.isSubworkflowChanged() + && Objects.equals(getTaskType(), taskModel.getTaskType()) + && getStatus() == taskModel.getStatus() + && Objects.equals(getInputData(), taskModel.getInputData()) + && Objects.equals(getReferenceTaskName(), taskModel.getReferenceTaskName()) + && Objects.equals(getCorrelationId(), taskModel.getCorrelationId()) + && Objects.equals(getTaskDefName(), taskModel.getTaskDefName()) + && Objects.equals(getRetriedTaskId(), taskModel.getRetriedTaskId()) + && Objects.equals(getWorkflowInstanceId(), taskModel.getWorkflowInstanceId()) + && Objects.equals(getWorkflowType(), taskModel.getWorkflowType()) + && Objects.equals(getTaskId(), taskModel.getTaskId()) + && Objects.equals(getReasonForIncompletion(), taskModel.getReasonForIncompletion()) + && Objects.equals(getWorkerId(), taskModel.getWorkerId()) + && Objects.equals(getOutputData(), taskModel.getOutputData()) + && Objects.equals(getWorkflowTask(), taskModel.getWorkflowTask()) + && Objects.equals(getDomain(), taskModel.getDomain()) + && Objects.equals(getInputMessage(), taskModel.getInputMessage()) + && Objects.equals(getOutputMessage(), taskModel.getOutputMessage()) + && Objects.equals( + getExternalInputPayloadStoragePath(), + taskModel.getExternalInputPayloadStoragePath()) + && Objects.equals( + getExternalOutputPayloadStoragePath(), + taskModel.getExternalOutputPayloadStoragePath()) + && Objects.equals(getExecutionNameSpace(), taskModel.getExecutionNameSpace()) + && Objects.equals(getIsolationGroupId(), taskModel.getIsolationGroupId()) + && Objects.equals(getSubWorkflowId(), taskModel.getSubWorkflowId()); + } + + @Override + public int hashCode() { + return Objects.hash( + getTaskType(), + getStatus(), + getInputData(), + getReferenceTaskName(), + getRetryCount(), + getSeq(), + getCorrelationId(), + getPollCount(), + getTaskDefName(), + getScheduledTime(), + getStartTime(), + getEndTime(), + getUpdateTime(), + getStartDelayInSeconds(), + getRetriedTaskId(), + isRetried(), + isExecuted(), + isCallbackFromWorker(), + getResponseTimeoutSeconds(), + getWorkflowInstanceId(), + getWorkflowType(), + getTaskId(), + getReasonForIncompletion(), + getCallbackAfterSeconds(), + getWorkerId(), + getOutputData(), + getWorkflowTask(), + getDomain(), + getInputMessage(), + getOutputMessage(), + getRateLimitPerFrequency(), + getRateLimitFrequencyInSeconds(), + getExternalInputPayloadStoragePath(), + getExternalOutputPayloadStoragePath(), + getWorkflowPriority(), + getExecutionNameSpace(), + getIsolationGroupId(), + getIteration(), + getSubWorkflowId(), + isSubworkflowChanged()); + } +} diff --git a/core/src/main/java/com/netflix/conductor/model/WorkflowModel.java b/core/src/main/java/com/netflix/conductor/model/WorkflowModel.java new file mode 100644 index 0000000000..65d2d58872 --- /dev/null +++ b/core/src/main/java/com/netflix/conductor/model/WorkflowModel.java @@ -0,0 +1,448 @@ +/* + * Copyright 2022 Netflix, Inc. + *

    + * 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.model; + +import java.util.*; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.BeanUtils; + +import com.netflix.conductor.common.metadata.workflow.WorkflowDef; + +import com.google.common.base.Preconditions; + +public class WorkflowModel { + + public enum Status { + RUNNING(false, false), + COMPLETED(true, true), + FAILED(true, false), + TIMED_OUT(true, false), + TERMINATED(true, false), + PAUSED(false, true); + + private final boolean terminal; + private final boolean successful; + + Status(boolean terminal, boolean successful) { + this.terminal = terminal; + this.successful = successful; + } + + public boolean isTerminal() { + return terminal; + } + + public boolean isSuccessful() { + return successful; + } + } + + private Status status = Status.RUNNING; + + private long endTime; + + private String workflowId; + + private String parentWorkflowId; + + private String parentWorkflowTaskId; + + private List tasks = new LinkedList<>(); + + private Map input = new HashMap<>(); + + private Map output = new HashMap<>(); + + private String correlationId; + + private String reRunFromWorkflowId; + + private String reasonForIncompletion; + + private String event; + + private Map taskToDomain = new HashMap<>(); + + private Set failedReferenceTaskNames = new HashSet<>(); + + private WorkflowDef workflowDefinition; + + private String externalInputPayloadStoragePath; + + private String externalOutputPayloadStoragePath; + + private int priority; + + private Map variables = new HashMap<>(); + + private long lastRetriedTime; + + private String ownerApp; + + private Long createTime; + + private Long updatedTime; + + private String createdBy; + + private String updatedBy; + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + public long getEndTime() { + return endTime; + } + + public void setEndTime(long endTime) { + this.endTime = endTime; + } + + public String getWorkflowId() { + return workflowId; + } + + public void setWorkflowId(String workflowId) { + this.workflowId = workflowId; + } + + public String getParentWorkflowId() { + return parentWorkflowId; + } + + public void setParentWorkflowId(String parentWorkflowId) { + this.parentWorkflowId = parentWorkflowId; + } + + public String getParentWorkflowTaskId() { + return parentWorkflowTaskId; + } + + public void setParentWorkflowTaskId(String parentWorkflowTaskId) { + this.parentWorkflowTaskId = parentWorkflowTaskId; + } + + public List getTasks() { + return tasks; + } + + public void setTasks(List tasks) { + this.tasks = tasks; + } + + public Map getInput() { + return input; + } + + public void setInput(Map input) { + if (input == null) { + input = new HashMap<>(); + } + this.input = input; + } + + public Map getOutput() { + return output; + } + + public void setOutput(Map output) { + if (output == null) { + output = new HashMap<>(); + } + this.output = output; + } + + public String getCorrelationId() { + return correlationId; + } + + public void setCorrelationId(String correlationId) { + this.correlationId = correlationId; + } + + public String getReRunFromWorkflowId() { + return reRunFromWorkflowId; + } + + public void setReRunFromWorkflowId(String reRunFromWorkflowId) { + this.reRunFromWorkflowId = reRunFromWorkflowId; + } + + public String getReasonForIncompletion() { + return reasonForIncompletion; + } + + public void setReasonForIncompletion(String reasonForIncompletion) { + this.reasonForIncompletion = reasonForIncompletion; + } + + public String getEvent() { + return event; + } + + public void setEvent(String event) { + this.event = event; + } + + public Map getTaskToDomain() { + return taskToDomain; + } + + public void setTaskToDomain(Map taskToDomain) { + this.taskToDomain = taskToDomain; + } + + public Set getFailedReferenceTaskNames() { + return failedReferenceTaskNames; + } + + public void setFailedReferenceTaskNames(Set failedReferenceTaskNames) { + this.failedReferenceTaskNames = failedReferenceTaskNames; + } + + public WorkflowDef getWorkflowDefinition() { + return workflowDefinition; + } + + public void setWorkflowDefinition(WorkflowDef workflowDefinition) { + this.workflowDefinition = workflowDefinition; + } + + public String getExternalInputPayloadStoragePath() { + return externalInputPayloadStoragePath; + } + + public void setExternalInputPayloadStoragePath(String externalInputPayloadStoragePath) { + this.externalInputPayloadStoragePath = externalInputPayloadStoragePath; + } + + public String getExternalOutputPayloadStoragePath() { + return externalOutputPayloadStoragePath; + } + + public void setExternalOutputPayloadStoragePath(String externalOutputPayloadStoragePath) { + this.externalOutputPayloadStoragePath = externalOutputPayloadStoragePath; + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + if (priority < 0 || priority > 99) { + throw new IllegalArgumentException("priority MUST be between 0 and 99 (inclusive)"); + } + this.priority = priority; + } + + public Map getVariables() { + return variables; + } + + public void setVariables(Map variables) { + this.variables = variables; + } + + public long getLastRetriedTime() { + return lastRetriedTime; + } + + public void setLastRetriedTime(long lastRetriedTime) { + this.lastRetriedTime = lastRetriedTime; + } + + public String getOwnerApp() { + return ownerApp; + } + + public void setOwnerApp(String ownerApp) { + this.ownerApp = ownerApp; + } + + public Long getCreateTime() { + return createTime; + } + + public void setCreateTime(Long createTime) { + this.createTime = createTime; + } + + public Long getUpdatedTime() { + return updatedTime; + } + + public void setUpdatedTime(Long updatedTime) { + this.updatedTime = updatedTime; + } + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + + public String getUpdatedBy() { + return updatedBy; + } + + public void setUpdatedBy(String updatedBy) { + this.updatedBy = updatedBy; + } + + /** + * Convenience method for accessing the workflow definition name. + * + * @return the workflow definition name. + */ + public String getWorkflowName() { + Preconditions.checkNotNull(workflowDefinition, "Workflow definition is null"); + return workflowDefinition.getName(); + } + + /** + * Convenience method for accessing the workflow definition version. + * + * @return the workflow definition version. + */ + public int getWorkflowVersion() { + Preconditions.checkNotNull(workflowDefinition, "Workflow definition is null"); + return workflowDefinition.getVersion(); + } + + public boolean hasParent() { + return StringUtils.isNotEmpty(parentWorkflowId); + } + + /** + * A string representation of all relevant fields that identify this workflow. Intended for use + * in log and other system generated messages. + */ + public String toShortString() { + String name = workflowDefinition != null ? workflowDefinition.getName() : null; + Integer version = workflowDefinition != null ? workflowDefinition.getVersion() : null; + return String.format("%s.%s/%s", name, version, workflowId); + } + + public TaskModel getTaskByRefName(String refName) { + if (refName == null) { + throw new RuntimeException( + "refName passed is null. Check the workflow execution. For dynamic tasks, make sure referenceTaskName is set to a not null value"); + } + LinkedList found = new LinkedList<>(); + for (TaskModel task : tasks) { + if (task.getReferenceTaskName() == null) { + throw new RuntimeException( + "Task " + + task.getTaskDefName() + + ", seq=" + + task.getSeq() + + " does not have reference name specified."); + } + if (task.getReferenceTaskName().equals(refName)) { + found.add(task); + } + } + if (found.isEmpty()) { + return null; + } + return found.getLast(); + } + + /** @return a deep copy of the workflow instance */ + public WorkflowModel copy() { + WorkflowModel copy = new WorkflowModel(); + BeanUtils.copyProperties(this, copy); + return copy; + } + + @Override + public String toString() { + String name = workflowDefinition != null ? workflowDefinition.getName() : null; + Integer version = workflowDefinition != null ? workflowDefinition.getVersion() : null; + return String.format("%s.%s/%s.%s", name, version, workflowId, status); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + WorkflowModel that = (WorkflowModel) o; + return getEndTime() == that.getEndTime() + && getPriority() == that.getPriority() + && getLastRetriedTime() == that.getLastRetriedTime() + && getStatus() == that.getStatus() + && Objects.equals(getWorkflowId(), that.getWorkflowId()) + && Objects.equals(getParentWorkflowId(), that.getParentWorkflowId()) + && Objects.equals(getParentWorkflowTaskId(), that.getParentWorkflowTaskId()) + && Objects.equals(getTasks(), that.getTasks()) + && Objects.equals(getInput(), that.getInput()) + && Objects.equals(getOutput(), that.getOutput()) + && Objects.equals(getCorrelationId(), that.getCorrelationId()) + && Objects.equals(getReRunFromWorkflowId(), that.getReRunFromWorkflowId()) + && Objects.equals(getReasonForIncompletion(), that.getReasonForIncompletion()) + && Objects.equals(getEvent(), that.getEvent()) + && Objects.equals(getTaskToDomain(), that.getTaskToDomain()) + && Objects.equals(getFailedReferenceTaskNames(), that.getFailedReferenceTaskNames()) + && Objects.equals(getWorkflowDefinition(), that.getWorkflowDefinition()) + && Objects.equals( + getExternalInputPayloadStoragePath(), + that.getExternalInputPayloadStoragePath()) + && Objects.equals( + getExternalOutputPayloadStoragePath(), + that.getExternalOutputPayloadStoragePath()) + && Objects.equals(getVariables(), that.getVariables()) + && Objects.equals(getOwnerApp(), that.getOwnerApp()) + && Objects.equals(getCreateTime(), that.getCreateTime()) + && Objects.equals(getUpdatedTime(), that.getUpdatedTime()) + && Objects.equals(getCreatedBy(), that.getCreatedBy()) + && Objects.equals(getUpdatedBy(), that.getUpdatedBy()); + } + + @Override + public int hashCode() { + return Objects.hash( + getStatus(), + getEndTime(), + getWorkflowId(), + getParentWorkflowId(), + getParentWorkflowTaskId(), + getTasks(), + getInput(), + getOutput(), + getCorrelationId(), + getReRunFromWorkflowId(), + getReasonForIncompletion(), + getEvent(), + getTaskToDomain(), + getFailedReferenceTaskNames(), + getWorkflowDefinition(), + getExternalInputPayloadStoragePath(), + getExternalOutputPayloadStoragePath(), + getPriority(), + getVariables(), + getLastRetriedTime(), + getOwnerApp(), + getCreateTime(), + getUpdatedTime(), + getCreatedBy(), + getUpdatedBy()); + } +} diff --git a/core/src/main/java/com/netflix/conductor/service/AdminService.java b/core/src/main/java/com/netflix/conductor/service/AdminService.java index eb66eb7758..84d68c2792 100644 --- a/core/src/main/java/com/netflix/conductor/service/AdminService.java +++ b/core/src/main/java/com/netflix/conductor/service/AdminService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -56,8 +56,8 @@ List getListOfPendingTask( /** * Verify that the Workflow is consistent, and run repairs as needed. * - * @param workflowId - * @return + * @param workflowId id of the workflow to be returned + * @return true, if repair was successful */ boolean verifyAndRepairWorkflowConsistency( @NotEmpty(message = "WorkflowId cannot be null or empty.") String workflowId); diff --git a/core/src/main/java/com/netflix/conductor/service/AdminServiceImpl.java b/core/src/main/java/com/netflix/conductor/service/AdminServiceImpl.java index 06e5cdae87..bf470d4e81 100644 --- a/core/src/main/java/com/netflix/conductor/service/AdminServiceImpl.java +++ b/core/src/main/java/com/netflix/conductor/service/AdminServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -26,13 +26,12 @@ import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.core.events.EventQueueManager; -import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.reconciliation.WorkflowRepairService; +import com.netflix.conductor.core.utils.Utils; import com.netflix.conductor.dao.QueueDAO; @Audit @Trace -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Service public class AdminServiceImpl implements AdminService { @@ -118,7 +117,7 @@ public boolean verifyAndRepairWorkflowConsistency(String workflowId) { public String requeueSweep(String workflowId) { boolean pushed = queueDAO.pushIfNotExists( - WorkflowExecutor.DECIDER_QUEUE, + Utils.DECIDER_QUEUE, workflowId, properties.getWorkflowOffsetTimeout().getSeconds()); return pushed + "." + workflowId; diff --git a/core/src/main/java/com/netflix/conductor/service/EventService.java b/core/src/main/java/com/netflix/conductor/service/EventService.java index f97d2fd24c..c2f29e7341 100644 --- a/core/src/main/java/com/netflix/conductor/service/EventService.java +++ b/core/src/main/java/com/netflix/conductor/service/EventService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/service/EventServiceImpl.java b/core/src/main/java/com/netflix/conductor/service/EventServiceImpl.java index 258f4f565e..b4b20bdf35 100644 --- a/core/src/main/java/com/netflix/conductor/service/EventServiceImpl.java +++ b/core/src/main/java/com/netflix/conductor/service/EventServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/service/ExecutionLockService.java b/core/src/main/java/com/netflix/conductor/service/ExecutionLockService.java index 1e0187d45e..e355dc336f 100644 --- a/core/src/main/java/com/netflix/conductor/service/ExecutionLockService.java +++ b/core/src/main/java/com/netflix/conductor/service/ExecutionLockService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/service/ExecutionService.java b/core/src/main/java/com/netflix/conductor/service/ExecutionService.java index 066cb53f38..a218c35bc7 100644 --- a/core/src/main/java/com/netflix/conductor/service/ExecutionService.java +++ b/core/src/main/java/com/netflix/conductor/service/ExecutionService.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -31,7 +31,6 @@ import com.netflix.conductor.common.metadata.events.EventExecution; import com.netflix.conductor.common.metadata.tasks.PollData; import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.metadata.tasks.TaskResult; @@ -44,24 +43,26 @@ import com.netflix.conductor.common.utils.ExternalPayloadStorage.Operation; import com.netflix.conductor.common.utils.ExternalPayloadStorage.PayloadType; import com.netflix.conductor.core.config.ConductorProperties; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; +import com.netflix.conductor.core.dal.ModelMapper; import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.tasks.SystemTaskRegistry; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; import com.netflix.conductor.core.utils.QueueUtils; import com.netflix.conductor.core.utils.Utils; import com.netflix.conductor.dao.QueueDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; @Trace -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Service public class ExecutionService { private static final Logger LOGGER = LoggerFactory.getLogger(ExecutionService.class); private final WorkflowExecutor workflowExecutor; + private final ModelMapper modelMapper; private final ExecutionDAOFacade executionDAOFacade; private final QueueDAO queueDAO; private final ExternalPayloadStorage externalPayloadStorage; @@ -75,12 +76,14 @@ public class ExecutionService { public ExecutionService( WorkflowExecutor workflowExecutor, + ModelMapper modelMapper, ExecutionDAOFacade executionDAOFacade, QueueDAO queueDAO, ConductorProperties properties, ExternalPayloadStorage externalPayloadStorage, SystemTaskRegistry systemTaskRegistry) { this.workflowExecutor = workflowExecutor; + this.modelMapper = modelMapper; this.executionDAOFacade = executionDAOFacade; this.queueDAO = queueDAO; this.externalPayloadStorage = externalPayloadStorage; @@ -134,7 +137,7 @@ public List poll( for (String taskId : taskIds) { try { - Task task = getTask(taskId); + TaskModel task = executionDAOFacade.getTaskModel(taskId); if (task == null || task.getStatus().isTerminal()) { // Remove taskId(s) without a valid Task/terminal state task from the queue queueDAO.remove(queueName, taskId); @@ -176,7 +179,7 @@ public List poll( continue; } - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); if (task.getStartTime() == 0) { task.setStartTime(System.currentTimeMillis()); Monitors.recordQueueWaitTime(task.getTaskDefName(), task.getQueueWaitTime()); @@ -186,7 +189,7 @@ public List poll( task.setWorkerId(workerId); task.incrementPollCount(); executionDAOFacade.updateTask(task); - tasks.add(task); + tasks.add(modelMapper.getTask(task)); } catch (Exception e) { // db operation failed for dequeued message, re-enqueue with a delay LOGGER.warn( @@ -234,12 +237,13 @@ public List getAllPollData() { queueSizes .keySet() .forEach( - k -> { + queueName -> { try { - if (!k.contains(QueueUtils.DOMAIN_SEPARATOR)) { + if (!queueName.contains(QueueUtils.DOMAIN_SEPARATOR)) { allPollData.addAll( getPollData( - QueueUtils.getQueueNameWithoutDomain(k))); + QueueUtils.getQueueNameWithoutDomain( + queueName))); } } catch (Exception e) { LOGGER.error("Unable to fetch all poll data!", e); @@ -253,25 +257,25 @@ public void terminateWorkflow(String workflowId, String reason) { workflowExecutor.terminateWorkflow(workflowId, reason); } - // For backward compatibility - to be removed in the later versions - public void updateTask(Task task) { - updateTask(new TaskResult(task)); - } - public void updateTask(TaskResult taskResult) { workflowExecutor.updateTask(taskResult); } public List getTasks(String taskType, String startKey, int count) { - return workflowExecutor.getTasks(taskType, startKey, count); + return executionDAOFacade.getTasksByName(taskType, startKey, count); } public Task getTask(String taskId) { - return workflowExecutor.getTask(taskId); + return executionDAOFacade.getTask(taskId); } public Task getPendingTaskForWorkflow(String taskReferenceName, String workflowId) { - return workflowExecutor.getPendingTaskByWorkflow(taskReferenceName, workflowId); + return executionDAOFacade.getTasksForWorkflow(workflowId).stream() + .filter(task -> !task.getStatus().isTerminal()) + .filter(task -> task.getReferenceTaskName().equals(taskReferenceName)) + .findFirst() // There can only be one task by a given reference name running at a + // time. + .orElse(null); } /** @@ -296,8 +300,8 @@ public Map getTaskQueueSizes(List taskDefNames) { return sizes; } - public void removeTaskfromQueue(String taskId) { - Task task = executionDAOFacade.getTaskById(taskId); + public void removeTaskFromQueue(String taskId) { + Task task = getTask(taskId); if (task == null) { throw new ApplicationException( ApplicationException.Code.NOT_FOUND, @@ -362,16 +366,17 @@ public List getWorkflowInstances( return workflows.stream() .parallel() .filter( - wf -> { + workflow -> { if (includeClosed - || wf.getStatus().equals(Workflow.WorkflowStatus.RUNNING)) { + || workflow.getStatus() + .equals(Workflow.WorkflowStatus.RUNNING)) { // including tasks for subset of workflows to increase performance if (includeTasks) { List tasks = executionDAOFacade.getTasksForWorkflow( - wf.getWorkflowId()); + workflow.getWorkflowId()); tasks.sort(Comparator.comparingInt(Task::getSeq)); - wf.setTasks(tasks); + workflow.setTasks(tasks); } return true; } else { @@ -382,7 +387,7 @@ public List getWorkflowInstances( } public Workflow getExecutionStatus(String workflowId, boolean includeTasks) { - return executionDAOFacade.getWorkflowById(workflowId, includeTasks); + return executionDAOFacade.getWorkflow(workflowId, includeTasks); } public List getRunningWorkflows(String workflowName, int version) { @@ -405,8 +410,7 @@ public SearchResult search( workflowId -> { try { return new WorkflowSummary( - executionDAOFacade.getWorkflowById( - workflowId, false)); + executionDAOFacade.getWorkflow(workflowId, false)); } catch (Exception e) { LOGGER.error( "Error fetching workflow by id: {}", workflowId, e); @@ -431,8 +435,7 @@ public SearchResult searchV2( .map( workflowId -> { try { - return executionDAOFacade.getWorkflowById( - workflowId, false); + return executionDAOFacade.getWorkflow(workflowId, false); } catch (Exception e) { LOGGER.error( "Error fetching workflow by id: {}", workflowId, e); @@ -458,8 +461,7 @@ public SearchResult searchWorkflowByTasks( try { String workflowId = taskSummary.getWorkflowId(); return new WorkflowSummary( - executionDAOFacade.getWorkflowById( - workflowId, false)); + executionDAOFacade.getWorkflow(workflowId, false)); } catch (Exception e) { LOGGER.error( "Error fetching workflow by id: {}", @@ -487,8 +489,7 @@ public SearchResult searchWorkflowByTasksV2( taskSummary -> { try { String workflowId = taskSummary.getWorkflowId(); - return executionDAOFacade.getWorkflowById( - workflowId, false); + return executionDAOFacade.getWorkflow(workflowId, false); } catch (Exception e) { LOGGER.error( "Error fetching workflow by id: {}", @@ -516,8 +517,7 @@ public SearchResult searchTasks( .map( task -> { try { - return new TaskSummary( - executionDAOFacade.getTaskById(task)); + return new TaskSummary(executionDAOFacade.getTask(task)); } catch (Exception e) { LOGGER.error("Error fetching task by id: {}", task, e); return null; @@ -551,7 +551,7 @@ public SearchResult getSearchTasksV2( .map( task -> { try { - return executionDAOFacade.getTaskById(task); + return executionDAOFacade.getTask(task); } catch (Exception e) { LOGGER.error("Error fetching task by id: {}", task, e); return null; diff --git a/core/src/main/java/com/netflix/conductor/service/MetadataService.java b/core/src/main/java/com/netflix/conductor/service/MetadataService.java index fcc636ebd8..d87be2ff73 100644 --- a/core/src/main/java/com/netflix/conductor/service/MetadataService.java +++ b/core/src/main/java/com/netflix/conductor/service/MetadataService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/service/MetadataServiceImpl.java b/core/src/main/java/com/netflix/conductor/service/MetadataServiceImpl.java index 8e46b72127..d0e97c478f 100644 --- a/core/src/main/java/com/netflix/conductor/service/MetadataServiceImpl.java +++ b/core/src/main/java/com/netflix/conductor/service/MetadataServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -29,7 +29,6 @@ import com.netflix.conductor.dao.MetadataDAO; import com.netflix.conductor.validations.ValidationContext; -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Service public class MetadataServiceImpl implements MetadataService { diff --git a/core/src/main/java/com/netflix/conductor/service/TaskService.java b/core/src/main/java/com/netflix/conductor/service/TaskService.java index cb44b53890..03e1371aa6 100644 --- a/core/src/main/java/com/netflix/conductor/service/TaskService.java +++ b/core/src/main/java/com/netflix/conductor/service/TaskService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/service/TaskServiceImpl.java b/core/src/main/java/com/netflix/conductor/service/TaskServiceImpl.java index 282d6f051c..9865dccd3e 100644 --- a/core/src/main/java/com/netflix/conductor/service/TaskServiceImpl.java +++ b/core/src/main/java/com/netflix/conductor/service/TaskServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,7 +12,6 @@ */ package com.netflix.conductor.service; -import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -39,7 +38,6 @@ import com.netflix.conductor.dao.QueueDAO; import com.netflix.conductor.metrics.Monitors; -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Audit @Trace @Service @@ -58,7 +56,7 @@ public TaskServiceImpl(ExecutionService executionService, QueueDAO queueDAO) { * Poll for a task of a certain type. * * @param taskType Task name - * @param workerId Id of the workflow + * @param workerId id of the workflow * @param domain Domain of the workflow * @return polled {@link Task} */ @@ -81,7 +79,7 @@ public Task poll(String taskType, String workerId, String domain) { * Batch Poll for a task of a certain type. * * @param taskType Task Name - * @param workerId Id of the workflow + * @param workerId id of the workflow * @param domain Domain of the workflow * @param count Number of tasks * @param timeout Timeout for polling in milliseconds @@ -115,7 +113,7 @@ public List getTasks(String taskType, String startKey, Integer count) { /** * Get in progress task for a given workflow id. * - * @param workflowId Id of the workflow + * @param workflowId id of the workflow * @param taskReferenceName Task reference name. * @return instance of {@link Task} */ @@ -145,9 +143,9 @@ public String updateTask(TaskResult taskResult) { /** * Ack Task is received. * - * @param taskId Id of the task - * @param workerId Id of the worker - * @return `true|false` if task if received or not + * @param taskId id of the task + * @param workerId id of the worker + * @return `true|false` if task is received or not */ public String ackTaskReceived(String taskId, String workerId) { LOGGER.debug("Ack received for task: {} from worker: {}", taskId, workerId); @@ -157,8 +155,8 @@ public String ackTaskReceived(String taskId, String workerId) { /** * Ack Task is received. * - * @param taskId Id of the task - * @return `true|false` if task if received or not + * @param taskId id of the task + * @return `true|false` if task is received or not */ public boolean ackTaskReceived(String taskId) { LOGGER.debug("Ack received for task: {}", taskId); @@ -191,12 +189,7 @@ public boolean ackTaskReceived(String taskId) { return ackResult.get(); } - /** - * Updates the task with FAILED status; On exception, fails the workflow. - * - * @param task - * @param errorMsg - */ + /** Updates the task with FAILED status; On exception, fails the workflow. */ private void failTask(Task task, String errorMsg) { try { TaskResult taskResult = new TaskResult(); @@ -219,7 +212,7 @@ private void failTask(Task task, String errorMsg) { /** * Log Task Execution Details. * - * @param taskId Id of the task + * @param taskId id of the task * @param log Details you want to log */ public void log(String taskId, String log) { @@ -229,7 +222,7 @@ public void log(String taskId, String log) { /** * Get Task Execution Logs. * - * @param taskId Id of the task. + * @param taskId id of the task. * @return list of {@link TaskExecLog} */ public List getTaskLogs(String taskId) { @@ -239,7 +232,7 @@ public List getTaskLogs(String taskId) { /** * Get task by Id. * - * @param taskId Id of the task. + * @param taskId id of the task. * @return instance of {@link Task} */ public Task getTask(String taskId) { @@ -253,7 +246,7 @@ public Task getTask(String taskId) { * @param taskId ID of the task */ public void removeTaskFromQueue(String taskType, String taskId) { - executionService.removeTaskfromQueue(taskId); + executionService.removeTaskFromQueue(taskId); } /** @@ -262,7 +255,7 @@ public void removeTaskFromQueue(String taskType, String taskId) { * @param taskId ID of the task */ public void removeTaskFromQueue(String taskId) { - executionService.removeTaskfromQueue(taskId); + executionService.removeTaskFromQueue(taskId); } /** @@ -291,7 +284,7 @@ public Map>> allVerbose() { */ public Map getAllQueueDetails() { return queueDAO.queuesDetail().entrySet().stream() - .sorted(Comparator.comparing(Entry::getKey)) + .sorted(Entry.comparingByKey()) .collect( Collectors.toMap( Entry::getKey, diff --git a/core/src/main/java/com/netflix/conductor/service/WorkflowBulkService.java b/core/src/main/java/com/netflix/conductor/service/WorkflowBulkService.java index a3c3858da1..2c1ef0f7fe 100644 --- a/core/src/main/java/com/netflix/conductor/service/WorkflowBulkService.java +++ b/core/src/main/java/com/netflix/conductor/service/WorkflowBulkService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/service/WorkflowBulkServiceImpl.java b/core/src/main/java/com/netflix/conductor/service/WorkflowBulkServiceImpl.java index fc4adf1105..c637b8bd91 100644 --- a/core/src/main/java/com/netflix/conductor/service/WorkflowBulkServiceImpl.java +++ b/core/src/main/java/com/netflix/conductor/service/WorkflowBulkServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/service/WorkflowService.java b/core/src/main/java/com/netflix/conductor/service/WorkflowService.java index f070125dfc..10f9e18425 100644 --- a/core/src/main/java/com/netflix/conductor/service/WorkflowService.java +++ b/core/src/main/java/com/netflix/conductor/service/WorkflowService.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/service/WorkflowServiceImpl.java b/core/src/main/java/com/netflix/conductor/service/WorkflowServiceImpl.java index 06164045c6..4af4b18312 100644 --- a/core/src/main/java/com/netflix/conductor/service/WorkflowServiceImpl.java +++ b/core/src/main/java/com/netflix/conductor/service/WorkflowServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -75,14 +75,15 @@ public String startWorkflow(StartWorkflowRequest startWorkflowRequest) { } /** - * Start a new workflow with StartWorkflowRequest, which allows task to be executed in a domain. + * Start a new workflow. * * @param name Name of the workflow you want to start. * @param version Version of the workflow you want to start. * @param correlationId CorrelationID of the workflow you want to start. * @param input Input to the workflow you want to start. - * @param externalInputPayloadStoragePath - * @param taskToDomain + * @param externalInputPayloadStoragePath the relative path in external storage where input + * payload is located + * @param taskToDomain the task to domain mapping * @param workflowDef - workflow definition * @return the id of the workflow instance that can be use for tracking. */ @@ -113,8 +114,9 @@ public String startWorkflow( * @param correlationId CorrelationID of the workflow you want to start. * @param priority Priority of the workflow you want to start. * @param input Input to the workflow you want to start. - * @param externalInputPayloadStoragePath - * @param taskToDomain + * @param externalInputPayloadStoragePath the relative path in external storage where input * + * payload is located + * @param taskToDomain the task to domain mapping * @param workflowDef - workflow definition * @return the id of the workflow instance that can be use for tracking. */ @@ -244,9 +246,9 @@ public Map> getWorkflows( } /** - * Gets the workflow by workflow Id. + * Gets the workflow by workflow id. * - * @param workflowId Id of the workflow. + * @param workflowId id of the workflow. * @param includeTasks Includes tasks associated with workflow. * @return an instance of {@link Workflow} */ @@ -275,7 +277,7 @@ public void deleteWorkflow(String workflowId, boolean archiveWorkflow) { * * @param workflowName Name of the workflow. * @param version Version of the workflow. - * @param startTime Starttime of the workflow. + * @param startTime start time of the workflow. * @param endTime EndTime of the workflow * @return a list of workflow Ids. */ @@ -307,7 +309,7 @@ public void decideWorkflow(String workflowId) { } /** - * Pauses the workflow given a worklfowId. + * Pauses the workflow given a workflowId. * * @param workflowId WorkflowId of the workflow. */ diff --git a/core/src/main/java/com/netflix/conductor/validations/ValidationContext.java b/core/src/main/java/com/netflix/conductor/validations/ValidationContext.java index f8296295a9..18d32197e4 100644 --- a/core/src/main/java/com/netflix/conductor/validations/ValidationContext.java +++ b/core/src/main/java/com/netflix/conductor/validations/ValidationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/core/src/main/java/com/netflix/conductor/validations/WorkflowTaskTypeConstraint.java b/core/src/main/java/com/netflix/conductor/validations/WorkflowTaskTypeConstraint.java index b8c4d01d72..d620c945be 100644 --- a/core/src/main/java/com/netflix/conductor/validations/WorkflowTaskTypeConstraint.java +++ b/core/src/main/java/com/netflix/conductor/validations/WorkflowTaskTypeConstraint.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -27,7 +27,6 @@ import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_SUB_WORKFLOW; import static com.netflix.conductor.core.execution.tasks.Terminate.getTerminationStatusParameter; import static com.netflix.conductor.core.execution.tasks.Terminate.validateInputStatus; @@ -97,7 +96,7 @@ public boolean isValid(WorkflowTask workflowTask, ConstraintValidatorContext con case TaskType.TASK_TYPE_DO_WHILE: valid = isDoWhileTaskValid(workflowTask, context); break; - case TASK_TYPE_SUB_WORKFLOW: + case TaskType.TASK_TYPE_SUB_WORKFLOW: valid = isSubWorkflowTaskValid(workflowTask, context); break; case TaskType.TASK_TYPE_JSON_JQ_TRANSFORM: @@ -227,7 +226,7 @@ private boolean isDoWhileTaskValid( valid = false; } if (workflowTask.collectTasks().stream() - .anyMatch(t -> t.getType().equals(TASK_TYPE_SUB_WORKFLOW))) { + .anyMatch(t -> t.getType().equals(TaskType.TASK_TYPE_SUB_WORKFLOW))) { String message = String.format( "SUB_WORKFLOW task inside loopover task: %s is not supported.", diff --git a/core/src/main/java/com/netflix/conductor/validations/WorkflowTaskValidConstraint.java b/core/src/main/java/com/netflix/conductor/validations/WorkflowTaskValidConstraint.java index a97a2b55fa..d7e4661c95 100644 --- a/core/src/main/java/com/netflix/conductor/validations/WorkflowTaskValidConstraint.java +++ b/core/src/main/java/com/netflix/conductor/validations/WorkflowTaskValidConstraint.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -31,7 +31,7 @@ import static java.lang.annotation.ElementType.TYPE; /** - * This constraint class validates following things. 1. Check Task Def exists in DAO or not. If not + * This constraint class validates following things. 1. Check Task Def exists in DAO or not. If not, * check if it is ephemeral task type. */ @Documented @@ -67,7 +67,7 @@ public boolean isValid(WorkflowTask workflowTask, ConstraintValidatorContext con boolean valid = true; - // avoid task type definition check incase of non simple task + // avoid task type definition check in case of non-simple task if (!workflowTask.getType().equals(TASK_TYPE_SIMPLE)) { return valid; } diff --git a/core/src/test/groovy/com/netflix/conductor/core/dal/ModelMapperSpec.groovy b/core/src/test/groovy/com/netflix/conductor/core/dal/ModelMapperSpec.groovy new file mode 100644 index 0000000000..1c8d9d8b38 --- /dev/null +++ b/core/src/test/groovy/com/netflix/conductor/core/dal/ModelMapperSpec.groovy @@ -0,0 +1,156 @@ +/* + * Copyright 2022 Netflix, Inc. + *

    + * 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.core.dal + +import com.netflix.conductor.common.metadata.tasks.Task +import com.netflix.conductor.common.metadata.workflow.WorkflowDef +import com.netflix.conductor.common.run.Workflow +import com.netflix.conductor.common.utils.ExternalPayloadStorage +import com.netflix.conductor.core.utils.ExternalPayloadStorageUtils +import com.netflix.conductor.model.TaskModel +import com.netflix.conductor.model.WorkflowModel + +import spock.lang.Specification +import spock.lang.Subject + +class ModelMapperSpec extends Specification { + + ExternalPayloadStorageUtils externalPayloadStorageUtils + WorkflowModel workflowModel + TaskModel taskModel1, taskModel2 + + @Subject + ModelMapper modelMapper + + def setup() { + taskModel1 = new TaskModel(taskId: 'taskId1', status: TaskModel.Status.SCHEDULED, inputData: ['key1': 'value1'], startTime: 10L) + taskModel2 = new TaskModel(taskId: 'taskId2', status: TaskModel.Status.IN_PROGRESS, externalInputPayloadStoragePath: '/relative/task/path') + + workflowModel = new WorkflowModel(workflowId: 'workflowId', status: WorkflowModel.Status.COMPLETED, input: ['app': 'conductor'], endTime: 100L, tasks: [taskModel1, taskModel2], externalOutputPayloadStoragePath: '/relative/workflow/path', workflowDefinition: new WorkflowDef(name: 'test_workflow')) + + externalPayloadStorageUtils = Mock(ExternalPayloadStorageUtils) + modelMapper = new ModelMapper(externalPayloadStorageUtils) + } + + def "get workflow from workflow model"() { + when: + Workflow workflow = modelMapper.getWorkflow(workflowModel) + + then: + 2 * externalPayloadStorageUtils.verifyAndUpload(_ as WorkflowModel, _ as ExternalPayloadStorage.PayloadType) + 4 * externalPayloadStorageUtils.verifyAndUpload(_ as TaskModel, _ as ExternalPayloadStorage.PayloadType) + with(workflow) { + workflowId == 'workflowId' + status == Workflow.WorkflowStatus.COMPLETED + input == ['app': 'conductor'] + externalOutputPayloadStoragePath == '/relative/workflow/path' + endTime == 100L + tasks.size() == 2 + tasks[0].taskId == 'taskId1' + tasks[0].status == Task.Status.SCHEDULED + tasks[0].inputData == ['key1': 'value1'] + tasks[1].taskId == 'taskId2' + tasks[1].status == Task.Status.IN_PROGRESS + tasks[1].externalInputPayloadStoragePath == '/relative/task/path' + } + } + + def "get full copy of workflow model"() { + when: + WorkflowModel fullWorkflowModel = modelMapper.getFullCopy(workflowModel) + + then: + 1 * externalPayloadStorageUtils.downloadPayload("/relative/workflow/path") >> ['wk': 'wv'] + 1 * externalPayloadStorageUtils.downloadPayload("/relative/task/path") >> ['tk': 'tv'] + with(fullWorkflowModel) { + workflowId == 'workflowId' + status == WorkflowModel.Status.COMPLETED + input == ['app': 'conductor'] + !externalOutputPayloadStoragePath + output == ['wk': 'wv'] + endTime == 100L + tasks.size() == 2 + tasks[0].taskId == 'taskId1' + tasks[0].status == TaskModel.Status.SCHEDULED + tasks[0].inputData == ['key1': 'value1'] + tasks[1].taskId == 'taskId2' + tasks[1].status == TaskModel.Status.IN_PROGRESS + !tasks[1].externalInputPayloadStoragePath + tasks[1].inputData == ['tk': 'tv'] + } + } + + def "get lean copy of workflow model"() { + when: + WorkflowModel leanWorkflowModel = modelMapper.getLeanCopy(workflowModel) + + then: + 2 * externalPayloadStorageUtils.verifyAndUpload(_ as WorkflowModel, _ as ExternalPayloadStorage.PayloadType) + 4 * externalPayloadStorageUtils.verifyAndUpload(_ as TaskModel, _ as ExternalPayloadStorage.PayloadType) + with(leanWorkflowModel) { + workflowId == 'workflowId' + status == WorkflowModel.Status.COMPLETED + input == ['app': 'conductor'] + externalOutputPayloadStoragePath == '/relative/workflow/path' + endTime == 100L + tasks.size() == 2 + tasks[0].taskId == 'taskId1' + tasks[0].status == TaskModel.Status.SCHEDULED + tasks[0].inputData == ['key1': 'value1'] + tasks[1].taskId == 'taskId2' + tasks[1].status == TaskModel.Status.IN_PROGRESS + tasks[1].externalInputPayloadStoragePath == '/relative/task/path' + } + } + + def "get task from task model"() { + when: + Task task = modelMapper.getTask(taskModel1) + + then: + 2 * externalPayloadStorageUtils.verifyAndUpload(_ as TaskModel, _ as ExternalPayloadStorage.PayloadType) + with(task) { + taskId == 'taskId1' + status == Task.Status.SCHEDULED + inputData == ['key1': 'value1'] + startTime == 10L + } + } + + def "get full copy of task"() { + when: + TaskModel fullTaskModel = modelMapper.getFullCopy(taskModel2) + + then: + 1 * externalPayloadStorageUtils.downloadPayload("/relative/task/path") >> ['k': 'v'] + with(fullTaskModel) { + taskId == 'taskId2' + status == TaskModel.Status.IN_PROGRESS + !externalInputPayloadStoragePath + inputData == ['k': 'v'] + } + } + + def "get lean copy of task model"() { + when: + TaskModel leanTaskModel = modelMapper.getLeanCopy(taskModel2) + + then: + 2 * externalPayloadStorageUtils.verifyAndUpload(_ as TaskModel, _ as ExternalPayloadStorage.PayloadType) + with(leanTaskModel) { + taskId == 'taskId2' + status == TaskModel.Status.IN_PROGRESS + externalInputPayloadStoragePath == '/relative/task/path' + } + } +} diff --git a/core/src/test/groovy/com/netflix/conductor/core/execution/AsyncSystemTaskExecutorTest.groovy b/core/src/test/groovy/com/netflix/conductor/core/execution/AsyncSystemTaskExecutorTest.groovy index 930d90abb5..dc1e11b57d 100644 --- a/core/src/test/groovy/com/netflix/conductor/core/execution/AsyncSystemTaskExecutorTest.groovy +++ b/core/src/test/groovy/com/netflix/conductor/core/execution/AsyncSystemTaskExecutorTest.groovy @@ -1,38 +1,36 @@ /* - * Copyright 2021 Netflix, Inc. - *

    - * 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. + * Copyright 2022 Netflix, Inc. + *

    + * 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.core.execution -import com.fasterxml.jackson.databind.ObjectMapper -import com.netflix.conductor.common.metadata.tasks.Task +import java.time.Duration + import com.netflix.conductor.common.metadata.tasks.TaskDef -import com.netflix.conductor.common.run.Workflow import com.netflix.conductor.core.config.ConductorProperties +import com.netflix.conductor.core.dal.ExecutionDAOFacade import com.netflix.conductor.core.execution.tasks.SubWorkflow import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade import com.netflix.conductor.core.utils.IDGenerator import com.netflix.conductor.core.utils.QueueUtils import com.netflix.conductor.dao.MetadataDAO import com.netflix.conductor.dao.QueueDAO +import com.netflix.conductor.model.TaskModel +import com.netflix.conductor.model.WorkflowModel + +import com.fasterxml.jackson.databind.ObjectMapper import spock.lang.Specification import spock.lang.Subject -import java.time.Duration - import static com.netflix.conductor.common.metadata.tasks.TaskType.SUB_WORKFLOW -import static com.netflix.conductor.common.run.Workflow.WorkflowStatus.COMPLETED -import static com.netflix.conductor.common.run.Workflow.WorkflowStatus.RUNNING class AsyncSystemTaskExecutorTest extends Specification { @@ -40,7 +38,6 @@ class AsyncSystemTaskExecutorTest extends Specification { QueueDAO queueDAO MetadataDAO metadataDAO WorkflowExecutor workflowExecutor - DeciderService deciderService @Subject AsyncSystemTaskExecutor executor @@ -53,14 +50,13 @@ class AsyncSystemTaskExecutorTest extends Specification { queueDAO = Mock(QueueDAO.class) metadataDAO = Mock(MetadataDAO.class) workflowExecutor = Mock(WorkflowExecutor.class) - deciderService = Mock(DeciderService.class) workflowSystemTask = Mock(WorkflowSystemTask.class) properties.taskExecutionPostponeDuration = Duration.ofSeconds(1) properties.systemTaskWorkerCallbackDuration = Duration.ofSeconds(1) - executor = new AsyncSystemTaskExecutor(executionDAOFacade, queueDAO, metadataDAO, properties, workflowExecutor, deciderService) + executor = new AsyncSystemTaskExecutor(executionDAOFacade, queueDAO, metadataDAO, properties, workflowExecutor) } // this is not strictly a unit test, but its essential to test AsyncSystemTaskExecutor with SubWorkflow @@ -71,7 +67,7 @@ class AsyncSystemTaskExecutorTest extends Specification { SubWorkflow subWorkflowTask = new SubWorkflow(new ObjectMapper()) String task1Id = IDGenerator.generate() - Task task1 = new Task() + TaskModel task1 = new TaskModel() task1.setTaskType(SUB_WORKFLOW.name()) task1.setReferenceTaskName("waitTask") task1.setWorkflowInstanceId(workflowId) @@ -80,25 +76,25 @@ class AsyncSystemTaskExecutorTest extends Specification { task1.getInputData().put("asyncComplete", true) task1.getInputData().put("subWorkflowName", "junit1") task1.getInputData().put("subWorkflowVersion", 1) - task1.setStatus(Task.Status.SCHEDULED) + task1.setStatus(TaskModel.Status.SCHEDULED) String queueName = QueueUtils.getQueueName(task1) - Workflow workflow = new Workflow(workflowId: workflowId, status: RUNNING) - Workflow subWorkflow = new Workflow(workflowId: subWorkflowId, status: RUNNING) + WorkflowModel workflow = new WorkflowModel(workflowId: workflowId, status: WorkflowModel.Status.RUNNING) + WorkflowModel subWorkflow = new WorkflowModel(workflowId: subWorkflowId, status: WorkflowModel.Status.RUNNING) when: executor.execute(subWorkflowTask, task1Id) then: - 1 * executionDAOFacade.getTaskById(task1Id) >> task1 - 1 * executionDAOFacade.getWorkflowById(workflowId, true) >> workflow + 1 * executionDAOFacade.getTaskModel(task1Id) >> task1 + 1 * executionDAOFacade.getWorkflowModel(workflowId, true) >> workflow 1 * workflowExecutor.startWorkflow(*_) >> subWorkflowId 1 * workflowExecutor.getWorkflow(subWorkflowId, false) >> subWorkflow // SUB_WORKFLOW is asyncComplete so its removed from the queue 1 * queueDAO.remove(queueName, task1Id) - task1.status == Task.Status.IN_PROGRESS + task1.status == TaskModel.Status.IN_PROGRESS task1.subWorkflowId == subWorkflowId task1.startTime != 0 } @@ -111,7 +107,7 @@ class AsyncSystemTaskExecutorTest extends Specification { executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> null + 1 * executionDAOFacade.getTaskModel(taskId) >> null 0 * workflowSystemTask.start(*_) 0 * executionDAOFacade.updateTask(_) } @@ -124,7 +120,7 @@ class AsyncSystemTaskExecutorTest extends Specification { executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> { throw new RuntimeException("datastore unavailable") } + 1 * executionDAOFacade.getTaskModel(taskId) >> { throw new RuntimeException("datastore unavailable") } 0 * workflowSystemTask.start(*_) 0 * executionDAOFacade.updateTask(_) } @@ -132,13 +128,13 @@ class AsyncSystemTaskExecutorTest extends Specification { def "Execute with a task id that is in terminal state"() { given: String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.COMPLETED, taskId: taskId) + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.COMPLETED, taskId: taskId) when: executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task + 1 * executionDAOFacade.getTaskModel(taskId) >> task 1 * queueDAO.remove(task.taskType, taskId) 0 * workflowSystemTask.start(*_) 0 * executionDAOFacade.updateTask(_) @@ -148,19 +144,19 @@ class AsyncSystemTaskExecutorTest extends Specification { given: String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId) - Workflow workflow = new Workflow(workflowId: workflowId, status: COMPLETED) + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId) + WorkflowModel workflow = new WorkflowModel(workflowId: workflowId, status: WorkflowModel.Status.COMPLETED) String queueName = QueueUtils.getQueueName(task) when: executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task - 1 * executionDAOFacade.getWorkflowById(workflowId, true) >> workflow + 1 * executionDAOFacade.getTaskModel(taskId) >> task + 1 * executionDAOFacade.getWorkflowModel(workflowId, true) >> workflow 1 * queueDAO.remove(queueName, taskId) - task.status == Task.Status.CANCELED + task.status == TaskModel.Status.CANCELED task.startTime == 0 } @@ -169,7 +165,7 @@ class AsyncSystemTaskExecutorTest extends Specification { String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, workflowPriority: 10) String queueName = QueueUtils.getQueueName(task) @@ -177,11 +173,11 @@ class AsyncSystemTaskExecutorTest extends Specification { executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task + 1 * executionDAOFacade.getTaskModel(taskId) >> task 1 * executionDAOFacade.exceedsInProgressLimit(task) >> true 1 * queueDAO.postpone(queueName, taskId, task.workflowPriority, properties.taskExecutionPostponeDuration.seconds) - task.status == Task.Status.SCHEDULED + task.status == TaskModel.Status.SCHEDULED task.startTime == 0 } @@ -189,7 +185,7 @@ class AsyncSystemTaskExecutorTest extends Specification { given: String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, rateLimitPerFrequency: 1, taskDefName: "taskDefName", workflowPriority: 10) String queueName = QueueUtils.getQueueName(task) TaskDef taskDef = new TaskDef() @@ -198,12 +194,12 @@ class AsyncSystemTaskExecutorTest extends Specification { executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task + 1 * executionDAOFacade.getTaskModel(taskId) >> task 1 * metadataDAO.getTaskDef(task.taskDefName) >> taskDef 1 * executionDAOFacade.exceedsRateLimitPerFrequency(task, taskDef) >> taskDef 1 * queueDAO.postpone(queueName, taskId, task.workflowPriority, properties.taskExecutionPostponeDuration.seconds) - task.status == Task.Status.SCHEDULED + task.status == TaskModel.Status.SCHEDULED task.startTime == 0 } @@ -211,7 +207,7 @@ class AsyncSystemTaskExecutorTest extends Specification { given: String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, rateLimitPerFrequency: 1, taskDefName: "taskDefName", workflowPriority: 10) String queueName = QueueUtils.getQueueName(task) TaskDef taskDef = new TaskDef() @@ -220,12 +216,12 @@ class AsyncSystemTaskExecutorTest extends Specification { executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task + 1 * executionDAOFacade.getTaskModel(taskId) >> task 1 * metadataDAO.getTaskDef(task.taskDefName) >> taskDef 1 * executionDAOFacade.exceedsRateLimitPerFrequency(task, taskDef) >> taskDef 1 * queueDAO.postpone(queueName, taskId, task.workflowPriority, properties.taskExecutionPostponeDuration.seconds) >> { throw new RuntimeException("queue unavailable") } - task.status == Task.Status.SCHEDULED + task.status == TaskModel.Status.SCHEDULED task.startTime == 0 } @@ -233,24 +229,24 @@ class AsyncSystemTaskExecutorTest extends Specification { given: String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, taskDefName: "taskDefName", workflowPriority: 10) - Workflow workflow = new Workflow(workflowId: workflowId, status: RUNNING) + WorkflowModel workflow = new WorkflowModel(workflowId: workflowId, status: WorkflowModel.Status.RUNNING) String queueName = QueueUtils.getQueueName(task) when: executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task - 1 * executionDAOFacade.getWorkflowById(workflowId, true) >> workflow + 1 * executionDAOFacade.getTaskModel(taskId) >> task + 1 * executionDAOFacade.getWorkflowModel(workflowId, true) >> workflow 1 * executionDAOFacade.updateTask(task) 1 * queueDAO.postpone(queueName, taskId, task.workflowPriority, properties.systemTaskWorkerCallbackDuration.seconds) - 1 * workflowSystemTask.start(workflow, task, workflowExecutor) >> { task.status = Task.Status.IN_PROGRESS } + 1 * workflowSystemTask.start(workflow, task, workflowExecutor) >> { task.status = TaskModel.Status.IN_PROGRESS } 0 * workflowExecutor.decide(workflowId) // verify that workflow is NOT decided - task.status == Task.Status.IN_PROGRESS + task.status == TaskModel.Status.IN_PROGRESS task.startTime != 0 // verify that startTime is set task.endTime == 0 // verify that endTime is not set task.pollCount == 1 // verify that poll count is incremented @@ -261,24 +257,24 @@ class AsyncSystemTaskExecutorTest extends Specification { given: String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, taskDefName: "taskDefName", workflowPriority: 10) - Workflow workflow = new Workflow(workflowId: workflowId, status: RUNNING) + WorkflowModel workflow = new WorkflowModel(workflowId: workflowId, status: WorkflowModel.Status.RUNNING) String queueName = QueueUtils.getQueueName(task) when: executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task - 1 * executionDAOFacade.getWorkflowById(workflowId, true) >> workflow + 1 * executionDAOFacade.getTaskModel(taskId) >> task + 1 * executionDAOFacade.getWorkflowModel(workflowId, true) >> workflow 1 * executionDAOFacade.updateTask(task) - 1 * workflowSystemTask.start(workflow, task, workflowExecutor) >> { task.status = Task.Status.COMPLETED } + 1 * workflowSystemTask.start(workflow, task, workflowExecutor) >> { task.status = TaskModel.Status.COMPLETED } 1 * queueDAO.remove(queueName, taskId) 1 * workflowExecutor.decide(workflowId) // verify that workflow is decided - task.status == Task.Status.COMPLETED + task.status == TaskModel.Status.COMPLETED task.startTime != 0 // verify that startTime is set task.endTime != 0 // verify that endTime is set task.pollCount == 1 // verify that poll count is incremented @@ -288,28 +284,28 @@ class AsyncSystemTaskExecutorTest extends Specification { given: String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, taskDefName: "taskDefName", workflowPriority: 10) - Workflow workflow = new Workflow(workflowId: workflowId, status: RUNNING) + WorkflowModel workflow = new WorkflowModel(workflowId: workflowId, status: WorkflowModel.Status.RUNNING) when: executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task - 1 * executionDAOFacade.getWorkflowById(workflowId, true) >> workflow + 1 * executionDAOFacade.getTaskModel(taskId) >> task + 1 * executionDAOFacade.getWorkflowModel(workflowId, true) >> workflow 1 * executionDAOFacade.updateTask(task) // simulating a "start" failure that happens after the Task object is modified // the modification will be persisted 1 * workflowSystemTask.start(workflow, task, workflowExecutor) >> { - task.status = Task.Status.IN_PROGRESS + task.status = TaskModel.Status.IN_PROGRESS throw new RuntimeException("unknown system task failure") } 0 * workflowExecutor.decide(workflowId) // verify that workflow is NOT decided - task.status == Task.Status.IN_PROGRESS + task.status == TaskModel.Status.IN_PROGRESS task.startTime != 0 // verify that startTime is set task.endTime == 0 // verify that endTime is not set task.pollCount == 1 // verify that poll count is incremented @@ -319,26 +315,26 @@ class AsyncSystemTaskExecutorTest extends Specification { given: String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.SCHEDULED, taskId: taskId, workflowInstanceId: workflowId, taskDefName: "taskDefName", workflowPriority: 10) - Workflow workflow = new Workflow(workflowId: workflowId, status: RUNNING) + WorkflowModel workflow = new WorkflowModel(workflowId: workflowId, status: WorkflowModel.Status.RUNNING) String queueName = QueueUtils.getQueueName(task) when: executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task - 1 * executionDAOFacade.getWorkflowById(workflowId, true) >> workflow + 1 * executionDAOFacade.getTaskModel(taskId) >> task + 1 * executionDAOFacade.getWorkflowModel(workflowId, true) >> workflow 1 * executionDAOFacade.updateTask(task) // 1st call for pollCount, 2nd call for status update 1 * workflowSystemTask.isAsyncComplete(task) >> true - 1 * workflowSystemTask.start(workflow, task, workflowExecutor) >> { task.status = Task.Status.IN_PROGRESS } + 1 * workflowSystemTask.start(workflow, task, workflowExecutor) >> { task.status = TaskModel.Status.IN_PROGRESS } 1 * queueDAO.remove(queueName, taskId) 1 * workflowExecutor.decide(workflowId) // verify that workflow is decided - task.status == Task.Status.IN_PROGRESS + task.status == TaskModel.Status.IN_PROGRESS task.startTime != 0 // verify that startTime is set task.endTime == 0 // verify that endTime is not set task.pollCount == 1 // verify that poll count is incremented @@ -348,22 +344,22 @@ class AsyncSystemTaskExecutorTest extends Specification { given: String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.IN_PROGRESS, taskId: taskId, workflowInstanceId: workflowId, + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.IN_PROGRESS, taskId: taskId, workflowInstanceId: workflowId, rateLimitPerFrequency: 1, taskDefName: "taskDefName", workflowPriority: 10, pollCount: 1) - Workflow workflow = new Workflow(workflowId: workflowId, status: RUNNING) + WorkflowModel workflow = new WorkflowModel(workflowId: workflowId, status: WorkflowModel.Status.RUNNING) when: executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task - 1 * executionDAOFacade.getWorkflowById(workflowId, true) >> workflow + 1 * executionDAOFacade.getTaskModel(taskId) >> task + 1 * executionDAOFacade.getWorkflowModel(workflowId, true) >> workflow 1 * executionDAOFacade.updateTask(task) // 1st call for pollCount, 2nd call for status update 0 * workflowSystemTask.start(workflow, task, workflowExecutor) 1 * workflowSystemTask.execute(workflow, task, workflowExecutor) - task.status == Task.Status.IN_PROGRESS + task.status == TaskModel.Status.IN_PROGRESS task.endTime == 0 // verify that endTime is not set task.pollCount == 2 // verify that poll count is incremented } @@ -372,23 +368,23 @@ class AsyncSystemTaskExecutorTest extends Specification { given: String workflowId = "workflowId" String taskId = "taskId" - Task task = new Task(taskType: "type1", status: Task.Status.IN_PROGRESS, taskId: taskId, workflowInstanceId: workflowId, + TaskModel task = new TaskModel(taskType: "type1", status: TaskModel.Status.IN_PROGRESS, taskId: taskId, workflowInstanceId: workflowId, rateLimitPerFrequency: 1, taskDefName: "taskDefName", workflowPriority: 10, pollCount: 1) - Workflow workflow = new Workflow(workflowId: workflowId, status: RUNNING) + WorkflowModel workflow = new WorkflowModel(workflowId: workflowId, status: WorkflowModel.Status.RUNNING) when: executor.execute(workflowSystemTask, taskId) then: - 1 * executionDAOFacade.getTaskById(taskId) >> task - 1 * executionDAOFacade.getWorkflowById(workflowId, true) >> workflow + 1 * executionDAOFacade.getTaskModel(taskId) >> task + 1 * executionDAOFacade.getWorkflowModel(workflowId, true) >> workflow 1 * executionDAOFacade.updateTask(task) // only one call since pollCount is not incremented 1 * workflowSystemTask.isAsyncComplete(task) >> true 0 * workflowSystemTask.start(workflow, task, workflowExecutor) 1 * workflowSystemTask.execute(workflow, task, workflowExecutor) - task.status == Task.Status.IN_PROGRESS + task.status == TaskModel.Status.IN_PROGRESS task.endTime == 0 // verify that endTime is not set task.pollCount == 1 // verify that poll count is NOT incremented } diff --git a/core/src/test/groovy/com/netflix/conductor/core/execution/tasks/EventSpec.groovy b/core/src/test/groovy/com/netflix/conductor/core/execution/tasks/EventSpec.groovy index 239009e8d2..3b2977f509 100644 --- a/core/src/test/groovy/com/netflix/conductor/core/execution/tasks/EventSpec.groovy +++ b/core/src/test/groovy/com/netflix/conductor/core/execution/tasks/EventSpec.groovy @@ -1,28 +1,28 @@ /* - * Copyright 2021 Netflix, Inc. - *

    - * 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. + * Copyright 2022 Netflix, Inc. + *

    + * 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.core.execution.tasks -import com.fasterxml.jackson.core.JsonParseException -import com.fasterxml.jackson.databind.ObjectMapper -import com.netflix.conductor.common.metadata.tasks.Task import com.netflix.conductor.common.metadata.workflow.WorkflowDef -import com.netflix.conductor.common.run.Workflow import com.netflix.conductor.core.events.EventQueues import com.netflix.conductor.core.events.queue.Message import com.netflix.conductor.core.events.queue.ObservableQueue import com.netflix.conductor.core.exception.ApplicationException import com.netflix.conductor.core.utils.ParametersUtils +import com.netflix.conductor.model.TaskModel +import com.netflix.conductor.model.WorkflowModel + +import com.fasterxml.jackson.core.JsonParseException +import com.fasterxml.jackson.databind.ObjectMapper import spock.lang.Specification import spock.lang.Subject @@ -30,12 +30,12 @@ class EventSpec extends Specification { EventQueues eventQueues ParametersUtils parametersUtils - ObjectMapper mapper + ObjectMapper objectMapper ObservableQueue observableQueue String payloadJSON = "payloadJSON" WorkflowDef testWorkflowDefinition - Workflow workflow + WorkflowModel workflow @Subject Event event @@ -44,14 +44,14 @@ class EventSpec extends Specification { parametersUtils = Mock(ParametersUtils.class) eventQueues = Mock(EventQueues.class) observableQueue = Mock(ObservableQueue.class) - mapper = Mock(ObjectMapper.class) { + objectMapper = Mock(ObjectMapper.class) { writeValueAsString(_) >> payloadJSON } testWorkflowDefinition = new WorkflowDef(name: "testWorkflow", version: 2) - workflow = new Workflow(workflowDefinition: testWorkflowDefinition, workflowId: 'workflowId', correlationId: 'corrId') + workflow = new WorkflowModel(workflowDefinition: testWorkflowDefinition, workflowId: 'workflowId', correlationId: 'corrId') - event = new Event(eventQueues, parametersUtils, mapper) + event = new Event(eventQueues, parametersUtils, objectMapper) } def "verify that event task is async"() { @@ -65,7 +65,7 @@ class EventSpec extends Specification { def "event cancel calls ack on the queue"() { given: // status is intentionally left as null - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': 'conductor']) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': 'conductor']) String queueName = "conductor:${workflow.workflowName}:${task.referenceTaskName}" @@ -83,7 +83,7 @@ class EventSpec extends Specification { def "event task with 'conductor' as sink"() { given: - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': 'conductor']) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': 'conductor']) String queueName = "conductor:${workflow.workflowName}:${task.referenceTaskName}" Message expectedMessage @@ -92,7 +92,7 @@ class EventSpec extends Specification { event.start(workflow, task, null) then: - task.status == Task.Status.COMPLETED + task.status == TaskModel.Status.COMPLETED verifyOutputData(task, queueName) 1 * parametersUtils.getTaskInputV2(_, workflow, task.taskId, _) >> ['sink': 'conductor'] @@ -108,7 +108,7 @@ class EventSpec extends Specification { String eventName = 'testEvent' String sinkValue = "conductor:$eventName".toString() - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': sinkValue]) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': sinkValue]) String queueName = "conductor:${workflow.workflowName}:$eventName" Message expectedMessage @@ -117,7 +117,7 @@ class EventSpec extends Specification { event.start(workflow, task, null) then: - task.status == Task.Status.COMPLETED + task.status == TaskModel.Status.COMPLETED verifyOutputData(task, queueName) 1 * parametersUtils.getTaskInputV2(_, workflow, task.taskId, _) >> ['sink': sinkValue] @@ -133,7 +133,7 @@ class EventSpec extends Specification { String eventName = 'testEvent' String sinkValue = "sqs:$eventName".toString() - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': sinkValue]) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': sinkValue]) // for non conductor queues, queueName is the same as the value of the 'sink' field in the inputData String queueName = sinkValue @@ -143,7 +143,7 @@ class EventSpec extends Specification { event.start(workflow, task, null) then: - task.status == Task.Status.COMPLETED + task.status == TaskModel.Status.COMPLETED verifyOutputData(task, queueName) 1 * parametersUtils.getTaskInputV2(_, workflow, task.taskId, _) >> ['sink': sinkValue] @@ -156,7 +156,7 @@ class EventSpec extends Specification { def "event task with 'conductor' as sink and async complete"() { given: - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': 'conductor', 'asyncComplete': true]) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': 'conductor', 'asyncComplete': true]) String queueName = "conductor:${workflow.workflowName}:${task.referenceTaskName}" Message expectedMessage @@ -165,7 +165,7 @@ class EventSpec extends Specification { event.start(workflow, task, null) then: - task.status == Task.Status.IN_PROGRESS + task.status == TaskModel.Status.IN_PROGRESS verifyOutputData(task, queueName) 1 * parametersUtils.getTaskInputV2(_, workflow, task.taskId, _) >> ['sink': 'conductor'] @@ -180,13 +180,13 @@ class EventSpec extends Specification { given: String sinkValue = 'conductorinvalidsink' - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': sinkValue]) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': sinkValue]) when: event.start(workflow, task, null) then: - task.status == Task.Status.FAILED + task.status == TaskModel.Status.FAILED task.reasonForIncompletion != null 1 * parametersUtils.getTaskInputV2(_, workflow, task.taskId, _) >> ['sink': sinkValue] @@ -196,7 +196,7 @@ class EventSpec extends Specification { given: String sinkValue = 'rabbitmq:abc_123' - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': sinkValue]) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', inputData: ['sink': sinkValue]) // for non conductor queues, queueName is the same as the value of the 'sink' field in the inputData String queueName = sinkValue @@ -205,7 +205,7 @@ class EventSpec extends Specification { event.start(workflow, task, null) then: - task.status == Task.Status.FAILED + task.status == TaskModel.Status.FAILED task.reasonForIncompletion != null 1 * parametersUtils.getTaskInputV2(_, workflow, task.taskId, _) >> ['sink': sinkValue] @@ -216,13 +216,13 @@ class EventSpec extends Specification { given: String sinkValue = 'conductor' - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', status: Task.Status.SCHEDULED, inputData: ['sink': sinkValue]) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', status: TaskModel.Status.SCHEDULED, inputData: ['sink': sinkValue]) when: event.start(workflow, task, null) then: - task.status == Task.Status.SCHEDULED + task.status == TaskModel.Status.SCHEDULED 1 * parametersUtils.getTaskInputV2(_, workflow, task.taskId, _) >> ['sink': sinkValue] 1 * eventQueues.getQueue(_) >> observableQueue @@ -234,13 +234,13 @@ class EventSpec extends Specification { given: String sinkValue = 'conductor' - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', status: Task.Status.SCHEDULED, inputData: ['sink': sinkValue]) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', status: TaskModel.Status.SCHEDULED, inputData: ['sink': sinkValue]) when: event.start(workflow, task, null) then: - task.status == Task.Status.FAILED + task.status == TaskModel.Status.FAILED task.reasonForIncompletion != null 1 * parametersUtils.getTaskInputV2(_, workflow, task.taskId, _) >> ['sink': sinkValue] @@ -253,36 +253,36 @@ class EventSpec extends Specification { given: String sinkValue = 'conductor' - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', status: Task.Status.SCHEDULED, inputData: ['sink': sinkValue]) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', status: TaskModel.Status.SCHEDULED, inputData: ['sink': sinkValue]) when: event.start(workflow, task, null) then: - task.status == Task.Status.FAILED + task.status == TaskModel.Status.FAILED task.reasonForIncompletion != null - 1 * mapper.writeValueAsString(_ as Map) >> { throw new JsonParseException(null, "invalid json") } + 1 * objectMapper.writeValueAsString(_ as Map) >> { throw new JsonParseException(null, "invalid json") } } def "event task fails with an unexpected exception"() { given: String sinkValue = 'conductor' - Task task = new Task(referenceTaskName: 'task0', taskId: 'task_id_0', status: Task.Status.SCHEDULED, inputData: ['sink': sinkValue]) + TaskModel task = new TaskModel(referenceTaskName: 'task0', taskId: 'task_id_0', status: TaskModel.Status.SCHEDULED, inputData: ['sink': sinkValue]) when: event.start(workflow, task, null) then: - task.status == Task.Status.FAILED + task.status == TaskModel.Status.FAILED task.reasonForIncompletion != null 1 * parametersUtils.getTaskInputV2(_, workflow, task.taskId, _) >> ['sink': sinkValue] 1 * eventQueues.getQueue(_) >> { throw new NullPointerException("some object is null") } } - private void verifyOutputData(Task task, String queueName) { + private void verifyOutputData(TaskModel task, String queueName) { assert task.outputData != null assert task.outputData['event_produced'] == queueName assert task.outputData['workflowInstanceId'] == workflow.workflowId @@ -291,7 +291,7 @@ class EventSpec extends Specification { assert task.outputData['correlationId'] == workflow.correlationId } - private void verifyMessage(Message expectedMessage, Task task) { + private void verifyMessage(Message expectedMessage, TaskModel task) { assert expectedMessage != null assert expectedMessage.id == task.taskId assert expectedMessage.receipt == task.taskId diff --git a/core/src/test/groovy/com/netflix/conductor/core/execution/tasks/IsolatedTaskQueueProducerSpec.groovy b/core/src/test/groovy/com/netflix/conductor/core/execution/tasks/IsolatedTaskQueueProducerSpec.groovy index cb00c315d9..3673c00911 100644 --- a/core/src/test/groovy/com/netflix/conductor/core/execution/tasks/IsolatedTaskQueueProducerSpec.groovy +++ b/core/src/test/groovy/com/netflix/conductor/core/execution/tasks/IsolatedTaskQueueProducerSpec.groovy @@ -1,26 +1,27 @@ /* - * Copyright 2021 Netflix, Inc. - *

    - * 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. + * Copyright 2022 Netflix, Inc. + *

    + * 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.core.execution.tasks +import java.time.Duration + +import org.junit.Test + import com.netflix.conductor.common.metadata.tasks.TaskDef import com.netflix.conductor.service.MetadataService -import org.junit.Test + import spock.lang.Specification import spock.lang.Subject -import java.time.Duration - class IsolatedTaskQueueProducerSpec extends Specification { SystemTaskWorker systemTaskWorker diff --git a/core/src/test/java/com/netflix/conductor/core/orchestration/ExecutionDAOFacadeTest.java b/core/src/test/java/com/netflix/conductor/core/dal/ExecutionDAOFacadeTest.java similarity index 78% rename from core/src/test/java/com/netflix/conductor/core/orchestration/ExecutionDAOFacadeTest.java rename to core/src/test/java/com/netflix/conductor/core/dal/ExecutionDAOFacadeTest.java index f3dc4db6ff..97e2dd63ff 100644 --- a/core/src/test/java/com/netflix/conductor/core/orchestration/ExecutionDAOFacadeTest.java +++ b/core/src/test/java/com/netflix/conductor/core/dal/ExecutionDAOFacadeTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -10,7 +10,7 @@ * 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.core.orchestration; +package com.netflix.conductor.core.dal; import java.io.InputStream; import java.util.ArrayList; @@ -29,31 +29,16 @@ import com.netflix.conductor.common.metadata.events.EventExecution; import com.netflix.conductor.common.run.SearchResult; import com.netflix.conductor.common.run.Workflow; -import com.netflix.conductor.common.run.Workflow.WorkflowStatus; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.core.execution.TestDeciderService; -import com.netflix.conductor.dao.ConcurrentExecutionLimitDAO; -import com.netflix.conductor.dao.ExecutionDAO; -import com.netflix.conductor.dao.IndexDAO; -import com.netflix.conductor.dao.PollDataDAO; -import com.netflix.conductor.dao.QueueDAO; -import com.netflix.conductor.dao.RateLimitingDAO; +import com.netflix.conductor.dao.*; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; @ContextConfiguration(classes = {TestObjectMapperConfiguration.class}) @RunWith(SpringRunner.class) @@ -61,6 +46,7 @@ public class ExecutionDAOFacadeTest { private ExecutionDAO executionDAO; private IndexDAO indexDAO; + private ModelMapper modelMapper; private ExecutionDAOFacade executionDAOFacade; @Autowired private ObjectMapper objectMapper; @@ -70,6 +56,7 @@ public void setUp() { executionDAO = mock(ExecutionDAO.class); QueueDAO queueDAO = mock(QueueDAO.class); indexDAO = mock(IndexDAO.class); + modelMapper = mock(ModelMapper.class); RateLimitingDAO rateLimitingDao = mock(RateLimitingDAO.class); ConcurrentExecutionLimitDAO concurrentExecutionLimitDAO = mock(ConcurrentExecutionLimitDAO.class); @@ -85,24 +72,35 @@ public void setUp() { rateLimitingDao, concurrentExecutionLimitDAO, pollDataDAO, + modelMapper, objectMapper, properties); } @Test - public void tesGetWorkflowById() throws Exception { - when(executionDAO.getWorkflow(any(), anyBoolean())).thenReturn(new Workflow()); - Workflow workflow = executionDAOFacade.getWorkflowById("workflowId", true); + public void testGetWorkflow() throws Exception { + when(executionDAO.getWorkflow(any(), anyBoolean())).thenReturn(new WorkflowModel()); + when(modelMapper.getWorkflow(any(WorkflowModel.class))).thenReturn(new Workflow()); + Workflow workflow = executionDAOFacade.getWorkflow("workflowId", true); assertNotNull(workflow); verify(indexDAO, never()).get(any(), any()); + } + + @Test + public void testGetWorkflowModel() throws Exception { + when(executionDAO.getWorkflow(any(), anyBoolean())).thenReturn(new WorkflowModel()); + when(modelMapper.getFullCopy(any(WorkflowModel.class))).thenReturn(new WorkflowModel()); + WorkflowModel workflowModel = executionDAOFacade.getWorkflowModel("workflowId", true); + assertNotNull(workflowModel); + verify(indexDAO, never()).get(any(), any()); when(executionDAO.getWorkflow(any(), anyBoolean())).thenReturn(null); InputStream stream = ExecutionDAOFacadeTest.class.getResourceAsStream("/test.json"); byte[] bytes = IOUtils.toByteArray(stream); String jsonString = new String(bytes); when(indexDAO.get(any(), any())).thenReturn(jsonString); - workflow = executionDAOFacade.getWorkflowById("workflowId", true); - assertNotNull(workflow); + workflowModel = executionDAOFacade.getWorkflowModel("wokflowId", true); + assertNotNull(workflowModel); verify(indexDAO, times(1)).get(any(), any()); } @@ -110,10 +108,12 @@ public void tesGetWorkflowById() throws Exception { public void testGetWorkflowsByCorrelationId() { when(executionDAO.canSearchAcrossWorkflows()).thenReturn(true); when(executionDAO.getWorkflowsByCorrelationId(any(), any(), anyBoolean())) - .thenReturn(Collections.singletonList(new Workflow())); + .thenReturn(Collections.singletonList(new WorkflowModel())); + when(modelMapper.getWorkflow(any(WorkflowModel.class))).thenReturn(new Workflow()); List workflows = executionDAOFacade.getWorkflowsByCorrelationId( "workflowName", "correlationId", true); + assertNotNull(workflows); assertEquals(1, workflows.size()); verify(indexDAO, never()) @@ -126,7 +126,8 @@ public void testGetWorkflowsByCorrelationId() { searchResult.setResults(workflowIds); when(indexDAO.searchWorkflows(anyString(), anyString(), anyInt(), anyInt(), any())) .thenReturn(searchResult); - when(executionDAO.getWorkflow("workflowId", true)).thenReturn(new Workflow()); + when(executionDAO.getWorkflow("workflowId", true)).thenReturn(new WorkflowModel()); + when(modelMapper.getWorkflow(any(WorkflowModel.class))).thenReturn(new Workflow()); workflows = executionDAOFacade.getWorkflowsByCorrelationId( "workflowName", "correlationId", true); @@ -136,8 +137,8 @@ public void testGetWorkflowsByCorrelationId() { @Test public void testRemoveWorkflow() { - Workflow workflow = new Workflow(); - workflow.setStatus(WorkflowStatus.COMPLETED); + WorkflowModel workflow = new WorkflowModel(); + workflow.setStatus(WorkflowModel.Status.COMPLETED); when(executionDAO.getWorkflow(anyString(), anyBoolean())).thenReturn(workflow); executionDAOFacade.removeWorkflow("workflowId", false); verify(indexDAO, never()).updateWorkflow(any(), any(), any()); @@ -147,7 +148,7 @@ public void testRemoveWorkflow() { @Test public void testArchiveWorkflow() throws Exception { InputStream stream = TestDeciderService.class.getResourceAsStream("/completed.json"); - Workflow workflow = objectMapper.readValue(stream, Workflow.class); + WorkflowModel workflow = objectMapper.readValue(stream, WorkflowModel.class); when(executionDAO.getWorkflow(anyString(), anyBoolean())).thenReturn(workflow); executionDAOFacade.removeWorkflow("workflowId", true); diff --git a/core/src/test/java/com/netflix/conductor/core/events/TestDefaultEventProcessor.java b/core/src/test/java/com/netflix/conductor/core/events/TestDefaultEventProcessor.java index 39e60fe346..d9aaa127ab 100644 --- a/core/src/test/java/com/netflix/conductor/core/events/TestDefaultEventProcessor.java +++ b/core/src/test/java/com/netflix/conductor/core/events/TestDefaultEventProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -37,17 +37,19 @@ import com.netflix.conductor.common.metadata.events.EventHandler.Action.Type; import com.netflix.conductor.common.metadata.events.EventHandler.StartWorkflow; import com.netflix.conductor.common.metadata.events.EventHandler.TaskDetails; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.config.ConductorProperties; +import com.netflix.conductor.core.dal.ModelMapper; import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.core.events.queue.ObservableQueue; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.evaluators.Evaluator; import com.netflix.conductor.core.execution.evaluators.JavascriptEvaluator; +import com.netflix.conductor.core.utils.ExternalPayloadStorageUtils; import com.netflix.conductor.core.utils.JsonUtils; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.service.ExecutionService; import com.netflix.conductor.service.MetadataService; @@ -60,12 +62,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.atMost; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @ContextConfiguration( classes = { @@ -80,8 +77,9 @@ public class TestDefaultEventProcessor { private MetadataService metadataService; private ExecutionService executionService; private WorkflowExecutor workflowExecutor; + private ModelMapper modelMapper; + private ExternalPayloadStorageUtils externalPayloadStorageUtils; private SimpleActionProcessor actionProcessor; - private EventQueues eventQueues; private ParametersUtils parametersUtils; private JsonUtils jsonUtils; private ConductorProperties properties; @@ -103,6 +101,8 @@ public void setup() { metadataService = mock(MetadataService.class); executionService = mock(ExecutionService.class); workflowExecutor = mock(WorkflowExecutor.class); + externalPayloadStorageUtils = mock(ExternalPayloadStorageUtils.class); + modelMapper = new ModelMapper(externalPayloadStorageUtils); actionProcessor = mock(SimpleActionProcessor.class); parametersUtils = new ParametersUtils(objectMapper); jsonUtils = new JsonUtils(objectMapper); @@ -184,16 +184,18 @@ public void testEventProcessor() { .when(workflowExecutor) .updateTask(any()); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setReferenceTaskName(completeTaskAction.getComplete_task().getTaskRefName()); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setTasks(Collections.singletonList(task)); when(workflowExecutor.getWorkflow( completeTaskAction.getComplete_task().getWorkflowId(), true)) .thenReturn(workflow); + doNothing().when(externalPayloadStorageUtils).verifyAndUpload(any(), any()); SimpleActionProcessor actionProcessor = - new SimpleActionProcessor(workflowExecutor, parametersUtils, jsonUtils); + new SimpleActionProcessor( + workflowExecutor, modelMapper, parametersUtils, jsonUtils); DefaultEventProcessor eventProcessor = new DefaultEventProcessor( @@ -259,7 +261,8 @@ public void testEventHandlerWithCondition() { eq(null)); SimpleActionProcessor actionProcessor = - new SimpleActionProcessor(workflowExecutor, parametersUtils, jsonUtils); + new SimpleActionProcessor( + workflowExecutor, modelMapper, parametersUtils, jsonUtils); DefaultEventProcessor eventProcessor = new DefaultEventProcessor( @@ -323,7 +326,8 @@ public void testEventHandlerWithConditionEvaluator() { eq(null)); SimpleActionProcessor actionProcessor = - new SimpleActionProcessor(workflowExecutor, parametersUtils, jsonUtils); + new SimpleActionProcessor( + workflowExecutor, modelMapper, parametersUtils, jsonUtils); DefaultEventProcessor eventProcessor = new DefaultEventProcessor( diff --git a/core/src/test/java/com/netflix/conductor/core/events/TestSimpleActionProcessor.java b/core/src/test/java/com/netflix/conductor/core/events/TestSimpleActionProcessor.java index 5e124e7d9c..c6858b05ec 100644 --- a/core/src/test/java/com/netflix/conductor/core/events/TestSimpleActionProcessor.java +++ b/core/src/test/java/com/netflix/conductor/core/events/TestSimpleActionProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -28,14 +28,16 @@ import com.netflix.conductor.common.metadata.events.EventHandler.Action.Type; import com.netflix.conductor.common.metadata.events.EventHandler.StartWorkflow; import com.netflix.conductor.common.metadata.events.EventHandler.TaskDetails; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskResult; import com.netflix.conductor.common.metadata.tasks.TaskResult.Status; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.core.dal.ModelMapper; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.core.utils.ExternalPayloadStorageUtils; import com.netflix.conductor.core.utils.JsonUtils; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -47,6 +49,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -56,22 +59,27 @@ public class TestSimpleActionProcessor { private WorkflowExecutor workflowExecutor; + private ExternalPayloadStorageUtils externalPayloadStorageUtils; private SimpleActionProcessor actionProcessor; @Autowired private ObjectMapper objectMapper; @Before public void setup() { + externalPayloadStorageUtils = mock(ExternalPayloadStorageUtils.class); + workflowExecutor = mock(WorkflowExecutor.class); + ModelMapper modelMapper = new ModelMapper(externalPayloadStorageUtils); actionProcessor = new SimpleActionProcessor( workflowExecutor, + modelMapper, new ParametersUtils(objectMapper), new JsonUtils(objectMapper)); } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) @Test public void testStartWorkflow_correlationId() throws Exception { StartWorkflow startWorkflow = new StartWorkflow(); @@ -203,12 +211,13 @@ public void testCompleteTask() throws Exception { "{\"workflowId\":\"workflow_1\",\"Message\":{\"someKey\":\"someData\",\"someNullKey\":null}}"; Object payload = objectMapper.readValue(payloadJson, Object.class); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setReferenceTaskName("testTask"); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.getTasks().add(task); when(workflowExecutor.getWorkflow(eq("workflow_1"), anyBoolean())).thenReturn(workflow); + doNothing().when(externalPayloadStorageUtils).verifyAndUpload(any(), any()); actionProcessor.execute(action, payload, "testEvent", "testMessage"); @@ -245,11 +254,12 @@ public void testCompleteTaskByTaskId() throws Exception { objectMapper.readValue( "{\"workflowId\":\"workflow_1\", \"taskId\":\"task_1\"}", Object.class); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskId("task_1"); task.setReferenceTaskName("testTask"); when(workflowExecutor.getTask(eq("task_1"))).thenReturn(task); + doNothing().when(externalPayloadStorageUtils).verifyAndUpload(any(), any()); actionProcessor.execute(action, payload, "testEvent", "testMessage"); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/TestDeciderOutcomes.java b/core/src/test/java/com/netflix/conductor/core/execution/TestDeciderOutcomes.java index 068d3b9f53..910446103b 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/TestDeciderOutcomes.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/TestDeciderOutcomes.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -35,13 +35,10 @@ import org.springframework.util.unit.DataSize; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; 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.core.config.ConductorProperties; import com.netflix.conductor.core.execution.DeciderService.DeciderOutcome; import com.netflix.conductor.core.execution.evaluators.Evaluator; @@ -66,6 +63,8 @@ import com.netflix.conductor.core.utils.ExternalPayloadStorageUtils; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -185,9 +184,9 @@ public void testWorkflowWithNoTasks() throws Exception { WorkflowDef def = objectMapper.readValue(stream, WorkflowDef.class); assertNotNull(def); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); - workflow.setStartTime(0); + workflow.setCreateTime(0L); workflow.getInput().put("param1", "nested"); workflow.getInput().put("param2", "one"); @@ -197,7 +196,7 @@ public void testWorkflowWithNoTasks() throws Exception { assertTrue(outcome.tasksToBeUpdated.isEmpty()); assertEquals(3, outcome.tasksToBeScheduled.size()); - outcome.tasksToBeScheduled.forEach(t -> t.setStatus(Status.COMPLETED)); + outcome.tasksToBeScheduled.forEach(t -> t.setStatus(TaskModel.Status.COMPLETED)); workflow.getTasks().addAll(outcome.tasksToBeScheduled); outcome = deciderService.decide(workflow); assertFalse(outcome.isComplete); @@ -213,9 +212,9 @@ public void testWorkflowWithNoTasksWithSwitch() throws Exception { WorkflowDef def = objectMapper.readValue(stream, WorkflowDef.class); assertNotNull(def); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); - workflow.setStartTime(0); + workflow.setCreateTime(0L); workflow.getInput().put("param1", "nested"); workflow.getInput().put("param2", "one"); @@ -225,7 +224,7 @@ public void testWorkflowWithNoTasksWithSwitch() throws Exception { assertTrue(outcome.tasksToBeUpdated.isEmpty()); assertEquals(3, outcome.tasksToBeScheduled.size()); - outcome.tasksToBeScheduled.forEach(t -> t.setStatus(Status.COMPLETED)); + outcome.tasksToBeScheduled.forEach(t -> t.setStatus(TaskModel.Status.COMPLETED)); workflow.getTasks().addAll(outcome.tasksToBeScheduled); outcome = deciderService.decide(workflow); assertFalse(outcome.isComplete); @@ -250,10 +249,10 @@ public void testRetries() { def.getTasks().add(workflowTask); def.setSchemaVersion(2); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); workflow.getInput().put("requestId", 123); - workflow.setStartTime(System.currentTimeMillis()); + workflow.setCreateTime(System.currentTimeMillis()); DeciderOutcome outcome = deciderService.decide(workflow); assertNotNull(outcome); @@ -266,7 +265,7 @@ public void testRetries() { assertEquals(task1Id, outcome.tasksToBeScheduled.get(0).getInputData().get("taskId")); assertEquals(123, outcome.tasksToBeScheduled.get(0).getInputData().get("requestId")); - outcome.tasksToBeScheduled.get(0).setStatus(Status.FAILED); + outcome.tasksToBeScheduled.get(0).setStatus(TaskModel.Status.FAILED); workflow.getTasks().addAll(outcome.tasksToBeScheduled); outcome = deciderService.decide(workflow); @@ -317,10 +316,10 @@ public void testRetries() { input.put("k1", 1); forkedInputs.put(wft.getTaskReferenceName(), input); } - workflow = new Workflow(); + workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); workflow.getInput().put("requestId", 123); - workflow.setStartTime(System.currentTimeMillis()); + workflow.setCreateTime(System.currentTimeMillis()); workflow.getInput().put("forks", forks); workflow.getInput().put("forkedInputs", forkedInputs); @@ -337,8 +336,8 @@ public void testRetries() { outcome.tasksToBeScheduled.get(1).getInputData().get("taskId")); task1Id = outcome.tasksToBeScheduled.get(1).getTaskId(); - outcome.tasksToBeScheduled.get(1).setStatus(Status.FAILED); - for (Task taskToBeScheduled : outcome.tasksToBeScheduled) { + outcome.tasksToBeScheduled.get(1).setStatus(TaskModel.Status.FAILED); + for (TaskModel taskToBeScheduled : outcome.tasksToBeScheduled) { taskToBeScheduled.setUpdateTime(System.currentTimeMillis()); } workflow.getTasks().addAll(outcome.tasksToBeScheduled); @@ -348,12 +347,12 @@ public void testRetries() { outcome.tasksToBeScheduled.stream() .anyMatch(task1 -> task1.getReferenceTaskName().equals("f0"))); - Optional optionalTask = + Optional optionalTask = outcome.tasksToBeScheduled.stream() .filter(t -> t.getReferenceTaskName().equals("f0")) .findFirst(); assertTrue(optionalTask.isPresent()); - Task task = optionalTask.get(); + TaskModel task = optionalTask.get(); assertEquals("v", task.getInputData().get("k")); assertEquals(1, task.getInputData().get("k1")); assertEquals(task.getTaskId(), task.getInputData().get("taskId")); @@ -384,9 +383,9 @@ public void testOptional() { def.getTasks().add(task2); def.setSchemaVersion(2); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); - workflow.setStartTime(System.currentTimeMillis()); + workflow.setCreateTime(System.currentTimeMillis()); DeciderOutcome outcome = deciderService.decide(workflow); assertNotNull(outcome); assertEquals(1, outcome.tasksToBeScheduled.size()); @@ -400,7 +399,7 @@ public void testOptional() { workflow.getTasks().clear(); workflow.getTasks().addAll(outcome.tasksToBeScheduled); - workflow.getTasks().get(0).setStatus(Status.FAILED); + workflow.getTasks().get(0).setStatus(TaskModel.Status.FAILED); outcome = deciderService.decide(workflow); @@ -408,7 +407,7 @@ public void testOptional() { assertEquals(1, outcome.tasksToBeUpdated.size()); assertEquals(1, outcome.tasksToBeScheduled.size()); - assertEquals(Task.Status.FAILED, workflow.getTasks().get(0).getStatus()); + assertEquals(TaskModel.Status.FAILED, workflow.getTasks().get(0).getStatus()); assertEquals(task1Id, outcome.tasksToBeUpdated.get(0).getTaskId()); assertEquals( task1.getTaskReferenceName(), @@ -420,7 +419,7 @@ public void testOptional() { workflow.getTasks().clear(); workflow.getTasks().addAll(outcome.tasksToBeScheduled); - workflow.getTasks().get(0).setStatus(Status.FAILED); + workflow.getTasks().get(0).setStatus(TaskModel.Status.FAILED); outcome = deciderService.decide(workflow); @@ -428,7 +427,8 @@ public void testOptional() { assertEquals(1, outcome.tasksToBeUpdated.size()); assertEquals(1, outcome.tasksToBeScheduled.size()); - assertEquals(Task.Status.COMPLETED_WITH_ERRORS, workflow.getTasks().get(0).getStatus()); + assertEquals( + TaskModel.Status.COMPLETED_WITH_ERRORS, workflow.getTasks().get(0).getStatus()); assertEquals(task1Id, outcome.tasksToBeUpdated.get(0).getTaskId()); assertEquals( task2.getTaskReferenceName(), @@ -458,7 +458,7 @@ public void testOptionalWithDynamicFork() { def.getTasks().add(task2); def.setSchemaVersion(2); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); List forks = new LinkedList<>(); Map> forkedInputs = new HashMap<>(); @@ -477,22 +477,22 @@ public void testOptionalWithDynamicFork() { workflow.getInput().put("forks", forks); workflow.getInput().put("forkedInputs", forkedInputs); - workflow.setStartTime(System.currentTimeMillis()); + workflow.setCreateTime(System.currentTimeMillis()); DeciderOutcome outcome = deciderService.decide(workflow); assertNotNull(outcome); assertEquals(5, outcome.tasksToBeScheduled.size()); assertEquals(0, outcome.tasksToBeUpdated.size()); assertEquals(TASK_TYPE_FORK, outcome.tasksToBeScheduled.get(0).getTaskType()); - assertEquals(Task.Status.COMPLETED, outcome.tasksToBeScheduled.get(0).getStatus()); + assertEquals(TaskModel.Status.COMPLETED, outcome.tasksToBeScheduled.get(0).getStatus()); for (int retryCount = 0; retryCount < 4; retryCount++) { - for (Task taskToBeScheduled : outcome.tasksToBeScheduled) { + for (TaskModel taskToBeScheduled : outcome.tasksToBeScheduled) { if (taskToBeScheduled.getTaskDefName().equals("join0")) { - assertEquals(Task.Status.IN_PROGRESS, taskToBeScheduled.getStatus()); + assertEquals(TaskModel.Status.IN_PROGRESS, taskToBeScheduled.getStatus()); } else if (taskToBeScheduled.getTaskType().matches("(f0|f1|f2)")) { - assertEquals(Task.Status.SCHEDULED, taskToBeScheduled.getStatus()); - taskToBeScheduled.setStatus(Status.FAILED); + assertEquals(TaskModel.Status.SCHEDULED, taskToBeScheduled.getStatus()); + taskToBeScheduled.setStatus(TaskModel.Status.FAILED); } taskToBeScheduled.setUpdateTime(System.currentTimeMillis()); @@ -505,13 +505,14 @@ public void testOptionalWithDynamicFork() { for (int i = 0; i < 3; i++) { assertEquals( - Task.Status.COMPLETED_WITH_ERRORS, outcome.tasksToBeUpdated.get(i).getStatus()); + TaskModel.Status.COMPLETED_WITH_ERRORS, + outcome.tasksToBeUpdated.get(i).getStatus()); assertEquals("f" + (i), outcome.tasksToBeUpdated.get(i).getTaskDefName()); } - assertEquals(Task.Status.IN_PROGRESS, outcome.tasksToBeScheduled.get(0).getStatus()); + assertEquals(TaskModel.Status.IN_PROGRESS, outcome.tasksToBeScheduled.get(0).getStatus()); new Join().execute(workflow, outcome.tasksToBeScheduled.get(0), null); - assertEquals(Task.Status.COMPLETED, outcome.tasksToBeScheduled.get(0).getStatus()); + assertEquals(TaskModel.Status.COMPLETED, outcome.tasksToBeScheduled.get(0).getStatus()); } @Test @@ -553,9 +554,9 @@ public void testDecisionCases() { def.getTasks().add(decide); def.setSchemaVersion(2); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); - workflow.setStartTime(System.currentTimeMillis()); + workflow.setCreateTime(System.currentTimeMillis()); DeciderOutcome outcome = deciderService.decide(workflow); assertNotNull(outcome); assertEquals(2, outcome.tasksToBeScheduled.size()); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/TestDeciderService.java b/core/src/test/java/com/netflix/conductor/core/execution/TestDeciderService.java index 49cf40259d..ed44d8cfb9 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/TestDeciderService.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/TestDeciderService.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -15,16 +15,7 @@ import java.io.IOException; import java.io.InputStream; import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -47,16 +38,12 @@ import org.springframework.test.context.junit4.SpringRunner; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.tasks.TaskDef.TimeoutPolicy; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.SubWorkflowParams; 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.common.run.Workflow.WorkflowStatus; import com.netflix.conductor.common.utils.TaskUtils; import com.netflix.conductor.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.execution.DeciderService.DeciderOutcome; @@ -67,6 +54,8 @@ import com.netflix.conductor.core.utils.ExternalPayloadStorageUtils; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.spectator.api.Counter; import com.netflix.spectator.api.DefaultRegistry; import com.netflix.spectator.api.Registry; @@ -74,29 +63,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import static com.netflix.conductor.common.metadata.tasks.TaskType.DECISION; -import static com.netflix.conductor.common.metadata.tasks.TaskType.FORK_JOIN; -import static com.netflix.conductor.common.metadata.tasks.TaskType.JOIN; -import static com.netflix.conductor.common.metadata.tasks.TaskType.SIMPLE; -import static com.netflix.conductor.common.metadata.tasks.TaskType.SUB_WORKFLOW; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_SUB_WORKFLOW; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_TERMINATE; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static com.netflix.conductor.common.metadata.tasks.TaskType.*; + +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; @ContextConfiguration( classes = {TestObjectMapperConfiguration.class, TestDeciderService.TestConfiguration.class}) @@ -116,7 +87,7 @@ public SubWorkflow subWorkflow(ObjectMapper objectMapper) { public WorkflowSystemTaskStub asyncCompleteSystemTask() { return new WorkflowSystemTaskStub("asyncCompleteSystemTask") { @Override - public boolean isAsyncComplete(Task task) { + public boolean isAsyncComplete(TaskModel task) { return true; } }; @@ -192,7 +163,7 @@ public void setup() { @Test public void testGetTaskInputV2() { - Workflow workflow = createDefaultWorkflow(); + WorkflowModel workflow = createDefaultWorkflow(); workflow.getWorkflowDefinition().setSchemaVersion(2); @@ -229,7 +200,7 @@ public void testGetTaskInputV2() { @Test public void testGetTaskInputV2Partial() { - Workflow workflow = createDefaultWorkflow(); + WorkflowModel workflow = createDefaultWorkflow(); System.setProperty("EC2_INSTANCE", "i-123abcdef990"); workflow.getWorkflowDefinition().setSchemaVersion(2); @@ -308,10 +279,10 @@ public void testGetTaskInput() { def.setName("testGetTaskInput"); def.setSchemaVersion(2); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); workflow.getInput().put("requestId", "request id 001"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setReferenceTaskName("task2"); task.getOutputData().put("location", "http://location"); task.getOutputData().put("isPersonActive", true); @@ -340,11 +311,11 @@ public void testGetTaskInputV1() { WorkflowDef def = new WorkflowDef(); def.setSchemaVersion(1); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); workflow.getInput().put("requestId", "request id 001"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setReferenceTaskName("task2"); task.getOutputData().put("location", "http://location"); task.getOutputData().put("isPersonActive", true); @@ -377,7 +348,7 @@ public void testGetTaskInputV2WithInputTemplate() { workflowDef.setName("testGetTaskInputV2WithInputTemplate"); workflowDef.setVersion(1); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); workflow.setInput(workflowInput); @@ -467,46 +438,46 @@ public void testCaseStatement() { WorkflowDef def = createConditionalWF(); - Workflow wf = new Workflow(); - wf.setWorkflowDefinition(def); - wf.setCreateTime(0L); - wf.setWorkflowId("a"); - wf.setCorrelationId("b"); - wf.setStatus(WorkflowStatus.RUNNING); + WorkflowModel workflow = new WorkflowModel(); + workflow.setWorkflowDefinition(def); + workflow.setCreateTime(0L); + workflow.setWorkflowId("a"); + workflow.setCorrelationId("b"); + workflow.setStatus(WorkflowModel.Status.RUNNING); - DeciderOutcome outcome = deciderService.decide(wf); - List scheduledTasks = outcome.tasksToBeScheduled; + DeciderOutcome outcome = deciderService.decide(workflow); + List scheduledTasks = outcome.tasksToBeScheduled; assertNotNull(scheduledTasks); assertEquals(2, scheduledTasks.size()); - assertEquals(Status.IN_PROGRESS, scheduledTasks.get(0).getStatus()); - assertEquals(Status.SCHEDULED, scheduledTasks.get(1).getStatus()); + assertEquals(TaskModel.Status.IN_PROGRESS, scheduledTasks.get(0).getStatus()); + assertEquals(TaskModel.Status.SCHEDULED, scheduledTasks.get(1).getStatus()); } @Test public void testGetTaskByRef() { - Workflow workflow = new Workflow(); - Task t1 = new Task(); + WorkflowModel workflow = new WorkflowModel(); + TaskModel t1 = new TaskModel(); t1.setReferenceTaskName("ref"); t1.setSeq(0); - t1.setStatus(Status.TIMED_OUT); + t1.setStatus(TaskModel.Status.TIMED_OUT); - Task t2 = new Task(); + TaskModel t2 = new TaskModel(); t2.setReferenceTaskName("ref"); t2.setSeq(1); - t2.setStatus(Status.FAILED); + t2.setStatus(TaskModel.Status.FAILED); - Task t3 = new Task(); + TaskModel t3 = new TaskModel(); t3.setReferenceTaskName("ref"); t3.setSeq(2); - t3.setStatus(Status.COMPLETED); + t3.setStatus(TaskModel.Status.COMPLETED); workflow.getTasks().add(t1); workflow.getTasks().add(t2); workflow.getTasks().add(t3); - Task task = workflow.getTaskByRefName("ref"); + TaskModel task = workflow.getTaskByRefName("ref"); assertNotNull(task); - assertEquals(Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertEquals(t3.getSeq(), task.getSeq()); } @@ -521,30 +492,30 @@ public void testTaskTimeout() { taskType.setTimeoutPolicy(TimeoutPolicy.RETRY); taskType.setTimeoutSeconds(1); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType(taskType.getName()); task.setStartTime(System.currentTimeMillis() - 2_000); // 2 seconds ago! - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); deciderService.checkTaskTimeout(taskType, task); // Task should be marked as timed out - assertEquals(Status.TIMED_OUT, task.getStatus()); + assertEquals(TaskModel.Status.TIMED_OUT, task.getStatus()); assertNotNull(task.getReasonForIncompletion()); assertEquals(++counterCount, counter.count()); taskType.setTimeoutPolicy(TimeoutPolicy.ALERT_ONLY); - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); task.setReasonForIncompletion(null); deciderService.checkTaskTimeout(taskType, task); // Nothing will happen - assertEquals(Status.IN_PROGRESS, task.getStatus()); + assertEquals(TaskModel.Status.IN_PROGRESS, task.getStatus()); assertNull(task.getReasonForIncompletion()); assertEquals(++counterCount, counter.count()); boolean exception = false; taskType.setTimeoutPolicy(TimeoutPolicy.TIME_OUT_WF); - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); task.setReasonForIncompletion(null); try { @@ -553,16 +524,16 @@ public void testTaskTimeout() { exception = true; } assertTrue(exception); - assertEquals(Status.TIMED_OUT, task.getStatus()); + assertEquals(TaskModel.Status.TIMED_OUT, task.getStatus()); assertNotNull(task.getReasonForIncompletion()); assertEquals(++counterCount, counter.count()); taskType.setTimeoutPolicy(TimeoutPolicy.TIME_OUT_WF); - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); task.setReasonForIncompletion(null); deciderService.checkTaskTimeout(null, task); // this will be a no-op - assertEquals(Status.IN_PROGRESS, task.getStatus()); + assertEquals(TaskModel.Status.IN_PROGRESS, task.getStatus()); assertNull(task.getReasonForIncompletion()); assertEquals(counterCount, counter.count()); } @@ -578,23 +549,23 @@ public void testCheckTaskPollTimeout() { taskType.setTimeoutPolicy(TimeoutPolicy.RETRY); taskType.setPollTimeoutSeconds(1); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType(taskType.getName()); task.setScheduledTime(System.currentTimeMillis() - 2_000); - task.setStatus(Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); deciderService.checkTaskPollTimeout(taskType, task); assertEquals(++counterCount, counter.count()); - assertEquals(Status.TIMED_OUT, task.getStatus()); + assertEquals(TaskModel.Status.TIMED_OUT, task.getStatus()); assertNotNull(task.getReasonForIncompletion()); task.setScheduledTime(System.currentTimeMillis()); task.setReasonForIncompletion(null); - task.setStatus(Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); deciderService.checkTaskPollTimeout(taskType, task); assertEquals(counterCount, counter.count()); - assertEquals(Status.SCHEDULED, task.getStatus()); + assertEquals(TaskModel.Status.SCHEDULED, task.getStatus()); assertNull(task.getReasonForIncompletion()); } @@ -635,7 +606,7 @@ public void testConcurrentTaskInputCalc() throws InterruptedException { workflowDef.setName("testConcurrentTaskInputCalc"); workflowDef.setVersion(1); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); workflow.setInput(workflowInput); @@ -678,7 +649,7 @@ public void testConcurrentTaskInputCalc() throws InterruptedException { @SuppressWarnings("unchecked") @Test public void testTaskRetry() { - Workflow workflow = createDefaultWorkflow(); + WorkflowModel workflow = createDefaultWorkflow(); workflow.getWorkflowDefinition().setSchemaVersion(2); @@ -697,9 +668,9 @@ public void testTaskRetry() { Map taskInput = parametersUtils.getTaskInput(inputParams, workflow, null, "t1"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(taskInput); - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setTaskId("t1"); TaskDef taskDef = new TaskDef(); @@ -707,7 +678,7 @@ public void testTaskRetry() { workflowTask.getInputParameters().put("task_id", "${CPEWF_TASK_ID}"); workflowTask.getInputParameters().put("env", env); - Optional task2 = deciderService.retry(taskDef, workflowTask, task, workflow); + Optional task2 = deciderService.retry(taskDef, workflowTask, task, workflow); assertEquals("t1", task.getInputData().get("task_id")); assertEquals( "t1", ((Map) task.getInputData().get("env")).get("env_task_id")); @@ -718,9 +689,9 @@ public void testTaskRetry() { task2.get().getTaskId(), ((Map) task2.get().getInputData().get("env")).get("env_task_id")); - Task task3 = new Task(); + TaskModel task3 = new TaskModel(); task3.getInputData().putAll(taskInput); - task3.setStatus(Status.FAILED_WITH_TERMINAL_ERROR); + task3.setStatus(TaskModel.Status.FAILED_WITH_TERMINAL_ERROR); task3.setTaskId("t1"); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(new WorkflowDef())); @@ -731,7 +702,7 @@ public void testTaskRetry() { @SuppressWarnings("unchecked") @Test public void testWorkflowTaskRetry() { - Workflow workflow = createDefaultWorkflow(); + WorkflowModel workflow = createDefaultWorkflow(); workflow.getWorkflowDefinition().setSchemaVersion(2); @@ -752,9 +723,9 @@ public void testWorkflowTaskRetry() { parametersUtils.getTaskInput(inputParams, workflow, null, "t1"); // Create a first failed task - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(taskInput); - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); task.setTaskId("t1"); TaskDef taskDef = new TaskDef(); @@ -766,7 +737,7 @@ public void testWorkflowTaskRetry() { workflowTask.setRetryCount(1); // Retry the failed task and assert that a new one has been created - Optional task2 = deciderService.retry(taskDef, workflowTask, task, workflow); + Optional task2 = deciderService.retry(taskDef, workflowTask, task, workflow); assertEquals("t1", task.getInputData().get("task_id")); assertEquals( "t1", ((Map) task.getInputData().get("env")).get("env_task_id")); @@ -778,21 +749,21 @@ public void testWorkflowTaskRetry() { ((Map) task2.get().getInputData().get("env")).get("env_task_id")); // Set the retried task to FAILED, retry it again and assert that the workflow failed - task2.get().setStatus(Status.FAILED); + task2.get().setStatus(TaskModel.Status.FAILED); exception.expect(TerminateWorkflowException.class); - final Optional task3 = + final Optional task3 = deciderService.retry(taskDef, workflowTask, task2.get(), workflow); assertFalse(task3.isPresent()); - assertEquals(WorkflowStatus.FAILED, workflow.getStatus()); + assertEquals(WorkflowModel.Status.FAILED, workflow.getStatus()); } @Test public void testLinearBackoff() { - Workflow workflow = createDefaultWorkflow(); + WorkflowModel workflow = createDefaultWorkflow(); - Task task = new Task(); - task.setStatus(Status.FAILED); + TaskModel task = new TaskModel(); + task.setStatus(TaskModel.Status.FAILED); task.setTaskId("t1"); TaskDef taskDef = new TaskDef(); @@ -801,28 +772,31 @@ public void testLinearBackoff() { taskDef.setBackoffScaleFactor(2); WorkflowTask workflowTask = new WorkflowTask(); - Optional task2 = deciderService.retry(taskDef, workflowTask, task, workflow); + Optional task2 = deciderService.retry(taskDef, workflowTask, task, workflow); assertEquals(120, task2.get().getCallbackAfterSeconds()); // 60*2*1 - Optional task3 = deciderService.retry(taskDef, workflowTask, task2.get(), workflow); + Optional task3 = + deciderService.retry(taskDef, workflowTask, task2.get(), workflow); assertEquals(240, task3.get().getCallbackAfterSeconds()); // 60*2*2 - Optional task4 = deciderService.retry(taskDef, workflowTask, task3.get(), workflow); + Optional task4 = + deciderService.retry(taskDef, workflowTask, task3.get(), workflow); // // 60*2*3 assertEquals(360, task4.get().getCallbackAfterSeconds()); // 60*2*3 taskDef.setRetryCount(Integer.MAX_VALUE); task4.get().setRetryCount(Integer.MAX_VALUE - 100); - Optional task5 = deciderService.retry(taskDef, workflowTask, task4.get(), workflow); + Optional task5 = + deciderService.retry(taskDef, workflowTask, task4.get(), workflow); assertEquals(Integer.MAX_VALUE, task5.get().getCallbackAfterSeconds()); } @Test public void testExponentialBackoff() { - Workflow workflow = createDefaultWorkflow(); + WorkflowModel workflow = createDefaultWorkflow(); - Task task = new Task(); - task.setStatus(Status.FAILED); + TaskModel task = new TaskModel(); + task.setStatus(TaskModel.Status.FAILED); task.setTaskId("t1"); TaskDef taskDef = new TaskDef(); @@ -830,25 +804,28 @@ public void testExponentialBackoff() { taskDef.setRetryLogic(TaskDef.RetryLogic.EXPONENTIAL_BACKOFF); WorkflowTask workflowTask = new WorkflowTask(); - Optional task2 = deciderService.retry(taskDef, workflowTask, task, workflow); + Optional task2 = deciderService.retry(taskDef, workflowTask, task, workflow); assertEquals(60, task2.get().getCallbackAfterSeconds()); - Optional task3 = deciderService.retry(taskDef, workflowTask, task2.get(), workflow); + Optional task3 = + deciderService.retry(taskDef, workflowTask, task2.get(), workflow); assertEquals(120, task3.get().getCallbackAfterSeconds()); - Optional task4 = deciderService.retry(taskDef, workflowTask, task3.get(), workflow); + Optional task4 = + deciderService.retry(taskDef, workflowTask, task3.get(), workflow); assertEquals(240, task4.get().getCallbackAfterSeconds()); taskDef.setRetryCount(Integer.MAX_VALUE); task4.get().setRetryCount(Integer.MAX_VALUE - 100); - Optional task5 = deciderService.retry(taskDef, workflowTask, task4.get(), workflow); + Optional task5 = + deciderService.retry(taskDef, workflowTask, task4.get(), workflow); assertEquals(Integer.MAX_VALUE, task5.get().getCallbackAfterSeconds()); } @Test public void testFork() throws IOException { InputStream stream = TestDeciderService.class.getResourceAsStream("/test.json"); - Workflow workflow = objectMapper.readValue(stream, Workflow.class); + WorkflowModel workflow = objectMapper.readValue(stream, WorkflowModel.class); DeciderOutcome outcome = deciderService.decide(workflow); assertFalse(outcome.isComplete); @@ -860,17 +837,17 @@ public void testFork() throws IOException { public void testDecideSuccessfulWorkflow() { WorkflowDef workflowDef = createLinearWorkflow(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setTaskType("junit_task_l1"); task1.setReferenceTaskName("s1"); task1.setSeq(1); task1.setRetried(false); task1.setExecuted(false); - task1.setStatus(Status.COMPLETED); + task1.setStatus(TaskModel.Status.COMPLETED); workflow.getTasks().add(task1); @@ -884,13 +861,13 @@ public void testDecideSuccessfulWorkflow() { assertEquals("s2", deciderOutcome.tasksToBeScheduled.get(0).getReferenceTaskName()); assertFalse(deciderOutcome.isComplete); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setTaskType("junit_task_l2"); task2.setReferenceTaskName("s2"); task2.setSeq(2); task2.setRetried(false); task2.setExecuted(false); - task2.setStatus(Status.COMPLETED); + task2.setStatus(TaskModel.Status.COMPLETED); workflow.getTasks().add(task2); deciderOutcome = deciderService.decide(workflow); @@ -907,18 +884,18 @@ public void testDecideSuccessfulWorkflow() { public void testDecideWithLoopTask() { WorkflowDef workflowDef = createLinearWorkflow(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setTaskType("junit_task_l1"); task1.setReferenceTaskName("s1"); task1.setSeq(1); task1.setIteration(1); task1.setRetried(false); task1.setExecuted(false); - task1.setStatus(Status.COMPLETED); + task1.setStatus(TaskModel.Status.COMPLETED); workflow.getTasks().add(task1); @@ -937,17 +914,17 @@ public void testDecideWithLoopTask() { public void testDecideFailedTask() { WorkflowDef workflowDef = createLinearWorkflow(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType("junit_task_l1"); task.setReferenceTaskName("s1"); task.setSeq(1); task.setRetried(false); task.setExecuted(false); - task.setStatus(Status.FAILED); + task.setStatus(TaskModel.Status.FAILED); WorkflowTask workflowTask = new WorkflowTask(); workflowTask.setTaskReferenceName("s1"); @@ -972,9 +949,9 @@ public void testDecideFailedTask() { public void testGetTasksToBeScheduled() { WorkflowDef workflowDef = createLinearWorkflow(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); WorkflowTask workflowTask1 = new WorkflowTask(); workflowTask1.setName("s1"); @@ -982,7 +959,7 @@ public void testGetTasksToBeScheduled() { workflowTask1.setType(SIMPLE.name()); workflowTask1.setTaskDefinition(new TaskDef("s1")); - List tasksToBeScheduled = + List tasksToBeScheduled = deciderService.getTasksToBeScheduled(workflow, workflowTask1, 0, null); assertNotNull(tasksToBeScheduled); assertEquals(1, tasksToBeScheduled.size()); @@ -1005,9 +982,9 @@ public void testIsResponseTimedOut() { taskDef.setName("test_rt"); taskDef.setResponseTimeoutSeconds(10); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskDefName("test_rt"); - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); task.setTaskId("aa"); task.setTaskType(TaskType.TASK_TYPE_SIMPLE); task.setUpdateTime(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(11)); @@ -1025,36 +1002,36 @@ public void testIsResponseTimedOut() { @Test public void testFilterNextLoopOverTasks() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setReferenceTaskName("task1"); - task1.setStatus(Status.COMPLETED); + task1.setStatus(TaskModel.Status.COMPLETED); task1.setTaskId("task1"); task1.setIteration(1); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setReferenceTaskName("task2"); - task2.setStatus(Status.SCHEDULED); + task2.setStatus(TaskModel.Status.SCHEDULED); task2.setTaskId("task2"); - Task task3 = new Task(); + TaskModel task3 = new TaskModel(); task3.setReferenceTaskName("task3__1"); - task3.setStatus(Status.IN_PROGRESS); + task3.setStatus(TaskModel.Status.IN_PROGRESS); task3.setTaskId("task3__1"); - Task task4 = new Task(); + TaskModel task4 = new TaskModel(); task4.setReferenceTaskName("task4"); - task4.setStatus(Status.SCHEDULED); + task4.setStatus(TaskModel.Status.SCHEDULED); task4.setTaskId("task4"); - Task task5 = new Task(); + TaskModel task5 = new TaskModel(); task5.setReferenceTaskName("task5"); - task5.setStatus(Status.COMPLETED); + task5.setStatus(TaskModel.Status.COMPLETED); task5.setTaskId("task5"); workflow.getTasks().addAll(Arrays.asList(task1, task2, task3, task4, task5)); - List tasks = + List tasks = deciderService.filterNextLoopOverTasks( Arrays.asList(task2, task3, task4), task1, workflow); assertEquals(2, tasks.size()); @@ -1067,58 +1044,14 @@ public void testFilterNextLoopOverTasks() { }); } - @Test - public void testPopulateWorkflowAndTaskData() { - String workflowInputPath = "workflow/input/test.json"; - String taskInputPath = "task/input/test.json"; - String taskOutputPath = "task/output/test.json"; - Map workflowParams = new HashMap<>(); - workflowParams.put("key1", "value1"); - workflowParams.put("key2", 100); - when(externalPayloadStorageUtils.downloadPayload(workflowInputPath)) - .thenReturn(workflowParams); - Map taskInputParams = new HashMap<>(); - taskInputParams.put("key", "taskInput"); - when(externalPayloadStorageUtils.downloadPayload(taskInputPath)) - .thenReturn(taskInputParams); - Map taskOutputParams = new HashMap<>(); - taskOutputParams.put("key", "taskOutput"); - when(externalPayloadStorageUtils.downloadPayload(taskOutputPath)) - .thenReturn(taskOutputParams); - Task task = new Task(); - task.setExternalInputPayloadStoragePath(taskInputPath); - task.setExternalOutputPayloadStoragePath(taskOutputPath); - Workflow workflow = new Workflow(); - WorkflowDef def = new WorkflowDef(); - def.setName("name"); - def.setVersion(1); - workflow.setWorkflowDefinition(def); - workflow.setExternalInputPayloadStoragePath(workflowInputPath); - workflow.getTasks().add(task); - Workflow workflowInstance = deciderService.populateWorkflowAndTaskData(workflow); - assertNotNull(workflowInstance); - assertTrue(workflow.getInput().isEmpty()); - assertNotNull(workflowInstance.getInput()); - assertEquals(workflowParams, workflowInstance.getInput()); - assertTrue(workflow.getTasks().get(0).getInputData().isEmpty()); - assertNotNull(workflowInstance.getTasks().get(0).getInputData()); - assertEquals(taskInputParams, workflowInstance.getTasks().get(0).getInputData()); - assertTrue(workflow.getTasks().get(0).getOutputData().isEmpty()); - assertNotNull(workflowInstance.getTasks().get(0).getOutputData()); - assertEquals(taskOutputParams, workflowInstance.getTasks().get(0).getOutputData()); - assertNull(workflowInstance.getExternalInputPayloadStoragePath()); - assertNull(workflowInstance.getTasks().get(0).getExternalInputPayloadStoragePath()); - assertNull(workflowInstance.getTasks().get(0).getExternalOutputPayloadStoragePath()); - } - @Test public void testUpdateWorkflowOutput() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(new WorkflowDef()); deciderService.updateWorkflowOutput(workflow, null); assertNotNull(workflow.getOutput()); assertTrue(workflow.getOutput().isEmpty()); - Task task = new Task(); + TaskModel task = new TaskModel(); Map taskOutput = new HashMap<>(); taskOutput.put("taskKey", "taskValue"); task.setOutputData(taskOutput); @@ -1135,7 +1068,7 @@ public void testUpdateWorkflowOutput() { @SuppressWarnings({"unchecked", "rawtypes"}) @Test public void testUpdateWorkflowOutput_WhenDefinitionHasOutputParameters() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setOutputParameters( new HashMap() { @@ -1144,7 +1077,7 @@ public void testUpdateWorkflowOutput_WhenDefinitionHasOutputParameters() { } }); workflow.setWorkflowDefinition(workflowDef); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setReferenceTaskName("test_task"); task.setOutputData( new HashMap() { @@ -1160,10 +1093,10 @@ public void testUpdateWorkflowOutput_WhenDefinitionHasOutputParameters() { @Test public void testUpdateWorkflowOutput_WhenWorkflowHasTerminateTask() { - Workflow workflow = new Workflow(); - Task task = new Task(); + WorkflowModel workflow = new WorkflowModel(); + TaskModel task = new TaskModel(); task.setTaskType(TASK_TYPE_TERMINATE); - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); task.setOutputData( new HashMap() { { @@ -1213,9 +1146,9 @@ public void testCheckWorkflowTimeout() { WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("test"); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setOwnerApp("junit"); - workflow.setStartTime(System.currentTimeMillis() - 10_000); + workflow.setCreateTime(System.currentTimeMillis() - 10_000); workflow.setWorkflowId("workflow_id"); // no-op @@ -1262,22 +1195,22 @@ public void testCheckForWorkflowCompletion() { conditionalWorkflowDef.getTasks().add(terminateWT); // when workflow has no tasks - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(conditionalWorkflowDef); // then workflow completion check returns false assertFalse(deciderService.checkForWorkflowCompletion(workflow)); // when only part of the tasks are completed - Task decTask = new Task(); + TaskModel decTask = new TaskModel(); decTask.setTaskType(DECISION.name()); decTask.setReferenceTaskName("conditional2"); - decTask.setStatus(Status.COMPLETED); + decTask.setStatus(TaskModel.Status.COMPLETED); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); decTask.setTaskType(SIMPLE.name()); task1.setReferenceTaskName("t1"); - task1.setStatus(Status.COMPLETED); + task1.setStatus(TaskModel.Status.COMPLETED); workflow.getTasks().addAll(Arrays.asList(decTask, task1)); @@ -1285,15 +1218,15 @@ public void testCheckForWorkflowCompletion() { assertFalse(deciderService.checkForWorkflowCompletion(workflow)); // when the terminate task is COMPLETED - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); decTask.setTaskType(SIMPLE.name()); task2.setReferenceTaskName("t2"); - task2.setStatus(Status.SCHEDULED); + task2.setStatus(TaskModel.Status.SCHEDULED); - Task terminateTask = new Task(); + TaskModel terminateTask = new TaskModel(); decTask.setTaskType(TaskType.TERMINATE.name()); terminateTask.setReferenceTaskName("terminate"); - terminateTask.setStatus(Status.COMPLETED); + terminateTask.setStatus(TaskModel.Status.COMPLETED); workflow.getTasks().addAll(Arrays.asList(task2, terminateTask)); @@ -1403,13 +1336,13 @@ private WorkflowDef createLinearWorkflow() { return workflowDef; } - private Workflow createDefaultWorkflow() { + private WorkflowModel createDefaultWorkflow() { WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("TestDeciderService"); workflowDef.setVersion(1); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); workflow.getInput().put("requestId", "request id 001"); @@ -1430,15 +1363,15 @@ private Workflow createDefaultWorkflow() { workflow.getOutput().put("names", names); workflow.getOutput().put("awards", 200); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setReferenceTaskName("task2"); task.getOutputData().put("location", "http://location"); - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setReferenceTaskName("task3"); task2.getOutputData().put("refId", "abcddef_1234_7890_aaffcc"); - task2.setStatus(Status.SCHEDULED); + task2.setStatus(TaskModel.Status.SCHEDULED); workflow.getTasks().add(task); workflow.getTasks().add(task2); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/TestWorkflowExecutor.java b/core/src/test/java/com/netflix/conductor/core/execution/TestWorkflowExecutor.java index cb2f375457..7d202e0d37 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/TestWorkflowExecutor.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/TestWorkflowExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -13,17 +13,7 @@ package com.netflix.conductor.core.execution; import java.time.Duration; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @@ -43,99 +33,42 @@ import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.common.metadata.tasks.PollData; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.RerunWorkflowRequest; 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.common.run.Workflow.WorkflowStatus; import com.netflix.conductor.common.utils.ExternalPayloadStorage; import com.netflix.conductor.core.config.ConductorProperties; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.execution.evaluators.Evaluator; -import com.netflix.conductor.core.execution.mapper.DecisionTaskMapper; -import com.netflix.conductor.core.execution.mapper.DynamicTaskMapper; -import com.netflix.conductor.core.execution.mapper.EventTaskMapper; -import com.netflix.conductor.core.execution.mapper.ForkJoinDynamicTaskMapper; -import com.netflix.conductor.core.execution.mapper.ForkJoinTaskMapper; -import com.netflix.conductor.core.execution.mapper.HTTPTaskMapper; -import com.netflix.conductor.core.execution.mapper.InlineTaskMapper; -import com.netflix.conductor.core.execution.mapper.JoinTaskMapper; -import com.netflix.conductor.core.execution.mapper.LambdaTaskMapper; -import com.netflix.conductor.core.execution.mapper.SimpleTaskMapper; -import com.netflix.conductor.core.execution.mapper.SubWorkflowTaskMapper; -import com.netflix.conductor.core.execution.mapper.SwitchTaskMapper; -import com.netflix.conductor.core.execution.mapper.TaskMapper; -import com.netflix.conductor.core.execution.mapper.UserDefinedTaskMapper; -import com.netflix.conductor.core.execution.mapper.WaitTaskMapper; -import com.netflix.conductor.core.execution.tasks.Lambda; -import com.netflix.conductor.core.execution.tasks.SubWorkflow; -import com.netflix.conductor.core.execution.tasks.SystemTaskRegistry; -import com.netflix.conductor.core.execution.tasks.Wait; -import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; +import com.netflix.conductor.core.execution.mapper.*; +import com.netflix.conductor.core.execution.tasks.*; import com.netflix.conductor.core.listener.WorkflowStatusListener; import com.netflix.conductor.core.metadata.MetadataMapperService; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; import com.netflix.conductor.core.utils.ExternalPayloadStorageUtils; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; import com.netflix.conductor.dao.QueueDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.service.ExecutionLockService; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.Uninterruptibles; -import static com.netflix.conductor.common.metadata.tasks.TaskType.DECISION; -import static com.netflix.conductor.common.metadata.tasks.TaskType.DYNAMIC; -import static com.netflix.conductor.common.metadata.tasks.TaskType.EVENT; -import static com.netflix.conductor.common.metadata.tasks.TaskType.FORK_JOIN; -import static com.netflix.conductor.common.metadata.tasks.TaskType.FORK_JOIN_DYNAMIC; -import static com.netflix.conductor.common.metadata.tasks.TaskType.HTTP; -import static com.netflix.conductor.common.metadata.tasks.TaskType.INLINE; -import static com.netflix.conductor.common.metadata.tasks.TaskType.JOIN; -import static com.netflix.conductor.common.metadata.tasks.TaskType.LAMBDA; -import static com.netflix.conductor.common.metadata.tasks.TaskType.SIMPLE; -import static com.netflix.conductor.common.metadata.tasks.TaskType.SUB_WORKFLOW; -import static com.netflix.conductor.common.metadata.tasks.TaskType.SWITCH; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_JSON_JQ_TRANSFORM; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_LAMBDA; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_SUB_WORKFLOW; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_WAIT; -import static com.netflix.conductor.common.metadata.tasks.TaskType.USER_DEFINED; -import static com.netflix.conductor.common.metadata.tasks.TaskType.WAIT; -import static com.netflix.conductor.common.run.Workflow.WorkflowStatus.COMPLETED; -import static com.netflix.conductor.common.run.Workflow.WorkflowStatus.PAUSED; -import static com.netflix.conductor.common.run.Workflow.WorkflowStatus.RUNNING; +import static com.netflix.conductor.common.metadata.tasks.TaskType.*; import static com.netflix.conductor.core.exception.ApplicationException.Code.CONFLICT; import static java.util.Comparator.comparingInt; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.maxBy; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; @ContextConfiguration( classes = { @@ -196,8 +129,9 @@ public boolean isAsync() { } @Override - public void start(Workflow workflow, Task task, WorkflowExecutor executor) { - task.setStatus(Task.Status.COMPLETED); + public void start( + WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { + task.setStatus(TaskModel.Status.COMPLETED); } }; } @@ -278,13 +212,13 @@ public void testScheduleTask() { WorkflowSystemTaskStub http2Task = beanFactory.getBean("HTTP2", WorkflowSystemTaskStub.class); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("1"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("1"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); - List tasks = new LinkedList<>(); + List tasks = new LinkedList<>(); WorkflowTask taskToSchedule = new WorkflowTask(); taskToSchedule.setWorkflowTaskType(TaskType.USER_DEFINED); @@ -299,7 +233,7 @@ public void testScheduleTask() { wait.setType("WAIT"); wait.setTaskReferenceName("wait"); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setTaskType(taskToSchedule.getType()); task1.setTaskDefName(taskToSchedule.getName()); task1.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -308,12 +242,12 @@ public void testScheduleTask() { task1.setScheduledTime(System.currentTimeMillis()); task1.setTaskId(IDGenerator.generate()); task1.setInputData(new HashMap<>()); - task1.setStatus(Status.SCHEDULED); + task1.setStatus(TaskModel.Status.SCHEDULED); task1.setRetryCount(0); task1.setCallbackAfterSeconds(taskToSchedule.getStartDelay()); task1.setWorkflowTask(taskToSchedule); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setTaskType(TASK_TYPE_WAIT); task2.setTaskDefName(taskToSchedule.getName()); task2.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -322,10 +256,10 @@ public void testScheduleTask() { task2.setScheduledTime(System.currentTimeMillis()); task2.setInputData(new HashMap<>()); task2.setTaskId(IDGenerator.generate()); - task2.setStatus(Status.IN_PROGRESS); + task2.setStatus(TaskModel.Status.IN_PROGRESS); task2.setWorkflowTask(taskToSchedule); - Task task3 = new Task(); + TaskModel task3 = new TaskModel(); task3.setTaskType(taskToSchedule2.getType()); task3.setTaskDefName(taskToSchedule.getName()); task3.setReferenceTaskName(taskToSchedule.getTaskReferenceName()); @@ -334,7 +268,7 @@ public void testScheduleTask() { task3.setScheduledTime(System.currentTimeMillis()); task3.setTaskId(IDGenerator.generate()); task3.setInputData(new HashMap<>()); - task3.setStatus(Status.SCHEDULED); + task3.setStatus(TaskModel.Status.SCHEDULED); task3.setRetryCount(0); task3.setCallbackAfterSeconds(taskToSchedule.getStartDelay()); task3.setWorkflowTask(taskToSchedule); @@ -373,18 +307,18 @@ public void testScheduleTask() { @Test(expected = TerminateWorkflowException.class) public void testScheduleTaskFailure() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("wid_01"); - List tasks = new LinkedList<>(); + List tasks = new LinkedList<>(); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setTaskType(TaskType.TASK_TYPE_SIMPLE); task1.setTaskDefName("task_1"); task1.setReferenceTaskName("task_1"); task1.setWorkflowInstanceId(workflow.getWorkflowId()); task1.setTaskId("tid_01"); - task1.setStatus(Status.SCHEDULED); + task1.setStatus(TaskModel.Status.SCHEDULED); task1.setRetryCount(0); tasks.add(task1); @@ -396,21 +330,21 @@ public void testScheduleTaskFailure() { /** Simulate Queue push failures and assert that scheduleTask doesn't throw an exception. */ @Test public void testQueueFailuresDuringScheduleTask() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("wid_01"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("wid"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); - List tasks = new LinkedList<>(); + List tasks = new LinkedList<>(); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setTaskType(TaskType.TASK_TYPE_SIMPLE); task1.setTaskDefName("task_1"); task1.setReferenceTaskName("task_1"); task1.setWorkflowInstanceId(workflow.getWorkflowId()); task1.setTaskId("tid_01"); - task1.setStatus(Status.SCHEDULED); + task1.setStatus(TaskModel.Status.SCHEDULED); task1.setRetryCount(0); tasks.add(task1); @@ -428,16 +362,16 @@ public void testCompleteWorkflow() { WorkflowDef def = new WorkflowDef(); def.setName("test"); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); workflow.setWorkflowId("1"); - workflow.setStatus(Workflow.WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflow.setOwnerApp("junit_test"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); workflow.setOutput(Collections.EMPTY_MAP); - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); AtomicInteger updateWorkflowCalledCounter = new AtomicInteger(0); doAnswer( @@ -467,18 +401,22 @@ public void testCompleteWorkflow() { .remove(anyString(), anyString()); workflowExecutor.completeWorkflow(workflow); - assertEquals(Workflow.WorkflowStatus.COMPLETED, workflow.getStatus()); + assertEquals(WorkflowModel.Status.COMPLETED, workflow.getStatus()); assertEquals(1, updateWorkflowCalledCounter.get()); assertEquals(0, updateTasksCalledCounter.get()); assertEquals(0, removeQueueEntryCalledCounter.get()); - verify(workflowStatusListener, times(1)).onWorkflowCompletedIfEnabled(any(Workflow.class)); - verify(workflowStatusListener, times(0)).onWorkflowFinalizedIfEnabled(any(Workflow.class)); + verify(workflowStatusListener, times(1)) + .onWorkflowCompletedIfEnabled(any(WorkflowModel.class)); + verify(workflowStatusListener, times(0)) + .onWorkflowFinalizedIfEnabled(any(WorkflowModel.class)); def.setWorkflowStatusListenerEnabled(true); - workflow.setStatus(Workflow.WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflowExecutor.completeWorkflow(workflow); - verify(workflowStatusListener, times(2)).onWorkflowCompletedIfEnabled(any(Workflow.class)); - verify(workflowStatusListener, times(0)).onWorkflowFinalizedIfEnabled(any(Workflow.class)); + verify(workflowStatusListener, times(2)) + .onWorkflowCompletedIfEnabled(any(WorkflowModel.class)); + verify(workflowStatusListener, times(0)) + .onWorkflowFinalizedIfEnabled(any(WorkflowModel.class)); } @Test @@ -487,16 +425,16 @@ public void testTerminateWorkflow() { WorkflowDef def = new WorkflowDef(); def.setName("test"); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); workflow.setWorkflowId("1"); - workflow.setStatus(Workflow.WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflow.setOwnerApp("junit_test"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); workflow.setOutput(Collections.EMPTY_MAP); - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); AtomicInteger updateWorkflowCalledCounter = new AtomicInteger(0); doAnswer( @@ -526,18 +464,22 @@ public void testTerminateWorkflow() { .remove(anyString(), anyString()); workflowExecutor.terminateWorkflow("workflowId", "reason"); - assertEquals(Workflow.WorkflowStatus.TERMINATED, workflow.getStatus()); + assertEquals(WorkflowModel.Status.TERMINATED, workflow.getStatus()); assertEquals(1, updateWorkflowCalledCounter.get()); assertEquals(1, removeQueueEntryCalledCounter.get()); - verify(workflowStatusListener, times(1)).onWorkflowTerminatedIfEnabled(any(Workflow.class)); - verify(workflowStatusListener, times(1)).onWorkflowFinalizedIfEnabled(any(Workflow.class)); + verify(workflowStatusListener, times(1)) + .onWorkflowTerminatedIfEnabled(any(WorkflowModel.class)); + verify(workflowStatusListener, times(1)) + .onWorkflowFinalizedIfEnabled(any(WorkflowModel.class)); def.setWorkflowStatusListenerEnabled(true); - workflow.setStatus(Workflow.WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflowExecutor.completeWorkflow(workflow); - verify(workflowStatusListener, times(1)).onWorkflowCompletedIfEnabled(any(Workflow.class)); - verify(workflowStatusListener, times(1)).onWorkflowFinalizedIfEnabled(any(Workflow.class)); + verify(workflowStatusListener, times(1)) + .onWorkflowCompletedIfEnabled(any(WorkflowModel.class)); + verify(workflowStatusListener, times(1)) + .onWorkflowFinalizedIfEnabled(any(WorkflowModel.class)); } @Test @@ -546,30 +488,30 @@ public void testUploadOutputFailuresDuringTerminateWorkflow() { def.setName("test"); def.setWorkflowStatusListenerEnabled(true); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); workflow.setWorkflowId("1"); - workflow.setStatus(Workflow.WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflow.setOwnerApp("junit_test"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); workflow.setOutput(Collections.EMPTY_MAP); - List tasks = new LinkedList<>(); + List tasks = new LinkedList<>(); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(1); task.setTaskId(UUID.randomUUID().toString()); task.setReferenceTaskName("t1"); task.setWorkflowInstanceId(workflow.getWorkflowId()); task.setTaskDefName("task1"); - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); tasks.add(task); workflow.setTasks(tasks); - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); AtomicInteger updateWorkflowCalledCounter = new AtomicInteger(0); doAnswer( @@ -585,9 +527,10 @@ public void testUploadOutputFailuresDuringTerminateWorkflow() { .verifyAndUpload(workflow, ExternalPayloadStorage.PayloadType.WORKFLOW_OUTPUT); workflowExecutor.terminateWorkflow(workflow.getWorkflowId(), "reason"); - assertEquals(Workflow.WorkflowStatus.TERMINATED, workflow.getStatus()); + assertEquals(WorkflowModel.Status.TERMINATED, workflow.getStatus()); assertEquals(1, updateWorkflowCalledCounter.get()); - verify(workflowStatusListener, times(1)).onWorkflowTerminatedIfEnabled(any(Workflow.class)); + verify(workflowStatusListener, times(1)) + .onWorkflowTerminatedIfEnabled(any(WorkflowModel.class)); } @Test @@ -597,16 +540,16 @@ public void testQueueExceptionsIgnoredDuringTerminateWorkflow() { def.setName("test"); def.setWorkflowStatusListenerEnabled(true); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); workflow.setWorkflowId("1"); - workflow.setStatus(Workflow.WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); workflow.setOwnerApp("junit_test"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); workflow.setOutput(Collections.EMPTY_MAP); - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); AtomicInteger updateWorkflowCalledCounter = new AtomicInteger(0); doAnswer( @@ -629,9 +572,10 @@ public void testQueueExceptionsIgnoredDuringTerminateWorkflow() { doThrow(new RuntimeException()).when(queueDAO).remove(anyString(), anyString()); workflowExecutor.terminateWorkflow("workflowId", "reason"); - assertEquals(Workflow.WorkflowStatus.TERMINATED, workflow.getStatus()); + assertEquals(WorkflowModel.Status.TERMINATED, workflow.getStatus()); assertEquals(1, updateWorkflowCalledCounter.get()); - verify(workflowStatusListener, times(1)).onWorkflowTerminatedIfEnabled(any(Workflow.class)); + verify(workflowStatusListener, times(1)) + .onWorkflowTerminatedIfEnabled(any(WorkflowModel.class)); } @Test @@ -646,29 +590,29 @@ public void testRestartWorkflow() { workflowDef.setRestartable(true); workflowDef.getTasks().addAll(Collections.singletonList(workflowTask)); - Task task_1 = new Task(); + TaskModel task_1 = new TaskModel(); task_1.setTaskId(UUID.randomUUID().toString()); task_1.setSeq(1); - task_1.setStatus(Status.FAILED); + task_1.setStatus(TaskModel.Status.FAILED); task_1.setTaskDefName(workflowTask.getName()); task_1.setReferenceTaskName(workflowTask.getTaskReferenceName()); - Task task_2 = new Task(); + TaskModel task_2 = new TaskModel(); task_2.setTaskId(UUID.randomUUID().toString()); task_2.setSeq(2); - task_2.setStatus(Status.FAILED); + task_2.setStatus(TaskModel.Status.FAILED); task_2.setTaskDefName(workflowTask.getName()); task_2.setReferenceTaskName(workflowTask.getTaskReferenceName()); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); workflow.setWorkflowId("test-workflow-id"); workflow.getTasks().addAll(Arrays.asList(task_1, task_2)); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); workflow.setEndTime(500); workflow.setLastRetriedTime(100); - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); doNothing().when(executionDAOFacade).removeTask(any()); when(metadataDAO.getWorkflowDef(workflow.getWorkflowName(), workflow.getWorkflowVersion())) .thenReturn(Optional.of(workflowDef)); @@ -676,12 +620,12 @@ public void testRestartWorkflow() { when(executionDAOFacade.updateWorkflow(any())).thenReturn(""); workflowExecutor.restart(workflow.getWorkflowId(), false); - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); assertEquals(0, workflow.getEndTime()); assertEquals(0, workflow.getLastRetriedTime()); verify(metadataDAO, never()).getLatestWorkflowDef(any()); - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Workflow.class); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(WorkflowModel.class); verify(executionDAOFacade, times(1)).createWorkflow(argumentCaptor.capture()); assertEquals( workflow.getWorkflowId(), argumentCaptor.getAllValues().get(0).getWorkflowId()); @@ -690,7 +634,7 @@ public void testRestartWorkflow() { argumentCaptor.getAllValues().get(0).getWorkflowDefinition()); // add a new version of the workflow definition and restart with latest - workflow.setStatus(Workflow.WorkflowStatus.COMPLETED); + workflow.setStatus(WorkflowModel.Status.COMPLETED); workflow.setEndTime(500); workflow.setLastRetriedTime(100); workflowDef = new WorkflowDef(); @@ -702,12 +646,12 @@ public void testRestartWorkflow() { when(metadataDAO.getLatestWorkflowDef(workflow.getWorkflowName())) .thenReturn(Optional.of(workflowDef)); workflowExecutor.restart(workflow.getWorkflowId(), true); - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); assertEquals(0, workflow.getEndTime()); assertEquals(0, workflow.getLastRetriedTime()); verify(metadataDAO, times(1)).getLatestWorkflowDef(anyString()); - argumentCaptor = ArgumentCaptor.forClass(Workflow.class); + argumentCaptor = ArgumentCaptor.forClass(WorkflowModel.class); verify(executionDAOFacade, times(2)).createWorkflow(argumentCaptor.capture()); assertEquals( workflow.getWorkflowId(), argumentCaptor.getAllValues().get(1).getWorkflowId()); @@ -716,21 +660,21 @@ public void testRestartWorkflow() { @Test(expected = ApplicationException.class) public void testRetryNonTerminalWorkflow() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRetryNonTerminalWorkflow"); - workflow.setStatus(Workflow.WorkflowStatus.RUNNING); - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + workflow.setStatus(WorkflowModel.Status.RUNNING); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); workflowExecutor.retry(workflow.getWorkflowId(), false); } @Test(expected = ApplicationException.class) public void testRetryWorkflowNoTasks() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("ApplicationException"); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); workflow.setTasks(Collections.emptyList()); - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); workflowExecutor.retry(workflow.getWorkflowId(), false); } @@ -738,35 +682,35 @@ public void testRetryWorkflowNoTasks() { @Test(expected = ApplicationException.class) public void testRetryWorkflowNoFailedTasks() { // setup - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRetryWorkflowId"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("testRetryWorkflowId"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRetryWorkflowId"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); //noinspection unchecked workflow.setOutput(Collections.EMPTY_MAP); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); // add 2 failed task in 2 forks and 1 cancelled in the 3rd fork - Task task_1_1 = new Task(); + TaskModel task_1_1 = new TaskModel(); task_1_1.setTaskId(UUID.randomUUID().toString()); task_1_1.setSeq(1); task_1_1.setRetryCount(0); task_1_1.setTaskType(TaskType.SIMPLE.toString()); - task_1_1.setStatus(Status.FAILED); + task_1_1.setStatus(TaskModel.Status.FAILED); task_1_1.setTaskDefName("task1"); task_1_1.setReferenceTaskName("task1_ref1"); - Task task_1_2 = new Task(); + TaskModel task_1_2 = new TaskModel(); task_1_2.setTaskId(UUID.randomUUID().toString()); task_1_2.setSeq(2); task_1_2.setRetryCount(1); task_1_2.setTaskType(TaskType.SIMPLE.toString()); - task_1_2.setStatus(Status.COMPLETED); + task_1_2.setStatus(TaskModel.Status.COMPLETED); task_1_2.setTaskDefName("task1"); task_1_2.setReferenceTaskName("task1_ref1"); @@ -774,7 +718,7 @@ public void testRetryWorkflowNoFailedTasks() { // end of setup // when: - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(new WorkflowDef())); @@ -784,18 +728,18 @@ public void testRetryWorkflowNoFailedTasks() { @Test public void testRetryWorkflow() { // setup - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRetryWorkflowId"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("testRetryWorkflowId"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRetryWorkflowId"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); //noinspection unchecked workflow.setOutput(Collections.EMPTY_MAP); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); AtomicInteger updateWorkflowCalledCounter = new AtomicInteger(0); doAnswer( @@ -825,52 +769,52 @@ public void testRetryWorkflow() { .updateTask(any()); // add 2 failed task in 2 forks and 1 cancelled in the 3rd fork - Task task_1_1 = new Task(); + TaskModel task_1_1 = new TaskModel(); task_1_1.setTaskId(UUID.randomUUID().toString()); task_1_1.setSeq(20); task_1_1.setRetryCount(1); task_1_1.setTaskType(TaskType.SIMPLE.toString()); - task_1_1.setStatus(Status.CANCELED); + task_1_1.setStatus(TaskModel.Status.CANCELED); task_1_1.setRetried(true); task_1_1.setTaskDefName("task1"); task_1_1.setWorkflowTask(new WorkflowTask()); task_1_1.setReferenceTaskName("task1_ref1"); - Task task_1_2 = new Task(); + TaskModel task_1_2 = new TaskModel(); task_1_2.setTaskId(UUID.randomUUID().toString()); task_1_2.setSeq(21); task_1_2.setRetryCount(1); task_1_2.setTaskType(TaskType.SIMPLE.toString()); - task_1_2.setStatus(Status.FAILED); + task_1_2.setStatus(TaskModel.Status.FAILED); task_1_2.setTaskDefName("task1"); task_1_2.setWorkflowTask(new WorkflowTask()); task_1_2.setReferenceTaskName("task1_ref1"); - Task task_2_1 = new Task(); + TaskModel task_2_1 = new TaskModel(); task_2_1.setTaskId(UUID.randomUUID().toString()); task_2_1.setSeq(22); task_2_1.setRetryCount(1); - task_2_1.setStatus(Status.FAILED); + task_2_1.setStatus(TaskModel.Status.FAILED); task_2_1.setTaskType(TaskType.SIMPLE.toString()); task_2_1.setTaskDefName("task2"); task_2_1.setWorkflowTask(new WorkflowTask()); task_2_1.setReferenceTaskName("task2_ref1"); - Task task_3_1 = new Task(); + TaskModel task_3_1 = new TaskModel(); task_3_1.setTaskId(UUID.randomUUID().toString()); task_3_1.setSeq(23); task_3_1.setRetryCount(1); - task_3_1.setStatus(Status.CANCELED); + task_3_1.setStatus(TaskModel.Status.CANCELED); task_3_1.setTaskType(TaskType.SIMPLE.toString()); task_3_1.setTaskDefName("task3"); task_3_1.setWorkflowTask(new WorkflowTask()); task_3_1.setReferenceTaskName("task3_ref1"); - Task task_4_1 = new Task(); + TaskModel task_4_1 = new TaskModel(); task_4_1.setTaskId(UUID.randomUUID().toString()); task_4_1.setSeq(122); task_4_1.setRetryCount(1); - task_4_1.setStatus(Status.FAILED); + task_4_1.setStatus(TaskModel.Status.FAILED); task_4_1.setTaskType(TaskType.SIMPLE.toString()); task_4_1.setTaskDefName("task1"); task_4_1.setWorkflowTask(new WorkflowTask()); @@ -880,14 +824,14 @@ public void testRetryWorkflow() { // end of setup // when: - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(new WorkflowDef())); workflowExecutor.retry(workflow.getWorkflowId(), false); // then: - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); assertEquals(1, updateWorkflowCalledCounter.get()); assertEquals(1, updateTasksCalledCounter.get()); assertEquals(0, updateTaskCalledCounter.get()); @@ -896,64 +840,64 @@ public void testRetryWorkflow() { @Test public void testRetryWorkflowReturnsNoDuplicates() { // setup - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRetryWorkflowId"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("testRetryWorkflowId"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRetryWorkflowId"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); //noinspection unchecked workflow.setOutput(Collections.EMPTY_MAP); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); - Task task_1_1 = new Task(); + TaskModel task_1_1 = new TaskModel(); task_1_1.setTaskId(UUID.randomUUID().toString()); task_1_1.setSeq(10); task_1_1.setRetryCount(0); task_1_1.setTaskType(TaskType.SIMPLE.toString()); - task_1_1.setStatus(Status.FAILED); + task_1_1.setStatus(TaskModel.Status.FAILED); task_1_1.setTaskDefName("task1"); task_1_1.setWorkflowTask(new WorkflowTask()); task_1_1.setReferenceTaskName("task1_ref1"); - Task task_1_2 = new Task(); + TaskModel task_1_2 = new TaskModel(); task_1_2.setTaskId(UUID.randomUUID().toString()); task_1_2.setSeq(11); task_1_2.setRetryCount(1); task_1_2.setTaskType(TaskType.SIMPLE.toString()); - task_1_2.setStatus(Status.COMPLETED); + task_1_2.setStatus(TaskModel.Status.COMPLETED); task_1_2.setTaskDefName("task1"); task_1_2.setWorkflowTask(new WorkflowTask()); task_1_2.setReferenceTaskName("task1_ref1"); - Task task_2_1 = new Task(); + TaskModel task_2_1 = new TaskModel(); task_2_1.setTaskId(UUID.randomUUID().toString()); task_2_1.setSeq(21); task_2_1.setRetryCount(0); - task_2_1.setStatus(Status.CANCELED); + task_2_1.setStatus(TaskModel.Status.CANCELED); task_2_1.setTaskType(TaskType.SIMPLE.toString()); task_2_1.setTaskDefName("task2"); task_2_1.setWorkflowTask(new WorkflowTask()); task_2_1.setReferenceTaskName("task2_ref1"); - Task task_3_1 = new Task(); + TaskModel task_3_1 = new TaskModel(); task_3_1.setTaskId(UUID.randomUUID().toString()); task_3_1.setSeq(31); task_3_1.setRetryCount(1); - task_3_1.setStatus(Status.FAILED_WITH_TERMINAL_ERROR); + task_3_1.setStatus(TaskModel.Status.FAILED_WITH_TERMINAL_ERROR); task_3_1.setTaskType(TaskType.SIMPLE.toString()); task_3_1.setTaskDefName("task1"); task_3_1.setWorkflowTask(new WorkflowTask()); task_3_1.setReferenceTaskName("task3_ref1"); - Task task_4_1 = new Task(); + TaskModel task_4_1 = new TaskModel(); task_4_1.setTaskId(UUID.randomUUID().toString()); task_4_1.setSeq(41); task_4_1.setRetryCount(0); - task_4_1.setStatus(Status.TIMED_OUT); + task_4_1.setStatus(TaskModel.Status.TIMED_OUT); task_4_1.setTaskType(TaskType.SIMPLE.toString()); task_4_1.setTaskDefName("task1"); task_4_1.setWorkflowTask(new WorkflowTask()); @@ -963,7 +907,7 @@ public void testRetryWorkflowReturnsNoDuplicates() { // end of setup // when: - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(new WorkflowDef())); @@ -975,35 +919,35 @@ public void testRetryWorkflowReturnsNoDuplicates() { @Test public void testRetryWorkflowMultipleRetries() { // setup - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRetryWorkflowId"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("testRetryWorkflowId"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRetryWorkflowId"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); //noinspection unchecked workflow.setOutput(Collections.EMPTY_MAP); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); - Task task_1_1 = new Task(); + TaskModel task_1_1 = new TaskModel(); task_1_1.setTaskId(UUID.randomUUID().toString()); task_1_1.setSeq(10); task_1_1.setRetryCount(0); task_1_1.setTaskType(TaskType.SIMPLE.toString()); - task_1_1.setStatus(Status.FAILED); + task_1_1.setStatus(TaskModel.Status.FAILED); task_1_1.setTaskDefName("task1"); task_1_1.setWorkflowTask(new WorkflowTask()); task_1_1.setReferenceTaskName("task1_ref1"); - Task task_2_1 = new Task(); + TaskModel task_2_1 = new TaskModel(); task_2_1.setTaskId(UUID.randomUUID().toString()); task_2_1.setSeq(20); task_2_1.setRetryCount(0); task_2_1.setTaskType(TaskType.SIMPLE.toString()); - task_2_1.setStatus(Status.CANCELED); + task_2_1.setStatus(TaskModel.Status.CANCELED); task_2_1.setTaskDefName("task1"); task_2_1.setWorkflowTask(new WorkflowTask()); task_2_1.setReferenceTaskName("task2_ref1"); @@ -1012,7 +956,7 @@ public void testRetryWorkflowMultipleRetries() { // end of setup // when: - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(new WorkflowDef())); @@ -1021,20 +965,20 @@ public void testRetryWorkflowMultipleRetries() { assertEquals(4, workflow.getTasks().size()); // Reset Last Workflow Task to FAILED. - Task lastTask = + TaskModel lastTask = workflow.getTasks().stream() .filter(t -> t.getReferenceTaskName().equals("task1_ref1")) .collect( groupingBy( - Task::getReferenceTaskName, - maxBy(comparingInt(Task::getSeq)))) + TaskModel::getReferenceTaskName, + maxBy(comparingInt(TaskModel::getSeq)))) .values() .stream() .map(Optional::get) .collect(Collectors.toList()) .get(0); - lastTask.setStatus(Status.FAILED); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + lastTask.setStatus(TaskModel.Status.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); workflowExecutor.retry(workflow.getWorkflowId(), false); @@ -1042,20 +986,20 @@ public void testRetryWorkflowMultipleRetries() { // Reset Last Workflow Task to FAILED. // Reset Last Workflow Task to FAILED. - Task lastTask2 = + TaskModel lastTask2 = workflow.getTasks().stream() .filter(t -> t.getReferenceTaskName().equals("task1_ref1")) .collect( groupingBy( - Task::getReferenceTaskName, - maxBy(comparingInt(Task::getSeq)))) + TaskModel::getReferenceTaskName, + maxBy(comparingInt(TaskModel::getSeq)))) .values() .stream() .map(Optional::get) .collect(Collectors.toList()) .get(0); - lastTask2.setStatus(Status.FAILED); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + lastTask2.setStatus(TaskModel.Status.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); workflowExecutor.retry(workflow.getWorkflowId(), false); @@ -1065,53 +1009,53 @@ public void testRetryWorkflowMultipleRetries() { @Test public void testRetryWorkflowWithJoinTask() { // setup - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRetryWorkflowId"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("testRetryWorkflowId"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRetryWorkflowId"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); //noinspection unchecked workflow.setOutput(Collections.EMPTY_MAP); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); - Task forkTask = new Task(); + TaskModel forkTask = new TaskModel(); forkTask.setTaskType(TaskType.FORK_JOIN.toString()); forkTask.setTaskId(UUID.randomUUID().toString()); forkTask.setSeq(1); forkTask.setRetryCount(1); - forkTask.setStatus(Status.COMPLETED); + forkTask.setStatus(TaskModel.Status.COMPLETED); forkTask.setReferenceTaskName("task_fork"); - Task task_1_1 = new Task(); + TaskModel task_1_1 = new TaskModel(); task_1_1.setTaskId(UUID.randomUUID().toString()); task_1_1.setSeq(20); task_1_1.setRetryCount(1); task_1_1.setTaskType(TaskType.SIMPLE.toString()); - task_1_1.setStatus(Status.FAILED); + task_1_1.setStatus(TaskModel.Status.FAILED); task_1_1.setTaskDefName("task1"); task_1_1.setWorkflowTask(new WorkflowTask()); task_1_1.setReferenceTaskName("task1_ref1"); - Task task_2_1 = new Task(); + TaskModel task_2_1 = new TaskModel(); task_2_1.setTaskId(UUID.randomUUID().toString()); task_2_1.setSeq(22); task_2_1.setRetryCount(1); - task_2_1.setStatus(Status.CANCELED); + task_2_1.setStatus(TaskModel.Status.CANCELED); task_2_1.setTaskType(TaskType.SIMPLE.toString()); task_2_1.setTaskDefName("task2"); task_2_1.setWorkflowTask(new WorkflowTask()); task_2_1.setReferenceTaskName("task2_ref1"); - Task joinTask = new Task(); + TaskModel joinTask = new TaskModel(); joinTask.setTaskType(TaskType.JOIN.toString()); joinTask.setTaskId(UUID.randomUUID().toString()); joinTask.setSeq(25); joinTask.setRetryCount(1); - joinTask.setStatus(Status.CANCELED); + joinTask.setStatus(TaskModel.Status.CANCELED); joinTask.setReferenceTaskName("task_join"); joinTask.getInputData() .put( @@ -1123,14 +1067,14 @@ public void testRetryWorkflowWithJoinTask() { // end of setup // when: - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(new WorkflowDef())); workflowExecutor.retry(workflow.getWorkflowId(), false); assertEquals(6, workflow.getTasks().size()); - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); } @Test @@ -1139,115 +1083,115 @@ public void testRetryFromLastFailedSubWorkflowTaskThenStartWithLastFailedTask() // given String id = IDGenerator.generate(); String workflowInstanceId = IDGenerator.generate(); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType(TaskType.SIMPLE.name()); task.setTaskDefName("task"); task.setReferenceTaskName("task_ref"); task.setWorkflowInstanceId(workflowInstanceId); task.setScheduledTime(System.currentTimeMillis()); task.setTaskId(IDGenerator.generate()); - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); task.setRetryCount(0); task.setWorkflowTask(new WorkflowTask()); task.setOutputData(new HashMap<>()); task.setSubWorkflowId(id); task.setSeq(1); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setTaskType(TaskType.SIMPLE.name()); task1.setTaskDefName("task1"); task1.setReferenceTaskName("task1_ref"); task1.setWorkflowInstanceId(workflowInstanceId); task1.setScheduledTime(System.currentTimeMillis()); task1.setTaskId(IDGenerator.generate()); - task1.setStatus(Status.FAILED); + task1.setStatus(TaskModel.Status.FAILED); task1.setRetryCount(0); task1.setWorkflowTask(new WorkflowTask()); task1.setOutputData(new HashMap<>()); task1.setSubWorkflowId(id); task1.setSeq(2); - Workflow subWorkflow = new Workflow(); + WorkflowModel subWorkflow = new WorkflowModel(); subWorkflow.setWorkflowId(id); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("subworkflow"); workflowDef.setVersion(1); subWorkflow.setWorkflowDefinition(workflowDef); - subWorkflow.setStatus(Workflow.WorkflowStatus.FAILED); + subWorkflow.setStatus(WorkflowModel.Status.FAILED); subWorkflow.getTasks().addAll(Arrays.asList(task, task1)); subWorkflow.setParentWorkflowId("testRunWorkflowId"); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setWorkflowInstanceId(subWorkflow.getWorkflowId()); task2.setScheduledTime(System.currentTimeMillis()); task2.setTaskId(IDGenerator.generate()); - task2.setStatus(Status.FAILED); + task2.setStatus(TaskModel.Status.FAILED); task2.setRetryCount(0); task2.setOutputData(new HashMap<>()); task2.setSubWorkflowId(id); task2.setTaskType(TaskType.SUB_WORKFLOW.name()); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRunWorkflowId"); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); workflow.setTasks(Collections.singletonList(task2)); workflowDef = new WorkflowDef(); workflowDef.setName("first_workflow"); workflow.setWorkflowDefinition(workflowDef); // when - when(executionDAOFacade.getWorkflowById(workflow.getWorkflowId(), true)) + when(executionDAOFacade.getWorkflowModel(workflow.getWorkflowId(), true)) .thenReturn(workflow); - when(executionDAOFacade.getWorkflowById(task.getSubWorkflowId(), true)) + when(executionDAOFacade.getWorkflowModel(task.getSubWorkflowId(), true)) .thenReturn(subWorkflow); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(workflowDef)); - when(executionDAOFacade.getTaskById(subWorkflow.getParentWorkflowTaskId())) + when(executionDAOFacade.getTaskModel(subWorkflow.getParentWorkflowTaskId())) .thenReturn(task1); - when(executionDAOFacade.getWorkflowById(subWorkflow.getParentWorkflowId(), false)) + when(executionDAOFacade.getWorkflowModel(subWorkflow.getParentWorkflowId(), false)) .thenReturn(workflow); workflowExecutor.retry(workflow.getWorkflowId(), true); // then - assertEquals(task.getStatus(), Status.COMPLETED); - assertEquals(task1.getStatus(), Status.IN_PROGRESS); - assertEquals(workflow.getStatus(), WorkflowStatus.RUNNING); - assertEquals(subWorkflow.getStatus(), WorkflowStatus.RUNNING); + assertEquals(task.getStatus(), TaskModel.Status.COMPLETED); + assertEquals(task1.getStatus(), TaskModel.Status.IN_PROGRESS); + assertEquals(workflow.getStatus(), WorkflowModel.Status.RUNNING); + assertEquals(subWorkflow.getStatus(), WorkflowModel.Status.RUNNING); } @Test public void testRetryTimedOutWorkflowWithoutFailedTasks() { // setup - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRetryWorkflowId"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("testRetryWorkflowId"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRetryWorkflowId"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); //noinspection unchecked workflow.setOutput(Collections.EMPTY_MAP); - workflow.setStatus(WorkflowStatus.TIMED_OUT); + workflow.setStatus(WorkflowModel.Status.TIMED_OUT); - Task task_1_1 = new Task(); + TaskModel task_1_1 = new TaskModel(); task_1_1.setTaskId(UUID.randomUUID().toString()); task_1_1.setSeq(20); task_1_1.setRetryCount(1); task_1_1.setTaskType(TaskType.SIMPLE.toString()); - task_1_1.setStatus(Status.COMPLETED); + task_1_1.setStatus(TaskModel.Status.COMPLETED); task_1_1.setRetried(true); task_1_1.setTaskDefName("task1"); task_1_1.setWorkflowTask(new WorkflowTask()); task_1_1.setReferenceTaskName("task1_ref1"); - Task task_2_1 = new Task(); + TaskModel task_2_1 = new TaskModel(); task_2_1.setTaskId(UUID.randomUUID().toString()); task_2_1.setSeq(22); task_2_1.setRetryCount(1); - task_2_1.setStatus(Status.COMPLETED); + task_2_1.setStatus(TaskModel.Status.COMPLETED); task_2_1.setTaskType(TaskType.SIMPLE.toString()); task_2_1.setTaskDefName("task2"); task_2_1.setWorkflowTask(new WorkflowTask()); @@ -1275,14 +1219,14 @@ public void testRetryTimedOutWorkflowWithoutFailedTasks() { // end of setup // when - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(new WorkflowDef())); workflowExecutor.retry(workflow.getWorkflowId(), false); // then - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); assertTrue(workflow.getLastRetriedTime() > 0); assertEquals(1, updateWorkflowCalledCounter.get()); assertEquals(1, updateTasksCalledCounter.get()); @@ -1291,42 +1235,42 @@ public void testRetryTimedOutWorkflowWithoutFailedTasks() { @Test public void testRerunWorkflow() { // setup - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRerunWorkflowId"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("testRerunWorkflowId"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRerunWorkflowId"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); //noinspection unchecked workflow.setOutput(Collections.EMPTY_MAP); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); workflow.setReasonForIncompletion("task1 failed"); workflow.setFailedReferenceTaskNames( - new HashSet() { + new HashSet<>() { { add("task1_ref1"); } }); - Task task_1_1 = new Task(); + TaskModel task_1_1 = new TaskModel(); task_1_1.setTaskId(UUID.randomUUID().toString()); task_1_1.setSeq(20); task_1_1.setRetryCount(1); task_1_1.setTaskType(TaskType.SIMPLE.toString()); - task_1_1.setStatus(Status.FAILED); + task_1_1.setStatus(TaskModel.Status.FAILED); task_1_1.setRetried(true); task_1_1.setTaskDefName("task1"); task_1_1.setWorkflowTask(new WorkflowTask()); task_1_1.setReferenceTaskName("task1_ref1"); - Task task_2_1 = new Task(); + TaskModel task_2_1 = new TaskModel(); task_2_1.setTaskId(UUID.randomUUID().toString()); task_2_1.setSeq(22); task_2_1.setRetryCount(1); - task_2_1.setStatus(Status.CANCELED); + task_2_1.setStatus(TaskModel.Status.CANCELED); task_2_1.setTaskType(TaskType.SIMPLE.toString()); task_2_1.setTaskDefName("task2"); task_2_1.setWorkflowTask(new WorkflowTask()); @@ -1336,7 +1280,7 @@ public void testRerunWorkflow() { // end of setup // when: - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(new WorkflowDef())); RerunWorkflowRequest rerunWorkflowRequest = new RerunWorkflowRequest(); @@ -1344,10 +1288,10 @@ public void testRerunWorkflow() { workflowExecutor.rerun(rerunWorkflowRequest); // when: - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); - assertEquals(null, workflow.getReasonForIncompletion()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); + assertNull(workflow.getReasonForIncompletion()); assertEquals(new HashSet<>(), workflow.getFailedReferenceTaskNames()); } @@ -1358,29 +1302,29 @@ public void testRerunSubWorkflow() { String subWorkflowId = IDGenerator.generate(); // sub workflow setup - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setTaskType(TaskType.SIMPLE.name()); task1.setTaskDefName("task1"); task1.setReferenceTaskName("task1_ref"); task1.setWorkflowInstanceId(subWorkflowId); task1.setScheduledTime(System.currentTimeMillis()); task1.setTaskId(IDGenerator.generate()); - task1.setStatus(Status.COMPLETED); + task1.setStatus(TaskModel.Status.COMPLETED); task1.setWorkflowTask(new WorkflowTask()); task1.setOutputData(new HashMap<>()); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setTaskType(TaskType.SIMPLE.name()); task2.setTaskDefName("task2"); task2.setReferenceTaskName("task2_ref"); task2.setWorkflowInstanceId(subWorkflowId); task2.setScheduledTime(System.currentTimeMillis()); task2.setTaskId(IDGenerator.generate()); - task2.setStatus(Status.COMPLETED); + task2.setStatus(TaskModel.Status.COMPLETED); task2.setWorkflowTask(new WorkflowTask()); task2.setOutputData(new HashMap<>()); - Workflow subWorkflow = new Workflow(); + WorkflowModel subWorkflow = new WorkflowModel(); subWorkflow.setParentWorkflowId(parentWorkflowId); subWorkflow.setWorkflowId(subWorkflowId); WorkflowDef subworkflowDef = new WorkflowDef(); @@ -1388,38 +1332,38 @@ public void testRerunSubWorkflow() { subworkflowDef.setVersion(1); subWorkflow.setWorkflowDefinition(subworkflowDef); subWorkflow.setOwnerApp("junit_testRerunWorkflowId"); - subWorkflow.setStatus(Workflow.WorkflowStatus.COMPLETED); + subWorkflow.setStatus(WorkflowModel.Status.COMPLETED); subWorkflow.getTasks().addAll(Arrays.asList(task1, task2)); // parent workflow setup - Task task = new Task(); + TaskModel task = new TaskModel(); task.setWorkflowInstanceId(parentWorkflowId); task.setScheduledTime(System.currentTimeMillis()); task.setTaskId(IDGenerator.generate()); - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); task.setOutputData(new HashMap<>()); task.setSubWorkflowId(subWorkflowId); task.setTaskType(TaskType.SUB_WORKFLOW.name()); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId(parentWorkflowId); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("parentworkflow"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRerunWorkflowId"); - workflow.setStatus(Workflow.WorkflowStatus.COMPLETED); + workflow.setStatus(WorkflowModel.Status.COMPLETED); workflow.getTasks().addAll(Arrays.asList(task)); // end of setup // when: - when(executionDAOFacade.getWorkflowById(workflow.getWorkflowId(), true)) + when(executionDAOFacade.getWorkflowModel(workflow.getWorkflowId(), true)) .thenReturn(workflow); - when(executionDAOFacade.getWorkflowById(task.getSubWorkflowId(), true)) + when(executionDAOFacade.getWorkflowModel(task.getSubWorkflowId(), true)) .thenReturn(subWorkflow); - when(executionDAOFacade.getTaskById(subWorkflow.getParentWorkflowTaskId())) + when(executionDAOFacade.getTaskModel(subWorkflow.getParentWorkflowTaskId())) .thenReturn(task); - when(executionDAOFacade.getWorkflowById(subWorkflow.getParentWorkflowId(), false)) + when(executionDAOFacade.getWorkflowModel(subWorkflow.getParentWorkflowId(), false)) .thenReturn(workflow); RerunWorkflowRequest rerunWorkflowRequest = new RerunWorkflowRequest(); @@ -1427,50 +1371,50 @@ public void testRerunSubWorkflow() { workflowExecutor.rerun(rerunWorkflowRequest); // then: - assertEquals(Status.IN_PROGRESS, task.getStatus()); - assertEquals(Workflow.WorkflowStatus.RUNNING, subWorkflow.getStatus()); - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); + assertEquals(TaskModel.Status.IN_PROGRESS, task.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, subWorkflow.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); } @Test public void testRerunWorkflowWithTaskId() { // setup - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRerunWorkflowId"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("testRetryWorkflowId"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRerunWorkflowId"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); //noinspection unchecked workflow.setOutput(Collections.EMPTY_MAP); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); workflow.setReasonForIncompletion("task1 failed"); workflow.setFailedReferenceTaskNames( - new HashSet() { + new HashSet<>() { { add("task1_ref1"); } }); - Task task_1_1 = new Task(); + TaskModel task_1_1 = new TaskModel(); task_1_1.setTaskId(UUID.randomUUID().toString()); task_1_1.setSeq(20); task_1_1.setRetryCount(1); task_1_1.setTaskType(TaskType.SIMPLE.toString()); - task_1_1.setStatus(Status.FAILED); + task_1_1.setStatus(TaskModel.Status.FAILED); task_1_1.setRetried(true); task_1_1.setTaskDefName("task1"); task_1_1.setWorkflowTask(new WorkflowTask()); task_1_1.setReferenceTaskName("task1_ref1"); - Task task_2_1 = new Task(); + TaskModel task_2_1 = new TaskModel(); task_2_1.setTaskId(UUID.randomUUID().toString()); task_2_1.setSeq(22); task_2_1.setRetryCount(1); - task_2_1.setStatus(Status.CANCELED); + task_2_1.setStatus(TaskModel.Status.CANCELED); task_2_1.setTaskType(TaskType.SIMPLE.toString()); task_2_1.setTaskDefName("task2"); task_2_1.setWorkflowTask(new WorkflowTask()); @@ -1480,7 +1424,7 @@ public void testRerunWorkflowWithTaskId() { // end of setup // when: - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); when(metadataDAO.getWorkflowDef(anyString(), anyInt())) .thenReturn(Optional.of(new WorkflowDef())); RerunWorkflowRequest rerunWorkflowRequest = new RerunWorkflowRequest(); @@ -1489,9 +1433,9 @@ public void testRerunWorkflowWithTaskId() { workflowExecutor.rerun(rerunWorkflowRequest); // when: - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); assertNull(workflow.getReasonForIncompletion()); assertEquals(new HashSet<>(), workflow.getFailedReferenceTaskNames()); } @@ -1501,36 +1445,36 @@ public void testRerunWorkflowWithSyncSystemTaskId() { // setup String workflowId = IDGenerator.generate(); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setTaskType(TaskType.SIMPLE.name()); task1.setTaskDefName("task1"); task1.setReferenceTaskName("task1_ref"); task1.setWorkflowInstanceId(workflowId); task1.setScheduledTime(System.currentTimeMillis()); task1.setTaskId(IDGenerator.generate()); - task1.setStatus(Status.COMPLETED); + task1.setStatus(TaskModel.Status.COMPLETED); task1.setWorkflowTask(new WorkflowTask()); task1.setOutputData(new HashMap<>()); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setTaskType(TaskType.JSON_JQ_TRANSFORM.name()); task2.setReferenceTaskName("task2_ref"); task2.setWorkflowInstanceId(workflowId); task2.setScheduledTime(System.currentTimeMillis()); task2.setTaskId("system-task-id"); - task2.setStatus(Status.FAILED); + task2.setStatus(TaskModel.Status.FAILED); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId(workflowId); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("workflow"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRerunWorkflowId"); - workflow.setStatus(WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); workflow.setReasonForIncompletion("task2 failed"); workflow.setFailedReferenceTaskNames( - new HashSet() { + new HashSet<>() { { add("task2_ref"); } @@ -1539,7 +1483,7 @@ public void testRerunWorkflowWithSyncSystemTaskId() { // end of setup // when: - when(executionDAOFacade.getWorkflowById(workflow.getWorkflowId(), true)) + when(executionDAOFacade.getWorkflowModel(workflow.getWorkflowId(), true)) .thenReturn(workflow); RerunWorkflowRequest rerunWorkflowRequest = new RerunWorkflowRequest(); rerunWorkflowRequest.setReRunFromWorkflowId(workflow.getWorkflowId()); @@ -1547,8 +1491,8 @@ public void testRerunWorkflowWithSyncSystemTaskId() { workflowExecutor.rerun(rerunWorkflowRequest); // then: - assertEquals(Status.COMPLETED, task2.getStatus()); - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task2.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); assertNull(workflow.getReasonForIncompletion()); assertEquals(new HashSet<>(), workflow.getFailedReferenceTaskNames()); } @@ -1560,29 +1504,29 @@ public void testRerunSubWorkflowWithTaskId() { String subWorkflowId = IDGenerator.generate(); // sub workflow setup - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setTaskType(TaskType.SIMPLE.name()); task1.setTaskDefName("task1"); task1.setReferenceTaskName("task1_ref"); task1.setWorkflowInstanceId(subWorkflowId); task1.setScheduledTime(System.currentTimeMillis()); task1.setTaskId(IDGenerator.generate()); - task1.setStatus(Status.COMPLETED); + task1.setStatus(TaskModel.Status.COMPLETED); task1.setWorkflowTask(new WorkflowTask()); task1.setOutputData(new HashMap<>()); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setTaskType(TaskType.SIMPLE.name()); task2.setTaskDefName("task2"); task2.setReferenceTaskName("task2_ref"); task2.setWorkflowInstanceId(subWorkflowId); task2.setScheduledTime(System.currentTimeMillis()); task2.setTaskId(IDGenerator.generate()); - task2.setStatus(Status.COMPLETED); + task2.setStatus(TaskModel.Status.COMPLETED); task2.setWorkflowTask(new WorkflowTask()); task2.setOutputData(new HashMap<>()); - Workflow subWorkflow = new Workflow(); + WorkflowModel subWorkflow = new WorkflowModel(); subWorkflow.setParentWorkflowId(parentWorkflowId); subWorkflow.setWorkflowId(subWorkflowId); WorkflowDef subworkflowDef = new WorkflowDef(); @@ -1590,38 +1534,38 @@ public void testRerunSubWorkflowWithTaskId() { subworkflowDef.setVersion(1); subWorkflow.setWorkflowDefinition(subworkflowDef); subWorkflow.setOwnerApp("junit_testRerunWorkflowId"); - subWorkflow.setStatus(Workflow.WorkflowStatus.COMPLETED); + subWorkflow.setStatus(WorkflowModel.Status.COMPLETED); subWorkflow.getTasks().addAll(Arrays.asList(task1, task2)); // parent workflow setup - Task task = new Task(); + TaskModel task = new TaskModel(); task.setWorkflowInstanceId(parentWorkflowId); task.setScheduledTime(System.currentTimeMillis()); task.setTaskId(IDGenerator.generate()); - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); task.setOutputData(new HashMap<>()); task.setSubWorkflowId(subWorkflowId); task.setTaskType(TaskType.SUB_WORKFLOW.name()); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId(parentWorkflowId); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("parentworkflow"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRerunWorkflowId"); - workflow.setStatus(Workflow.WorkflowStatus.COMPLETED); + workflow.setStatus(WorkflowModel.Status.COMPLETED); workflow.getTasks().addAll(Arrays.asList(task)); // end of setup // when: - when(executionDAOFacade.getWorkflowById(workflow.getWorkflowId(), true)) + when(executionDAOFacade.getWorkflowModel(workflow.getWorkflowId(), true)) .thenReturn(workflow); - when(executionDAOFacade.getWorkflowById(task.getSubWorkflowId(), true)) + when(executionDAOFacade.getWorkflowModel(task.getSubWorkflowId(), true)) .thenReturn(subWorkflow); - when(executionDAOFacade.getTaskById(subWorkflow.getParentWorkflowTaskId())) + when(executionDAOFacade.getTaskModel(subWorkflow.getParentWorkflowTaskId())) .thenReturn(task); - when(executionDAOFacade.getWorkflowById(subWorkflow.getParentWorkflowId(), false)) + when(executionDAOFacade.getWorkflowModel(subWorkflow.getParentWorkflowId(), false)) .thenReturn(workflow); RerunWorkflowRequest rerunWorkflowRequest = new RerunWorkflowRequest(); @@ -1630,10 +1574,10 @@ public void testRerunSubWorkflowWithTaskId() { workflowExecutor.rerun(rerunWorkflowRequest); // then: - assertEquals(Status.SCHEDULED, task2.getStatus()); - assertEquals(Status.IN_PROGRESS, task.getStatus()); - assertEquals(Workflow.WorkflowStatus.RUNNING, subWorkflow.getStatus()); - assertEquals(Workflow.WorkflowStatus.RUNNING, workflow.getStatus()); + assertEquals(TaskModel.Status.SCHEDULED, task2.getStatus()); + assertEquals(TaskModel.Status.IN_PROGRESS, task.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, subWorkflow.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); } @Test @@ -1715,8 +1659,8 @@ public void testDefaultDomain() { @Test public void testTaskToDomain() { - Workflow workflow = generateSampleWorkflow(); - List tasks = generateSampleTasks(3); + WorkflowModel workflow = generateSampleWorkflow(); + List tasks = generateSampleTasks(3); Map taskToDomain = new HashMap<>(); taskToDomain.put("*", "mydomain"); @@ -1735,8 +1679,8 @@ public void testTaskToDomain() { @Test public void testTaskToDomainsPerTask() { - Workflow workflow = generateSampleWorkflow(); - List tasks = generateSampleTasks(2); + WorkflowModel workflow = generateSampleWorkflow(); + List tasks = generateSampleTasks(2); Map taskToDomain = new HashMap<>(); taskToDomain.put("*", "mydomain, NO_DOMAIN"); @@ -1756,8 +1700,8 @@ public void testTaskToDomainsPerTask() { @Test public void testTaskToDomainOverrides() { - Workflow workflow = generateSampleWorkflow(); - List tasks = generateSampleTasks(4); + WorkflowModel workflow = generateSampleWorkflow(); + List tasks = generateSampleTasks(4); Map taskToDomain = new HashMap<>(); taskToDomain.put("*", "mydomain"); @@ -1793,19 +1737,19 @@ public void testTaskToDomainOverrides() { @Test public void testDedupAndAddTasks() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setReferenceTaskName("task1"); task1.setRetryCount(1); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setReferenceTaskName("task2"); task2.setRetryCount(2); - List tasks = new ArrayList<>(Arrays.asList(task1, task2)); + List tasks = new ArrayList<>(Arrays.asList(task1, task2)); - List taskList = workflowExecutor.dedupAndAddTasks(workflow, tasks); + List taskList = workflowExecutor.dedupAndAddTasks(workflow, tasks); assertEquals(2, taskList.size()); assertEquals(tasks, taskList); assertEquals(workflow.getTasks(), taskList); @@ -1816,7 +1760,7 @@ public void testDedupAndAddTasks() { assertEquals(workflow.getTasks(), tasks); // Adding 2 new tasks - Task newTask = new Task(); + TaskModel newTask = new TaskModel(); newTask.setReferenceTaskName("newTask"); newTask.setRetryCount(0); @@ -1828,10 +1772,10 @@ public void testDedupAndAddTasks() { @Test(expected = ApplicationException.class) public void testTerminateCompletedWorkflow() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testTerminateTerminalWorkflow"); - workflow.setStatus(Workflow.WorkflowStatus.COMPLETED); - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + workflow.setStatus(WorkflowModel.Status.COMPLETED); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); workflowExecutor.terminateWorkflow( workflow.getWorkflowId(), "test terminating terminal workflow"); @@ -1840,48 +1784,48 @@ public void testTerminateCompletedWorkflow() { @Test public void testResetCallbacksForWorkflowTasks() { String workflowId = "test-workflow-id"; - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId(workflowId); - workflow.setStatus(WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); - Task completedTask = new Task(); + TaskModel completedTask = new TaskModel(); completedTask.setTaskType(TaskType.SIMPLE.name()); completedTask.setReferenceTaskName("completedTask"); completedTask.setWorkflowInstanceId(workflowId); completedTask.setScheduledTime(System.currentTimeMillis()); completedTask.setCallbackAfterSeconds(300); completedTask.setTaskId("simple-task-id"); - completedTask.setStatus(Status.COMPLETED); + completedTask.setStatus(TaskModel.Status.COMPLETED); - Task systemTask = new Task(); + TaskModel systemTask = new TaskModel(); systemTask.setTaskType(TaskType.WAIT.name()); systemTask.setReferenceTaskName("waitTask"); systemTask.setWorkflowInstanceId(workflowId); systemTask.setScheduledTime(System.currentTimeMillis()); systemTask.setTaskId("system-task-id"); - systemTask.setStatus(Status.SCHEDULED); + systemTask.setStatus(TaskModel.Status.SCHEDULED); - Task simpleTask = new Task(); + TaskModel simpleTask = new TaskModel(); simpleTask.setTaskType(TaskType.SIMPLE.name()); simpleTask.setReferenceTaskName("simpleTask"); simpleTask.setWorkflowInstanceId(workflowId); simpleTask.setScheduledTime(System.currentTimeMillis()); simpleTask.setCallbackAfterSeconds(300); simpleTask.setTaskId("simple-task-id"); - simpleTask.setStatus(Status.SCHEDULED); + simpleTask.setStatus(TaskModel.Status.SCHEDULED); - Task noCallbackTask = new Task(); + TaskModel noCallbackTask = new TaskModel(); noCallbackTask.setTaskType(TaskType.SIMPLE.name()); noCallbackTask.setReferenceTaskName("noCallbackTask"); noCallbackTask.setWorkflowInstanceId(workflowId); noCallbackTask.setScheduledTime(System.currentTimeMillis()); noCallbackTask.setCallbackAfterSeconds(0); noCallbackTask.setTaskId("no-callback-task-id"); - noCallbackTask.setStatus(Status.SCHEDULED); + noCallbackTask.setStatus(TaskModel.Status.SCHEDULED); workflow.getTasks() .addAll(Arrays.asList(completedTask, systemTask, simpleTask, noCallbackTask)); - when(executionDAOFacade.getWorkflowById(workflowId, true)).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(workflowId, true)).thenReturn(workflow); workflowExecutor.resetCallbacksForWorkflow(workflowId); verify(queueDAO, times(1)).resetOffsetTime(anyString(), anyString()); @@ -1893,23 +1837,23 @@ public void testUpdateParentWorkflowTask() { String parentWorkflowTaskId = "parent_workflow_task_id"; String workflowId = "workflow_id"; - Workflow subWorkflow = new Workflow(); + WorkflowModel subWorkflow = new WorkflowModel(); subWorkflow.setWorkflowId(workflowId); subWorkflow.setParentWorkflowTaskId(parentWorkflowTaskId); - subWorkflow.setStatus(WorkflowStatus.COMPLETED); + subWorkflow.setStatus(WorkflowModel.Status.COMPLETED); - Task subWorkflowTask = new Task(); + TaskModel subWorkflowTask = new TaskModel(); subWorkflowTask.setSubWorkflowId(workflowId); - subWorkflowTask.setStatus(Status.IN_PROGRESS); + subWorkflowTask.setStatus(TaskModel.Status.IN_PROGRESS); subWorkflowTask.setExternalOutputPayloadStoragePath(null); - when(executionDAOFacade.getTaskById(parentWorkflowTaskId)).thenReturn(subWorkflowTask); - when(executionDAOFacade.getWorkflowById(workflowId, false)).thenReturn(subWorkflow); + when(executionDAOFacade.getTaskModel(parentWorkflowTaskId)).thenReturn(subWorkflowTask); + when(executionDAOFacade.getWorkflowModel(workflowId, false)).thenReturn(subWorkflow); workflowExecutor.updateParentWorkflowTask(subWorkflow); - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Task.class); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(TaskModel.class); verify(executionDAOFacade, times(1)).updateTask(argumentCaptor.capture()); - assertEquals(Status.COMPLETED, argumentCaptor.getAllValues().get(0).getStatus()); + assertEquals(TaskModel.Status.COMPLETED, argumentCaptor.getAllValues().get(0).getStatus()); assertEquals(workflowId, argumentCaptor.getAllValues().get(0).getSubWorkflowId()); } @@ -1917,7 +1861,7 @@ public void testUpdateParentWorkflowTask() { public void testStartWorkflow() { WorkflowDef def = new WorkflowDef(); def.setName("test"); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); Map workflowInput = new HashMap<>(); @@ -1930,7 +1874,7 @@ public void testStartWorkflow() { Map taskToDomain = null; when(executionLockService.acquireLock(anyString())).thenReturn(true); - when(executionDAOFacade.getWorkflowById(anyString(), anyBoolean())).thenReturn(workflow); + when(executionDAOFacade.getWorkflowModel(anyString(), anyBoolean())).thenReturn(workflow); workflowExecutor.startWorkflow( def, @@ -1943,25 +1887,25 @@ public void testStartWorkflow() { event, taskToDomain); - verify(executionDAOFacade, times(1)).createWorkflow(any(Workflow.class)); + verify(executionDAOFacade, times(1)).createWorkflow(any(WorkflowModel.class)); verify(executionLockService, times(2)).acquireLock(anyString()); - verify(executionDAOFacade, times(1)).getWorkflowById(anyString(), anyBoolean()); + verify(executionDAOFacade, times(1)).getWorkflowModel(anyString(), anyBoolean()); } @Test public void testScheduleNextIteration() { - Workflow workflow = generateSampleWorkflow(); + WorkflowModel workflow = generateSampleWorkflow(); workflow.setTaskToDomain( - new HashMap() { + new HashMap<>() { { put("TEST", "domain1"); } }); - Task loopTask = mock(Task.class); + TaskModel loopTask = mock(TaskModel.class); WorkflowTask loopWfTask = mock(WorkflowTask.class); when(loopTask.getWorkflowTask()).thenReturn(loopWfTask); List loopOver = - new ArrayList() { + new ArrayList<>() { { WorkflowTask workflowTask = new WorkflowTask(); workflowTask.setType(TaskType.TASK_TYPE_SIMPLE); @@ -1981,37 +1925,38 @@ public void testCancelNonTerminalTasks() { WorkflowDef def = new WorkflowDef(); def.setWorkflowStatusListenerEnabled(true); - Workflow workflow = generateSampleWorkflow(); + WorkflowModel workflow = generateSampleWorkflow(); workflow.setWorkflowDefinition(def); - Task subWorkflowTask = new Task(); + TaskModel subWorkflowTask = new TaskModel(); subWorkflowTask.setTaskId(UUID.randomUUID().toString()); subWorkflowTask.setTaskType(TaskType.SUB_WORKFLOW.name()); - subWorkflowTask.setStatus(Status.IN_PROGRESS); + subWorkflowTask.setStatus(TaskModel.Status.IN_PROGRESS); - Task lambdaTask = new Task(); + TaskModel lambdaTask = new TaskModel(); lambdaTask.setTaskId(UUID.randomUUID().toString()); lambdaTask.setTaskType(TaskType.LAMBDA.name()); - lambdaTask.setStatus(Status.SCHEDULED); + lambdaTask.setStatus(TaskModel.Status.SCHEDULED); - Task simpleTask = new Task(); + TaskModel simpleTask = new TaskModel(); simpleTask.setTaskId(UUID.randomUUID().toString()); simpleTask.setTaskType(TaskType.SIMPLE.name()); - simpleTask.setStatus(Status.COMPLETED); + simpleTask.setStatus(TaskModel.Status.COMPLETED); workflow.getTasks().addAll(Arrays.asList(subWorkflowTask, lambdaTask, simpleTask)); List erroredTasks = workflowExecutor.cancelNonTerminalTasks(workflow); assertTrue(erroredTasks.isEmpty()); - ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Task.class); + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(TaskModel.class); verify(executionDAOFacade, times(2)).updateTask(argumentCaptor.capture()); assertEquals(2, argumentCaptor.getAllValues().size()); assertEquals( TaskType.SUB_WORKFLOW.name(), argumentCaptor.getAllValues().get(0).getTaskType()); - assertEquals(Status.CANCELED, argumentCaptor.getAllValues().get(0).getStatus()); + assertEquals(TaskModel.Status.CANCELED, argumentCaptor.getAllValues().get(0).getStatus()); assertEquals(TaskType.LAMBDA.name(), argumentCaptor.getAllValues().get(1).getTaskType()); - assertEquals(Status.CANCELED, argumentCaptor.getAllValues().get(1).getStatus()); - verify(workflowStatusListener, times(1)).onWorkflowFinalizedIfEnabled(any(Workflow.class)); + assertEquals(TaskModel.Status.CANCELED, argumentCaptor.getAllValues().get(1).getStatus()); + verify(workflowStatusListener, times(1)) + .onWorkflowFinalizedIfEnabled(any(WorkflowModel.class)); } @Test @@ -2020,95 +1965,95 @@ public void testPauseWorkflow() { doNothing().when(executionLockService).releaseLock(anyString()); String workflowId = "testPauseWorkflowId"; - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId(workflowId); // if workflow is in terminal state - workflow.setStatus(COMPLETED); - when(executionDAOFacade.getWorkflowById(workflowId, false)).thenReturn(workflow); + workflow.setStatus(WorkflowModel.Status.COMPLETED); + when(executionDAOFacade.getWorkflowModel(workflowId, false)).thenReturn(workflow); try { workflowExecutor.pauseWorkflow(workflowId); fail("Expected " + ApplicationException.class); } catch (ApplicationException e) { assertEquals(e.getCode(), CONFLICT); - verify(executionDAOFacade, never()).updateWorkflow(any(Workflow.class)); + verify(executionDAOFacade, never()).updateWorkflow(any(WorkflowModel.class)); verify(queueDAO, never()).remove(anyString(), anyString()); } // if workflow is already PAUSED - workflow.setStatus(PAUSED); - when(executionDAOFacade.getWorkflowById(workflowId, false)).thenReturn(workflow); + workflow.setStatus(WorkflowModel.Status.PAUSED); + when(executionDAOFacade.getWorkflowModel(workflowId, false)).thenReturn(workflow); workflowExecutor.pauseWorkflow(workflowId); - assertEquals(PAUSED, workflow.getStatus()); - verify(executionDAOFacade, never()).updateWorkflow(any(Workflow.class)); + assertEquals(WorkflowModel.Status.PAUSED, workflow.getStatus()); + verify(executionDAOFacade, never()).updateWorkflow(any(WorkflowModel.class)); verify(queueDAO, never()).remove(anyString(), anyString()); // if workflow is RUNNING - workflow.setStatus(RUNNING); - when(executionDAOFacade.getWorkflowById(workflowId, false)).thenReturn(workflow); + workflow.setStatus(WorkflowModel.Status.RUNNING); + when(executionDAOFacade.getWorkflowModel(workflowId, false)).thenReturn(workflow); workflowExecutor.pauseWorkflow(workflowId); - assertEquals(PAUSED, workflow.getStatus()); - verify(executionDAOFacade, times(1)).updateWorkflow(any(Workflow.class)); + assertEquals(WorkflowModel.Status.PAUSED, workflow.getStatus()); + verify(executionDAOFacade, times(1)).updateWorkflow(any(WorkflowModel.class)); verify(queueDAO, times(1)).remove(anyString(), anyString()); } @Test public void testResumeWorkflow() { String workflowId = "testResumeWorkflowId"; - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId(workflowId); // if workflow is not in PAUSED state - workflow.setStatus(COMPLETED); - when(executionDAOFacade.getWorkflowById(workflowId, false)).thenReturn(workflow); + workflow.setStatus(WorkflowModel.Status.COMPLETED); + when(executionDAOFacade.getWorkflowModel(workflowId, false)).thenReturn(workflow); try { workflowExecutor.resumeWorkflow(workflowId); } catch (Exception e) { assertTrue(e instanceof IllegalStateException); - verify(executionDAOFacade, never()).updateWorkflow(any(Workflow.class)); + verify(executionDAOFacade, never()).updateWorkflow(any(WorkflowModel.class)); verify(queueDAO, never()).push(anyString(), anyString(), anyInt(), anyLong()); } // if workflow is in PAUSED state - workflow.setStatus(PAUSED); - when(executionDAOFacade.getWorkflowById(workflowId, false)).thenReturn(workflow); + workflow.setStatus(WorkflowModel.Status.PAUSED); + when(executionDAOFacade.getWorkflowModel(workflowId, false)).thenReturn(workflow); workflowExecutor.resumeWorkflow(workflowId); - assertEquals(RUNNING, workflow.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, workflow.getStatus()); assertTrue(workflow.getLastRetriedTime() > 0); - verify(executionDAOFacade, times(1)).updateWorkflow(any(Workflow.class)); + verify(executionDAOFacade, times(1)).updateWorkflow(any(WorkflowModel.class)); verify(queueDAO, times(1)).push(anyString(), anyString(), anyInt(), anyLong()); } - private Workflow generateSampleWorkflow() { + private WorkflowModel generateSampleWorkflow() { // setup - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("testRetryWorkflowId"); WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setName("testRetryWorkflowId"); workflowDef.setVersion(1); workflow.setWorkflowDefinition(workflowDef); workflow.setOwnerApp("junit_testRetryWorkflowId"); - workflow.setStartTime(10L); + workflow.setCreateTime(10L); workflow.setEndTime(100L); //noinspection unchecked workflow.setOutput(Collections.EMPTY_MAP); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setStatus(WorkflowModel.Status.FAILED); return workflow; } - private List generateSampleTasks(int count) { + private List generateSampleTasks(int count) { if (count == 0) { return null; } - List tasks = new ArrayList<>(); + List tasks = new ArrayList<>(); for (int i = 0; i < count; i++) { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskId(UUID.randomUUID().toString()); task.setSeq(i); task.setRetryCount(1); task.setTaskType("task" + (i + 1)); - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); task.setTaskDefName("taskX"); task.setReferenceTaskName("task_ref" + (i + 1)); tasks.add(task); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/WorkflowSystemTaskStub.java b/core/src/test/java/com/netflix/conductor/core/execution/WorkflowSystemTaskStub.java index 8debfeaac7..3175a248e8 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/WorkflowSystemTaskStub.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/WorkflowSystemTaskStub.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -12,10 +12,9 @@ */ package com.netflix.conductor.core.execution; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; public class WorkflowSystemTaskStub extends WorkflowSystemTask { @@ -26,9 +25,9 @@ public WorkflowSystemTaskStub(String taskType) { } @Override - public void start(Workflow workflow, Task task, WorkflowExecutor executor) { + public void start(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { started = true; - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); super.start(workflow, task, executor); } diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/DecisionTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/DecisionTaskMapperTest.java index e02b151c23..df38b5eb83 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/DecisionTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/DecisionTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -28,16 +28,16 @@ import org.springframework.test.context.junit4.SpringRunner; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.execution.DeciderService; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -119,7 +119,7 @@ public void getMappedTasks() { WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setSchemaVersion(2); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); Map workflowInput = new HashMap<>(); workflowInput.put("Id", "22"); @@ -133,7 +133,7 @@ public void getMappedTasks() { parametersUtils.getTaskInput( decisionTask.getInputParameters(), workflowInstance, null, null); - Task theTask = new Task(); + TaskModel theTask = new TaskModel(); theTask.setReferenceTaskName("Foo"); theTask.setTaskId(IDGenerator.generate()); @@ -152,7 +152,7 @@ public void getMappedTasks() { .build(); // When - List mappedTasks = decisionTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = decisionTaskMapper.getMappedTasks(taskMapperContext); // Then assertEquals(2, mappedTasks.size()); @@ -174,7 +174,7 @@ public void getEvaluatedCaseValue() { decisionCases.put("1", Collections.singletonList(task3)); decisionTask.setDecisionCases(decisionCases); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(new WorkflowDef()); Map workflowInput = new HashMap<>(); workflowInput.put("param1", "test1"); @@ -218,7 +218,7 @@ public void getEvaluatedCaseValueUsingExpression() { WorkflowDef def = new WorkflowDef(); def.setSchemaVersion(2); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(def); Map workflowInput = new HashMap<>(); workflowInput.put("Id", "22"); @@ -265,7 +265,7 @@ public void getEvaluatedCaseValueException() { WorkflowDef def = new WorkflowDef(); def.setSchemaVersion(2); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(def); Map workflowInput = new HashMap<>(); workflowInput.put(".Id", "22"); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/DoWhileTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/DoWhileTaskMapperTest.java index d8d972015f..f56cce21c4 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/DoWhileTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/DoWhileTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,16 +20,16 @@ import org.junit.Test; import org.mockito.Mockito; -import com.netflix.conductor.common.metadata.tasks.Task; 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.common.utils.TaskUtils; import com.netflix.conductor.core.execution.DeciderService; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_DO_WHILE; @@ -38,9 +38,9 @@ public class DoWhileTaskMapperTest { - private Task task1; + private TaskModel task1; private DeciderService deciderService; - private Workflow workflow; + private WorkflowModel workflow; private WorkflowTask workflowTask1; private TaskMapperContext taskMapperContext; private MetadataDAO metadataDAO; @@ -50,9 +50,9 @@ public void setup() { WorkflowTask taskToSchedule = new WorkflowTask(); taskToSchedule.setType(TaskType.DO_WHILE.name()); taskToSchedule.setTaskReferenceName("Test"); - task1 = new Task(); + task1 = new TaskModel(); task1.setReferenceTaskName("task1"); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setReferenceTaskName("task2"); workflowTask1 = new WorkflowTask(); workflowTask1.setTaskReferenceName("task1"); @@ -67,7 +67,7 @@ public void setup() { String taskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - workflow = new Workflow(); + workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); deciderService = Mockito.mock(DeciderService.class); @@ -92,7 +92,7 @@ public void getMappedTasks() { .when(deciderService) .getTasksToBeScheduled(workflow, workflowTask1, 0); - List mappedTasks = + List mappedTasks = new DoWhileTaskMapper(metadataDAO).getMappedTasks(taskMapperContext); assertNotNull(mappedTasks); @@ -105,9 +105,9 @@ public void getMappedTasks() { @Test public void shouldNotScheduleCompletedTask() { - task1.setStatus(Task.Status.COMPLETED); + task1.setStatus(TaskModel.Status.COMPLETED); - List mappedTasks = + List mappedTasks = new DoWhileTaskMapper(metadataDAO).getMappedTasks(taskMapperContext); assertNotNull(mappedTasks); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/DynamicTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/DynamicTaskMapperTest.java index 0d88ec26d1..7f6baaa59e 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/DynamicTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/DynamicTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,15 +21,15 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -67,12 +67,12 @@ public void getMappedTasks() { taskInput.put("dynamicTaskName", "DynoTask"); when(parametersUtils.getTaskInput( - anyMap(), any(Workflow.class), any(TaskDef.class), anyString())) + anyMap(), any(WorkflowModel.class), any(TaskDef.class), anyString())) .thenReturn(taskInput); String taskId = IDGenerator.generate(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef workflowDef = new WorkflowDef(); workflow.setWorkflowDefinition(workflowDef); @@ -89,11 +89,11 @@ public void getMappedTasks() { when(metadataDAO.getTaskDef("DynoTask")).thenReturn(new TaskDef()); - List mappedTasks = dynamicTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = dynamicTaskMapper.getMappedTasks(taskMapperContext); assertEquals(1, mappedTasks.size()); - Task dynamicTask = mappedTasks.get(0); + TaskModel dynamicTask = mappedTasks.get(0); assertEquals(taskId, dynamicTask.getTaskId()); } diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/EventTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/EventTaskMapperTest.java index 6b2628f810..b8dd426038 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/EventTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/EventTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -19,13 +19,13 @@ import org.junit.Test; import org.mockito.Mockito; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; 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.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -48,11 +48,11 @@ public void getMappedTasks() { eventTaskInput.put("sink", "SQSSINK"); when(parametersUtils.getTaskInput( - anyMap(), any(Workflow.class), any(TaskDef.class), anyString())) + anyMap(), any(WorkflowModel.class), any(TaskDef.class), anyString())) .thenReturn(eventTaskInput); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -65,10 +65,10 @@ public void getMappedTasks() { .withTaskId(taskId) .build(); - List mappedTasks = eventTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = eventTaskMapper.getMappedTasks(taskMapperContext); assertEquals(1, mappedTasks.size()); - Task eventTask = mappedTasks.get(0); + TaskModel eventTask = mappedTasks.get(0); assertEquals(taskId, eventTask.getTaskId()); } } diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapperTest.java index 2456a7cd24..f2a9d26f5b 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/ForkJoinDynamicTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -25,18 +25,18 @@ import org.junit.rules.ExpectedException; import org.mockito.Mockito; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.DynamicForkJoinTaskList; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.execution.DeciderService; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -82,7 +82,7 @@ public void getMappedTasksException() { def.setVersion(1); def.setInputParameters(Arrays.asList("param1", "param2")); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(def); WorkflowTask dynamicForkJoinToSchedule = new WorkflowTask(); @@ -123,16 +123,16 @@ public void getMappedTasksException() { dynamicTasksInput.put("dynamicTasksInput", dynamicTasksInput); // when - when(parametersUtils.getTaskInput(anyMap(), any(Workflow.class), any(), any())) + when(parametersUtils.getTaskInput(anyMap(), any(WorkflowModel.class), any(), any())) .thenReturn(dynamicTasksInput); when(objectMapper.convertValue(any(), any(TypeReference.class))) .thenReturn(Arrays.asList(wt2, wt3)); - Task simpleTask1 = new Task(); + TaskModel simpleTask1 = new TaskModel(); simpleTask1.setReferenceTaskName("xdt1"); - Task simpleTask2 = new Task(); + TaskModel simpleTask2 = new TaskModel(); simpleTask2.setReferenceTaskName("xdt2"); when(deciderService.getTasksToBeScheduled(workflowInstance, wt2, 0)) @@ -166,7 +166,7 @@ public void getMappedTasks() { def.setVersion(1); def.setInputParameters(Arrays.asList("param1", "param2")); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(def); WorkflowTask dynamicForkJoinToSchedule = new WorkflowTask(); @@ -208,15 +208,15 @@ public void getMappedTasks() { dynamicTasksInput.put("dynamicTasksInput", dynamicTasksInput); // when - when(parametersUtils.getTaskInput(anyMap(), any(Workflow.class), any(), any())) + when(parametersUtils.getTaskInput(anyMap(), any(WorkflowModel.class), any(), any())) .thenReturn(dynamicTasksInput); when(objectMapper.convertValue(any(), any(TypeReference.class))) .thenReturn(Arrays.asList(wt2, wt3)); - Task simpleTask1 = new Task(); + TaskModel simpleTask1 = new TaskModel(); simpleTask1.setReferenceTaskName("xdt1"); - Task simpleTask2 = new Task(); + TaskModel simpleTask2 = new TaskModel(); simpleTask2.setReferenceTaskName("xdt2"); when(deciderService.getTasksToBeScheduled(workflowInstance, wt2, 0)) @@ -236,7 +236,7 @@ public void getMappedTasks() { .build(); // then - List mappedTasks = forkJoinDynamicTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = forkJoinDynamicTaskMapper.getMappedTasks(taskMapperContext); assertEquals(4, mappedTasks.size()); @@ -275,14 +275,14 @@ public void getDynamicForkJoinTasksAndInput() { // when when(parametersUtils.getTaskInput( - anyMap(), any(Workflow.class), any(TaskDef.class), anyString())) + anyMap(), any(WorkflowModel.class), any(TaskDef.class), anyString())) .thenReturn(dynamicTasksInput); when(objectMapper.convertValue(any(), any(Class.class))).thenReturn(dtasks); Pair, Map>> dynamicForkJoinTasksAndInput = forkJoinDynamicTaskMapper.getDynamicForkJoinTasksAndInput( - dynamicForkJoinToSchedule, new Workflow()); + dynamicForkJoinToSchedule, new WorkflowModel()); // then assertNotNull(dynamicForkJoinTasksAndInput.getLeft()); assertEquals(2, dynamicForkJoinTasksAndInput.getLeft().size()); @@ -318,7 +318,7 @@ public void getDynamicForkJoinTasksAndInputException() { // when when(parametersUtils.getTaskInput( - anyMap(), any(Workflow.class), any(TaskDef.class), anyString())) + anyMap(), any(WorkflowModel.class), any(TaskDef.class), anyString())) .thenReturn(dynamicTasksInput); when(objectMapper.convertValue(any(), any(Class.class))).thenReturn(null); @@ -327,7 +327,7 @@ public void getDynamicForkJoinTasksAndInputException() { expectedException.expect(TerminateWorkflowException.class); forkJoinDynamicTaskMapper.getDynamicForkJoinTasksAndInput( - dynamicForkJoinToSchedule, new Workflow()); + dynamicForkJoinToSchedule, new WorkflowModel()); } @Test @@ -365,7 +365,7 @@ public void getDynamicForkTasksAndInput() { dynamicTasksInput.put("dynamicTasksInput", dynamicTasksInput); // when - when(parametersUtils.getTaskInput(anyMap(), any(Workflow.class), any(), any())) + when(parametersUtils.getTaskInput(anyMap(), any(WorkflowModel.class), any(), any())) .thenReturn(dynamicTasksInput); when(objectMapper.convertValue(any(), any(TypeReference.class))) @@ -373,7 +373,7 @@ public void getDynamicForkTasksAndInput() { Pair, Map>> dynamicTasks = forkJoinDynamicTaskMapper.getDynamicForkTasksAndInput( - dynamicForkJoinToSchedule, new Workflow(), "dynamicTasks"); + dynamicForkJoinToSchedule, new WorkflowModel(), "dynamicTasks"); // then assertNotNull(dynamicTasks.getLeft()); @@ -414,7 +414,7 @@ public void getDynamicForkTasksAndInputException() { dynamicTasksInput.put("dynamicTasks", Arrays.asList(wt2, wt3)); dynamicTasksInput.put("dynamicTasksInput", null); - when(parametersUtils.getTaskInput(anyMap(), any(Workflow.class), any(), any())) + when(parametersUtils.getTaskInput(anyMap(), any(WorkflowModel.class), any(), any())) .thenReturn(dynamicTasksInput); when(objectMapper.convertValue(any(), any(TypeReference.class))) @@ -423,7 +423,7 @@ public void getDynamicForkTasksAndInputException() { expectedException.expect(TerminateWorkflowException.class); // when forkJoinDynamicTaskMapper.getDynamicForkTasksAndInput( - dynamicForkJoinToSchedule, new Workflow(), "dynamicTasks"); + dynamicForkJoinToSchedule, new WorkflowModel(), "dynamicTasks"); } @Test @@ -434,7 +434,7 @@ public void testDynamicTaskDuplicateTaskRefName() { def.setVersion(1); def.setInputParameters(Arrays.asList("param1", "param2")); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(def); WorkflowTask dynamicForkJoinToSchedule = new WorkflowTask(); @@ -476,12 +476,12 @@ public void testDynamicTaskDuplicateTaskRefName() { dynamicTasksInput.put("dynamicTasksInput", dynamicTasksInput); // dynamic - when(parametersUtils.getTaskInput(anyMap(), any(Workflow.class), any(), any())) + when(parametersUtils.getTaskInput(anyMap(), any(WorkflowModel.class), any(), any())) .thenReturn(dynamicTasksInput); when(objectMapper.convertValue(any(), any(TypeReference.class))) .thenReturn(Arrays.asList(wt2, wt3)); - Task simpleTask1 = new Task(); + TaskModel simpleTask1 = new TaskModel(); simpleTask1.setReferenceTaskName("xdt1"); // Empty list, this is a bad state, workflow should terminate diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/ForkJoinTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/ForkJoinTaskMapperTest.java index 9993d1275b..edd902e16a 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/ForkJoinTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/ForkJoinTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -24,14 +24,14 @@ import org.junit.rules.ExpectedException; import org.mockito.Mockito; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.execution.DeciderService; import com.netflix.conductor.core.utils.IDGenerator; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_FORK; @@ -101,13 +101,13 @@ public void getMappedTasks() { def.getTasks().add(join); def.getTasks().add(wft4); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setReferenceTaskName(wft1.getTaskReferenceName()); - Task task3 = new Task(); + TaskModel task3 = new TaskModel(); task3.setReferenceTaskName(wft3.getTaskReferenceName()); Mockito.when(deciderService.getTasksToBeScheduled(workflow, wft1, 0)) @@ -126,7 +126,7 @@ public void getMappedTasks() { .withDeciderService(deciderService) .build(); - List mappedTasks = forkJoinTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = forkJoinTaskMapper.getMappedTasks(taskMapperContext); assertEquals(3, mappedTasks.size()); assertEquals(TASK_TYPE_FORK, mappedTasks.get(0).getTaskType()); @@ -182,13 +182,13 @@ public void getMappedTasksException() { def.getTasks().add(wft4); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setReferenceTaskName(wft1.getTaskReferenceName()); - Task task3 = new Task(); + TaskModel task3 = new TaskModel(); task3.setReferenceTaskName(wft3.getTaskReferenceName()); Mockito.when(deciderService.getTasksToBeScheduled(workflow, wft1, 0)) diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/HTTPTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/HTTPTaskMapperTest.java index 993a579c68..10da266706 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/HTTPTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/HTTPTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,15 +20,15 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; @@ -56,7 +56,7 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); String retriedTaskId = IDGenerator.generate(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef workflowDef = new WorkflowDef(); workflow.setWorkflowDefinition(workflowDef); @@ -73,7 +73,7 @@ public void getMappedTasks() { .build(); // when - List mappedTasks = httpTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = httpTaskMapper.getMappedTasks(taskMapperContext); // Then assertEquals(1, mappedTasks.size()); @@ -89,7 +89,7 @@ public void getMappedTasks_WithoutTaskDef() { String taskId = IDGenerator.generate(); String retriedTaskId = IDGenerator.generate(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef workflowDef = new WorkflowDef(); workflow.setWorkflowDefinition(workflowDef); @@ -106,7 +106,7 @@ public void getMappedTasks_WithoutTaskDef() { .build(); // when - List mappedTasks = httpTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = httpTaskMapper.getMappedTasks(taskMapperContext); // Then assertEquals(1, mappedTasks.size()); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/InlineTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/InlineTaskMapperTest.java index 826bf2569f..5791555c0e 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/InlineTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/InlineTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,16 +17,16 @@ import org.junit.Before; import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.execution.evaluators.JavascriptEvaluator; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -58,7 +58,7 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -71,7 +71,7 @@ public void getMappedTasks() { .withTaskId(taskId) .build(); - List mappedTasks = + List mappedTasks = new InlineTaskMapper(parametersUtils, metadataDAO) .getMappedTasks(taskMapperContext); @@ -93,7 +93,7 @@ public void getMappedTasks_WithoutTaskDef() { String taskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -106,7 +106,7 @@ public void getMappedTasks_WithoutTaskDef() { .withTaskId(taskId) .build(); - List mappedTasks = + List mappedTasks = new InlineTaskMapper(parametersUtils, metadataDAO) .getMappedTasks(taskMapperContext); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/JoinTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/JoinTaskMapperTest.java index 346479937c..a1c9fd8ca2 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/JoinTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/JoinTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,13 +17,13 @@ import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.utils.IDGenerator; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_JOIN; @@ -42,20 +42,20 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); WorkflowDef wd = new WorkflowDef(); - Workflow w = new Workflow(); - w.setWorkflowDefinition(wd); + WorkflowModel workflow = new WorkflowModel(); + workflow.setWorkflowDefinition(wd); TaskMapperContext taskMapperContext = TaskMapperContext.newBuilder() .withWorkflowDefinition(wd) - .withWorkflowInstance(w) + .withWorkflowInstance(workflow) .withTaskDefinition(new TaskDef()) .withTaskToSchedule(taskToSchedule) .withRetryCount(0) .withTaskId(taskId) .build(); - List mappedTasks = new JoinTaskMapper().getMappedTasks(taskMapperContext); + List mappedTasks = new JoinTaskMapper().getMappedTasks(taskMapperContext); assertNotNull(mappedTasks); assertEquals(TASK_TYPE_JOIN, mappedTasks.get(0).getTaskType()); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/JsonJQTransformTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/JsonJQTransformTaskMapperTest.java index 97080f1188..fa573f6c93 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/JsonJQTransformTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/JsonJQTransformTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -19,15 +19,15 @@ import org.junit.Before; import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -61,7 +61,7 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -75,7 +75,7 @@ public void getMappedTasks() { .withTaskId(taskId) .build(); - List mappedTasks = + List mappedTasks = new JsonJQTransformTaskMapper(parametersUtils, metadataDAO) .getMappedTasks(taskMapperContext); @@ -99,7 +99,7 @@ public void getMappedTasks_WithoutTaskDef() { String taskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -113,7 +113,7 @@ public void getMappedTasks_WithoutTaskDef() { .withTaskId(taskId) .build(); - List mappedTasks = + List mappedTasks = new JsonJQTransformTaskMapper(parametersUtils, metadataDAO) .getMappedTasks(taskMapperContext); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/KafkaPublishTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/KafkaPublishTaskMapperTest.java index 19c76457a9..f55dc8ab66 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/KafkaPublishTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/KafkaPublishTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,15 +20,15 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; @@ -56,7 +56,7 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); String retriedTaskId = IDGenerator.generate(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef workflowDef = new WorkflowDef(); workflow.setWorkflowDefinition(workflowDef); @@ -73,7 +73,7 @@ public void getMappedTasks() { .build(); // when - List mappedTasks = kafkaTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = kafkaTaskMapper.getMappedTasks(taskMapperContext); // Then assertEquals(1, mappedTasks.size()); @@ -89,7 +89,7 @@ public void getMappedTasks_WithoutTaskDef() { String taskId = IDGenerator.generate(); String retriedTaskId = IDGenerator.generate(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef workflowDef = new WorkflowDef(); workflow.setWorkflowDefinition(workflowDef); @@ -111,7 +111,7 @@ public void getMappedTasks_WithoutTaskDef() { .build(); // when - List mappedTasks = kafkaTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = kafkaTaskMapper.getMappedTasks(taskMapperContext); // Then assertEquals(1, mappedTasks.size()); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/LambdaTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/LambdaTaskMapperTest.java index 6282843a12..ef38f9b065 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/LambdaTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/LambdaTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,15 +17,15 @@ import org.junit.Before; import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -55,7 +55,7 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -68,7 +68,7 @@ public void getMappedTasks() { .withTaskId(taskId) .build(); - List mappedTasks = + List mappedTasks = new LambdaTaskMapper(parametersUtils, metadataDAO) .getMappedTasks(taskMapperContext); @@ -88,7 +88,7 @@ public void getMappedTasks_WithoutTaskDef() { String taskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -101,7 +101,7 @@ public void getMappedTasks_WithoutTaskDef() { .withTaskId(taskId) .build(); - List mappedTasks = + List mappedTasks = new LambdaTaskMapper(parametersUtils, metadataDAO) .getMappedTasks(taskMapperContext); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/SetVariableTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/SetVariableTaskMapperTest.java index 02e800b5ff..c7615b199a 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/SetVariableTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/SetVariableTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,13 +17,13 @@ import org.junit.Assert; import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.utils.IDGenerator; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; public class SetVariableTaskMapperTest { @@ -36,7 +36,7 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -49,7 +49,7 @@ public void getMappedTasks() { .withTaskId(taskId) .build(); - List mappedTasks = new SetVariableTaskMapper().getMappedTasks(taskMapperContext); + List mappedTasks = new SetVariableTaskMapper().getMappedTasks(taskMapperContext); Assert.assertNotNull(mappedTasks); Assert.assertEquals(1, mappedTasks.size()); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/SimpleTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/SimpleTaskMapperTest.java index e2c067e007..91e5e2cc7f 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/SimpleTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/SimpleTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,14 +20,14 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -56,7 +56,7 @@ public void getMappedTasks() { String retriedTaskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -71,7 +71,7 @@ public void getMappedTasks() { .withTaskId(taskId) .build(); - List mappedTasks = simpleTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = simpleTaskMapper.getMappedTasks(taskMapperContext); assertNotNull(mappedTasks); assertEquals(1, mappedTasks.size()); } @@ -86,7 +86,7 @@ public void getMappedTasksException() { String retriedTaskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/SubWorkflowTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/SubWorkflowTaskMapperTest.java index 96b8f4e49b..36e6fc076c 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/SubWorkflowTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/SubWorkflowTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -21,16 +21,16 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.workflow.SubWorkflowParams; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.execution.DeciderService; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_SUB_WORKFLOW; @@ -61,7 +61,7 @@ public void setUp() { public void getMappedTasks() { // Given WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); WorkflowTask taskToSchedule = new WorkflowTask(); SubWorkflowParams subWorkflowParams = new SubWorkflowParams(); @@ -71,7 +71,7 @@ public void getMappedTasks() { taskToSchedule.setStartDelay(30); Map taskInput = new HashMap<>(); Map taskToDomain = - new HashMap() { + new HashMap<>() { { put("*", "unittest"); } @@ -81,7 +81,7 @@ public void getMappedTasks() { subWorkflowParamMap.put("name", "FooWorkFlow"); subWorkflowParamMap.put("version", 2); subWorkflowParamMap.put("taskToDomain", taskToDomain); - when(parametersUtils.getTaskInputV2(anyMap(), any(Workflow.class), any(), any())) + when(parametersUtils.getTaskInputV2(anyMap(), any(WorkflowModel.class), any(), any())) .thenReturn(subWorkflowParamMap); // When @@ -96,14 +96,14 @@ public void getMappedTasks() { .withDeciderService(deciderService) .build(); - List mappedTasks = subWorkflowTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = subWorkflowTaskMapper.getMappedTasks(taskMapperContext); // Then assertFalse(mappedTasks.isEmpty()); assertEquals(1, mappedTasks.size()); - Task subWorkFlowTask = mappedTasks.get(0); - assertEquals(Task.Status.SCHEDULED, subWorkFlowTask.getStatus()); + TaskModel subWorkFlowTask = mappedTasks.get(0); + assertEquals(TaskModel.Status.SCHEDULED, subWorkFlowTask.getStatus()); assertEquals(TASK_TYPE_SUB_WORKFLOW, subWorkFlowTask.getTaskType()); assertEquals(30, subWorkFlowTask.getCallbackAfterSeconds()); assertEquals(taskToDomain, subWorkFlowTask.getInputData().get("subWorkflowTaskToDomain")); @@ -113,11 +113,11 @@ public void getMappedTasks() { public void testTaskToDomain() { // Given WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); WorkflowTask taskToSchedule = new WorkflowTask(); Map taskToDomain = - new HashMap() { + new HashMap<>() { { put("*", "unittest"); } @@ -133,7 +133,7 @@ public void testTaskToDomain() { subWorkflowParamMap.put("name", "FooWorkFlow"); subWorkflowParamMap.put("version", 2); - when(parametersUtils.getTaskInputV2(anyMap(), any(Workflow.class), any(), any())) + when(parametersUtils.getTaskInputV2(anyMap(), any(WorkflowModel.class), any(), any())) .thenReturn(subWorkflowParamMap); // When @@ -148,14 +148,14 @@ public void testTaskToDomain() { .withDeciderService(deciderService) .build(); - List mappedTasks = subWorkflowTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = subWorkflowTaskMapper.getMappedTasks(taskMapperContext); // Then assertFalse(mappedTasks.isEmpty()); assertEquals(1, mappedTasks.size()); - Task subWorkFlowTask = mappedTasks.get(0); - assertEquals(Task.Status.SCHEDULED, subWorkFlowTask.getStatus()); + TaskModel subWorkFlowTask = mappedTasks.get(0); + assertEquals(TaskModel.Status.SCHEDULED, subWorkFlowTask.getStatus()); assertEquals(TASK_TYPE_SUB_WORKFLOW, subWorkFlowTask.getTaskType()); } diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/SwitchTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/SwitchTaskMapperTest.java index 17a98ab371..ddaed22311 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/SwitchTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/SwitchTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -30,18 +30,18 @@ import org.springframework.test.context.junit4.SpringRunner; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.execution.DeciderService; import com.netflix.conductor.core.execution.evaluators.Evaluator; import com.netflix.conductor.core.execution.evaluators.JavascriptEvaluator; import com.netflix.conductor.core.execution.evaluators.ValueParamEvaluator; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -133,7 +133,7 @@ public void getMappedTasks() { WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setSchemaVersion(2); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); Map workflowInput = new HashMap<>(); workflowInput.put("Id", "22"); @@ -147,7 +147,7 @@ public void getMappedTasks() { parametersUtils.getTaskInput( switchTask.getInputParameters(), workflowInstance, null, null); - Task theTask = new Task(); + TaskModel theTask = new TaskModel(); theTask.setReferenceTaskName("Foo"); theTask.setTaskId(IDGenerator.generate()); @@ -166,7 +166,7 @@ public void getMappedTasks() { .build(); // When - List mappedTasks = switchTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = switchTaskMapper.getMappedTasks(taskMapperContext); // Then assertEquals(2, mappedTasks.size()); @@ -202,7 +202,7 @@ public void getMappedTasksWithValueParamEvaluator() { WorkflowDef workflowDef = new WorkflowDef(); workflowDef.setSchemaVersion(2); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); Map workflowInput = new HashMap<>(); workflowInput.put("Id", "even"); @@ -216,7 +216,7 @@ public void getMappedTasksWithValueParamEvaluator() { parametersUtils.getTaskInput( switchTask.getInputParameters(), workflowInstance, null, null); - Task theTask = new Task(); + TaskModel theTask = new TaskModel(); theTask.setReferenceTaskName("Foo"); theTask.setTaskId(IDGenerator.generate()); @@ -235,7 +235,7 @@ public void getMappedTasksWithValueParamEvaluator() { .build(); // When - List mappedTasks = switchTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = switchTaskMapper.getMappedTasks(taskMapperContext); // Then assertEquals(2, mappedTasks.size()); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/TerminateTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/TerminateTaskMapperTest.java index 87e82459b3..9c98594ef6 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/TerminateTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/TerminateTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -18,14 +18,14 @@ import org.junit.Before; import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.mockito.Mockito.mock; @@ -46,7 +46,7 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(workflowDef); TaskMapperContext taskMapperContext = @@ -59,7 +59,7 @@ public void getMappedTasks() { .withTaskId(taskId) .build(); - List mappedTasks = + List mappedTasks = new TerminateTaskMapper(parametersUtils).getMappedTasks(taskMapperContext); Assert.assertNotNull(mappedTasks); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/UserDefinedTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/UserDefinedTaskMapperTest.java index bd5ad3676e..277d33c107 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/UserDefinedTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/UserDefinedTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,16 +20,16 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.exception.TerminateWorkflowException; import com.netflix.conductor.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; @@ -57,7 +57,7 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); String retriedTaskId = IDGenerator.generate(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef workflowDef = new WorkflowDef(); workflow.setWorkflowDefinition(workflowDef); @@ -74,7 +74,7 @@ public void getMappedTasks() { .build(); // when - List mappedTasks = userDefinedTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = userDefinedTaskMapper.getMappedTasks(taskMapperContext); // Then assertEquals(1, mappedTasks.size()); @@ -90,7 +90,7 @@ public void getMappedTasksException() { String taskId = IDGenerator.generate(); String retriedTaskId = IDGenerator.generate(); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef workflowDef = new WorkflowDef(); workflow.setWorkflowDefinition(workflowDef); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/mapper/WaitTaskMapperTest.java b/core/src/test/java/com/netflix/conductor/core/execution/mapper/WaitTaskMapperTest.java index 11feade359..e9af6e7de8 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/mapper/WaitTaskMapperTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/mapper/WaitTaskMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,14 +17,14 @@ import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; 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.core.utils.IDGenerator; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_WAIT; @@ -43,7 +43,7 @@ public void getMappedTasks() { String taskId = IDGenerator.generate(); ParametersUtils parametersUtils = mock(ParametersUtils.class); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef workflowDef = new WorkflowDef(); workflow.setWorkflowDefinition(workflowDef); @@ -60,7 +60,7 @@ public void getMappedTasks() { WaitTaskMapper waitTaskMapper = new WaitTaskMapper(parametersUtils); // When - List mappedTasks = waitTaskMapper.getMappedTasks(taskMapperContext); + List mappedTasks = waitTaskMapper.getMappedTasks(taskMapperContext); // Then assertEquals(1, mappedTasks.size()); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/tasks/EventQueueResolutionTest.java b/core/src/test/java/com/netflix/conductor/core/execution/tasks/EventQueueResolutionTest.java index c8dcbb92f3..8d1ed59afa 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/tasks/EventQueueResolutionTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/tasks/EventQueueResolutionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -23,16 +23,15 @@ import org.springframework.test.context.junit4.SpringRunner; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; 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.core.events.EventQueueProvider; import com.netflix.conductor.core.events.EventQueues; import com.netflix.conductor.core.events.MockQueueProvider; import com.netflix.conductor.core.events.queue.ObservableQueue; import com.netflix.conductor.core.utils.ParametersUtils; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -40,8 +39,8 @@ import static org.junit.Assert.assertNotNull; /** - * Tests the {@link Event#getQueue(Workflow, Task)} method with a real {@link ParametersUtils} - * object. + * Tests the {@link Event#getQueue(WorkflowModel, TaskModel)} method with a real {@link + * ParametersUtils} object. */ @ContextConfiguration(classes = {TestObjectMapperConfiguration.class}) @RunWith(SpringRunner.class) @@ -74,20 +73,20 @@ public void testSinkParam() { WorkflowDef def = new WorkflowDef(); def.setName("wf0"); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); - Task task1 = new Task(); + TaskModel task1 = new TaskModel(); task1.setReferenceTaskName("t1"); task1.getOutputData().put("q", "t1_queue"); workflow.getTasks().add(task1); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setReferenceTaskName("t2"); task2.getOutputData().put("q", "task2_queue"); workflow.getTasks().add(task2); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setReferenceTaskName("event"); task.getInputData().put("sink", sink); task.setTaskType(TaskType.EVENT.name()); @@ -133,17 +132,17 @@ public void testSinkParam() { @Test public void testDynamicSinks() { Event event = new Event(eventQueues, parametersUtils, objectMapper); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(testWorkflowDefinition); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setReferenceTaskName("task0"); task.setTaskId("task_id_0"); - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); task.getInputData().put("sink", "conductor:some_arbitary_queue"); ObservableQueue queue = event.getQueue(workflow, task); - assertEquals(Task.Status.IN_PROGRESS, task.getStatus()); + assertEquals(TaskModel.Status.IN_PROGRESS, task.getStatus()); assertNotNull(queue); assertEquals("testWorkflow:some_arbitary_queue", queue.getName()); assertEquals("testWorkflow:some_arbitary_queue", queue.getURI()); @@ -156,7 +155,7 @@ public void testDynamicSinks() { queue = event.getQueue(workflow, task); assertEquals( "not in progress: " + task.getReasonForIncompletion(), - Task.Status.IN_PROGRESS, + TaskModel.Status.IN_PROGRESS, task.getStatus()); assertNotNull(queue); assertEquals("testWorkflow:task0", queue.getName()); @@ -165,7 +164,7 @@ public void testDynamicSinks() { queue = event.getQueue(workflow, task); assertEquals( "not in progress: " + task.getReasonForIncompletion(), - Task.Status.IN_PROGRESS, + TaskModel.Status.IN_PROGRESS, task.getStatus()); assertNotNull(queue); assertEquals("my_sqs_queue_name", queue.getName()); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/tasks/InlineTest.java b/core/src/test/java/com/netflix/conductor/core/execution/tasks/InlineTest.java index 95f5e29232..c66af8fe1d 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/tasks/InlineTest.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/tasks/InlineTest.java @@ -17,19 +17,19 @@ import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.evaluators.Evaluator; import com.netflix.conductor.core.execution.evaluators.JavascriptEvaluator; import com.netflix.conductor.core.execution.evaluators.ValueParamEvaluator; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; public class InlineTest { - private final Workflow workflow = new Workflow(); + private final WorkflowModel workflow = new WorkflowModel(); private final WorkflowExecutor executor = mock(WorkflowExecutor.class); @Test @@ -41,10 +41,10 @@ public void testInlineTaskValidationFailures() { inputObj.put("expression", ""); inputObj.put("evaluatorType", "value-param"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(inputObj); inline.execute(workflow, task, executor); - assertEquals(Task.Status.FAILED, task.getStatus()); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); assertEquals( "Empty 'expression' in Inline task's input parameters. A non-empty String value must be provided.", task.getReasonForIncompletion()); @@ -54,10 +54,10 @@ public void testInlineTaskValidationFailures() { inputObj.put("expression", "value"); inputObj.put("evaluatorType", ""); - task = new Task(); + task = new TaskModel(); task.getInputData().putAll(inputObj); inline.execute(workflow, task, executor); - assertEquals(Task.Status.FAILED, task.getStatus()); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); assertEquals( "Empty 'evaluatorType' in Inline task's input parameters. A non-empty String value must be provided.", task.getReasonForIncompletion()); @@ -72,11 +72,11 @@ public void testInlineValueParamExpression() { inputObj.put("expression", "value"); inputObj.put("evaluatorType", "value-param"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(inputObj); inline.execute(workflow, task, executor); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertNull(task.getReasonForIncompletion()); assertEquals(101, task.getOutputData().get("result")); @@ -85,15 +85,16 @@ public void testInlineValueParamExpression() { inputObj.put("expression", "value"); inputObj.put("evaluatorType", "value-param"); - task = new Task(); + task = new TaskModel(); task.getInputData().putAll(inputObj); inline.execute(workflow, task, executor); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertNull(task.getReasonForIncompletion()); assertEquals("StringValue", task.getOutputData().get("result")); } + @SuppressWarnings("unchecked") @Test public void testInlineJavascriptExpression() { Inline inline = new Inline(getStringEvaluatorMap()); @@ -105,11 +106,11 @@ public void testInlineJavascriptExpression() { "function e() { if ($.value == 101){return {\"evalResult\": true}} else { return {\"evalResult\": false}}} e();"); inputObj.put("evaluatorType", "javascript"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(inputObj); inline.execute(workflow, task, executor); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertNull(task.getReasonForIncompletion()); assertEquals( true, ((Map) task.getOutputData().get("result")).get("evalResult")); @@ -121,11 +122,11 @@ public void testInlineJavascriptExpression() { "function e() { if ($.value == 'StringValue'){return {\"evalResult\": true}} else { return {\"evalResult\": false}}} e();"); inputObj.put("evaluatorType", "javascript"); - task = new Task(); + task = new TaskModel(); task.getInputData().putAll(inputObj); inline.execute(workflow, task, executor); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertNull(task.getReasonForIncompletion()); assertEquals( true, ((Map) task.getOutputData().get("result")).get("evalResult")); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestDoWhile.java b/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestDoWhile.java index 031a4fb980..77f7ba07f9 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestDoWhile.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestDoWhile.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,21 +20,20 @@ import org.junit.Before; import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.common.metadata.tasks.TaskType; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.config.ConductorProperties; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; import com.netflix.conductor.core.execution.DeciderService; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.listener.WorkflowStatusListener; import com.netflix.conductor.core.metadata.MetadataMapperService; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; import com.netflix.conductor.core.utils.ParametersUtils; import com.netflix.conductor.dao.MetadataDAO; import com.netflix.conductor.dao.QueueDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.service.ExecutionLockService; import static org.junit.Assert.assertEquals; @@ -63,18 +62,19 @@ public class TestDoWhile { ConductorProperties properties; ParametersUtils parametersUtils; SystemTaskRegistry systemTaskRegistry; - private Workflow workflow; - private Task loopTask; + private WorkflowModel workflow; + private TaskModel loopTask; private TaskDef loopTaskDef; private WorkflowTask loopWorkflowTask; - private Task task1; - private Task task2; + private TaskModel task1; + private TaskModel task2; private WorkflowExecutor provider; private DoWhile doWhile; + @SuppressWarnings("unchecked") @Before public void setup() { - workflow = mock(Workflow.class); + workflow = mock(WorkflowModel.class); deciderService = mock(DeciderService.class); metadataDAO = mock(MetadataDAO.class); queueDAO = mock(QueueDAO.class); @@ -107,21 +107,21 @@ public void setup() { WorkflowTask loopWorkflowTask2 = new WorkflowTask(); loopWorkflowTask2.setTaskReferenceName("task2"); loopWorkflowTask2.setName("task2"); - task1 = new Task(); + task1 = new TaskModel(); task1.setWorkflowTask(loopWorkflowTask1); task1.setReferenceTaskName("task1"); - task1.setStatus(Task.Status.COMPLETED); + task1.setStatus(TaskModel.Status.COMPLETED); task1.setTaskType(TaskType.HTTP.name()); task1.setInputData(new HashMap<>()); task1.setIteration(1); - task2 = new Task(); + task2 = new TaskModel(); task2.setWorkflowTask(loopWorkflowTask2); task2.setReferenceTaskName("task2"); - task2.setStatus(Task.Status.COMPLETED); + task2.setStatus(TaskModel.Status.COMPLETED); task2.setTaskType(TaskType.HTTP.name()); task2.setInputData(new HashMap<>()); task2.setIteration(1); - loopTask = new Task(); + loopTask = new TaskModel(); loopTask.setReferenceTaskName("loopTask"); loopTask.setTaskType(TaskType.DO_WHILE.name()); loopTask.setInputData(new HashMap<>()); @@ -145,7 +145,10 @@ public void setup() { doReturn(new HashMap<>()) .when(parametersUtils) .getTaskInputV2( - isA(Map.class), isA(Workflow.class), isA(String.class), isA(TaskDef.class)); + isA(Map.class), + isA(WorkflowModel.class), + isA(String.class), + isA(TaskDef.class)); } @Test @@ -156,34 +159,34 @@ public void testSingleSuccessfulIteration() { boolean success = doWhile.execute(workflow, loopTask, provider); assertTrue(success); verify(provider, times(0)).scheduleNextIteration(loopTask, workflow); - assertEquals(loopTask.getStatus(), Task.Status.COMPLETED); + assertEquals(loopTask.getStatus(), TaskModel.Status.COMPLETED); } @Test public void testSingleFailedIteration() { - task1.setStatus(Task.Status.FAILED); + task1.setStatus(TaskModel.Status.FAILED); String reason = "Test"; task1.setReasonForIncompletion(reason); doReturn(Arrays.asList(task1, task2, loopTask)).when(workflow).getTasks(); boolean success = doWhile.execute(workflow, loopTask, provider); assertTrue(success); - assertEquals(loopTask.getStatus(), Task.Status.FAILED); + assertEquals(loopTask.getStatus(), TaskModel.Status.FAILED); assertNotEquals(reason, loopTask.getReasonForIncompletion()); } @Test public void testInProgress() { - loopTask.setStatus(Task.Status.IN_PROGRESS); - task1.setStatus(Task.Status.IN_PROGRESS); + loopTask.setStatus(TaskModel.Status.IN_PROGRESS); + task1.setStatus(TaskModel.Status.IN_PROGRESS); doReturn(Arrays.asList(task1, task2, loopTask)).when(workflow).getTasks(); boolean success = doWhile.execute(workflow, loopTask, provider); assertFalse(success); - assertSame(loopTask.getStatus(), Status.IN_PROGRESS); + assertSame(loopTask.getStatus(), TaskModel.Status.IN_PROGRESS); } @Test public void testSingleIteration() { - loopTask.setStatus(Task.Status.IN_PROGRESS); + loopTask.setStatus(TaskModel.Status.IN_PROGRESS); doReturn(Arrays.asList(task1, task2)).when(workflow).getTasks(); loopWorkflowTask.setLoopCondition( "if ($.loopTask['iteration'] > 1) { false; } else { true; }"); @@ -192,12 +195,12 @@ public void testSingleIteration() { assertTrue(success); assertEquals(loopTask.getIteration(), 2); verify(provider, times(1)).scheduleNextIteration(loopTask, workflow); - assertSame(loopTask.getStatus(), Status.IN_PROGRESS); + assertSame(loopTask.getStatus(), TaskModel.Status.IN_PROGRESS); } @Test public void testLoopOverTaskOutputInCondition() { - loopTask.setStatus(Task.Status.IN_PROGRESS); + loopTask.setStatus(TaskModel.Status.IN_PROGRESS); Map output = new HashMap<>(); output.put("value", 1); task1.setOutputData(output); @@ -207,7 +210,7 @@ public void testLoopOverTaskOutputInCondition() { boolean success = doWhile.execute(workflow, loopTask, provider); assertTrue(success); verify(provider, times(0)).scheduleNextIteration(loopTask, workflow); - assertSame(loopTask.getStatus(), Status.COMPLETED); + assertSame(loopTask.getStatus(), TaskModel.Status.COMPLETED); } @Test @@ -215,7 +218,7 @@ public void testInputParameterInCondition() { Map output = new HashMap<>(); output.put("value", 1); loopTask.setInputData(output); - loopTask.setStatus(Task.Status.IN_PROGRESS); + loopTask.setStatus(TaskModel.Status.IN_PROGRESS); loopWorkflowTask.setInputParameters(output); doReturn(output) .when(parametersUtils) @@ -230,12 +233,12 @@ public void testInputParameterInCondition() { boolean success = doWhile.execute(workflow, loopTask, provider); assertTrue(success); verify(provider, times(0)).scheduleNextIteration(loopTask, workflow); - assertSame(loopTask.getStatus(), Status.COMPLETED); + assertSame(loopTask.getStatus(), TaskModel.Status.COMPLETED); } @Test public void testSecondIteration() { - loopTask.setStatus(Task.Status.IN_PROGRESS); + loopTask.setStatus(TaskModel.Status.IN_PROGRESS); doReturn(Arrays.asList(task1, task2)).when(workflow).getTasks(); loopWorkflowTask.setLoopCondition( "if ($.loopTask['iteration'] > 1) { false; } else { true; }"); @@ -248,7 +251,7 @@ public void testSecondIteration() { success = doWhile.execute(workflow, loopTask, provider); assertTrue(success); verify(provider, times(1)).scheduleNextIteration(loopTask, workflow); - assertEquals(loopTask.getStatus(), Task.Status.COMPLETED); + assertEquals(loopTask.getStatus(), TaskModel.Status.COMPLETED); } @Test @@ -258,6 +261,6 @@ public void testConditionException() { doNothing().when(provider).scheduleNextIteration(loopTask, workflow); boolean success = doWhile.execute(workflow, loopTask, provider); assertTrue(success); - assertSame(loopTask.getStatus(), Status.FAILED_WITH_TERMINAL_ERROR); + assertSame(loopTask.getStatus(), TaskModel.Status.FAILED_WITH_TERMINAL_ERROR); } } diff --git a/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestLambda.java b/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestLambda.java index dc0d1379a4..b62a355ca4 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestLambda.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestLambda.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,9 +17,9 @@ import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; @@ -27,7 +27,7 @@ /** @author x-ultra */ public class TestLambda { - private final Workflow workflow = new Workflow(); + private final WorkflowModel workflow = new WorkflowModel(); private final WorkflowExecutor executor = mock(WorkflowExecutor.class); @SuppressWarnings({"rawtypes", "unchecked"}) @@ -39,24 +39,24 @@ public void start() { inputObj.put("a", 1); // test for scriptExpression == null - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().put("input", inputObj); lambda.execute(workflow, task, executor); - assertEquals(Task.Status.FAILED, task.getStatus()); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); // test for normal - task = new Task(); + task = new TaskModel(); task.getInputData().put("input", inputObj); task.getInputData().put("scriptExpression", "if ($.input.a==1){return 1}else{return 0 } "); lambda.execute(workflow, task, executor); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertEquals(task.getOutputData().toString(), "{result=1}"); // test for scriptExpression ScriptException - task = new Task(); + task = new TaskModel(); task.getInputData().put("input", inputObj); task.getInputData().put("scriptExpression", "if ($.a.size==1){return 1}else{return 0 } "); lambda.execute(workflow, task, executor); - assertEquals(Task.Status.FAILED, task.getStatus()); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); } } diff --git a/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestSubWorkflow.java b/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestSubWorkflow.java index 3284dde227..f2dad62f9a 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestSubWorkflow.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestSubWorkflow.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -23,11 +23,11 @@ import org.springframework.test.context.junit4.SpringRunner; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; @@ -59,10 +59,10 @@ public void setup() { @Test public void testStartSubWorkflow() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setOutputData(new HashMap<>()); Map inputData = new HashMap<>(); @@ -71,7 +71,7 @@ public void testStartSubWorkflow() { task.setInputData(inputData); String workflowId = "workflow_1"; - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId(workflowId); when(workflowExecutor.startWorkflow( @@ -88,31 +88,31 @@ public void testStartSubWorkflow() { when(workflowExecutor.getWorkflow(anyString(), eq(false))).thenReturn(workflow); - workflow.setStatus(Workflow.WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); subWorkflow.start(workflowInstance, task, workflowExecutor); assertEquals("workflow_1", task.getSubWorkflowId()); - assertEquals(Task.Status.IN_PROGRESS, task.getStatus()); + assertEquals(TaskModel.Status.IN_PROGRESS, task.getStatus()); - workflow.setStatus(Workflow.WorkflowStatus.TERMINATED); + workflow.setStatus(WorkflowModel.Status.TERMINATED); subWorkflow.start(workflowInstance, task, workflowExecutor); assertEquals("workflow_1", task.getSubWorkflowId()); - assertEquals(Task.Status.CANCELED, task.getStatus()); + assertEquals(TaskModel.Status.CANCELED, task.getStatus()); - workflow.setStatus(Workflow.WorkflowStatus.COMPLETED); + workflow.setStatus(WorkflowModel.Status.COMPLETED); subWorkflow.start(workflowInstance, task, workflowExecutor); assertEquals("workflow_1", task.getSubWorkflowId()); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); } @Test public void testStartSubWorkflowQueueFailure() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setOutputData(new HashMap<>()); - task.setStatus(Task.Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); Map inputData = new HashMap<>(); inputData.put("subWorkflowName", "UnitWorkFlow"); @@ -135,19 +135,19 @@ public void testStartSubWorkflowQueueFailure() { subWorkflow.start(workflowInstance, task, workflowExecutor); assertNull("subWorkflowId should be null", task.getSubWorkflowId()); - assertEquals(Task.Status.SCHEDULED, task.getStatus()); + assertEquals(TaskModel.Status.SCHEDULED, task.getStatus()); assertTrue("Output data should be empty", task.getOutputData().isEmpty()); } @Test public void testStartSubWorkflowStartError() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setOutputData(new HashMap<>()); - task.setStatus(Task.Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); Map inputData = new HashMap<>(); inputData.put("subWorkflowName", "UnitWorkFlow"); @@ -171,7 +171,7 @@ public void testStartSubWorkflowStartError() { subWorkflow.start(workflowInstance, task, workflowExecutor); assertNull("subWorkflowId should be null", task.getSubWorkflowId()); - assertEquals(Task.Status.FAILED, task.getStatus()); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); assertEquals(failureReason, task.getReasonForIncompletion()); assertTrue("Output data should be empty", task.getOutputData().isEmpty()); } @@ -179,10 +179,10 @@ public void testStartSubWorkflowStartError() { @Test public void testStartSubWorkflowWithEmptyWorkflowInput() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setOutputData(new HashMap<>()); Map inputData = new HashMap<>(); @@ -212,10 +212,10 @@ public void testStartSubWorkflowWithEmptyWorkflowInput() { @Test public void testStartSubWorkflowWithWorkflowInput() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setOutputData(new HashMap<>()); Map inputData = new HashMap<>(); @@ -246,16 +246,16 @@ public void testStartSubWorkflowWithWorkflowInput() { @Test public void testStartSubWorkflowTaskToDomain() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); Map taskToDomain = - new HashMap() { + new HashMap<>() { { put("*", "unittest"); } }; - Task task = new Task(); + TaskModel task = new TaskModel(); task.setOutputData(new HashMap<>()); Map inputData = new HashMap<>(); @@ -283,10 +283,10 @@ public void testStartSubWorkflowTaskToDomain() { @Test public void testExecuteSubWorkflowWithoutId() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setOutputData(new HashMap<>()); Map inputData = new HashMap<>(); @@ -312,17 +312,17 @@ public void testExecuteSubWorkflowWithoutId() { @Test public void testExecuteWorkflowStatus() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); - Workflow subWorkflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); + WorkflowModel subWorkflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); Map taskToDomain = - new HashMap() { + new HashMap<>() { { put("*", "unittest"); } }; - Task task = new Task(); + TaskModel task = new TaskModel(); Map outputData = new HashMap<>(); task.setOutputData(outputData); task.setSubWorkflowId("sub-workflow-id"); @@ -347,48 +347,48 @@ public void testExecuteWorkflowStatus() { when(workflowExecutor.getWorkflow(eq("sub-workflow-id"), eq(false))) .thenReturn(subWorkflowInstance); - subWorkflowInstance.setStatus(Workflow.WorkflowStatus.RUNNING); + subWorkflowInstance.setStatus(WorkflowModel.Status.RUNNING); assertFalse(subWorkflow.execute(workflowInstance, task, workflowExecutor)); assertNull(task.getStatus()); assertNull(task.getReasonForIncompletion()); - subWorkflowInstance.setStatus(Workflow.WorkflowStatus.PAUSED); + subWorkflowInstance.setStatus(WorkflowModel.Status.PAUSED); assertFalse(subWorkflow.execute(workflowInstance, task, workflowExecutor)); assertNull(task.getStatus()); assertNull(task.getReasonForIncompletion()); - subWorkflowInstance.setStatus(Workflow.WorkflowStatus.COMPLETED); + subWorkflowInstance.setStatus(WorkflowModel.Status.COMPLETED); assertTrue(subWorkflow.execute(workflowInstance, task, workflowExecutor)); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertNull(task.getReasonForIncompletion()); - subWorkflowInstance.setStatus(Workflow.WorkflowStatus.FAILED); + subWorkflowInstance.setStatus(WorkflowModel.Status.FAILED); subWorkflowInstance.setReasonForIncompletion("unit1"); assertTrue(subWorkflow.execute(workflowInstance, task, workflowExecutor)); - assertEquals(Task.Status.FAILED, task.getStatus()); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); assertTrue(task.getReasonForIncompletion().contains("unit1")); - subWorkflowInstance.setStatus(Workflow.WorkflowStatus.TIMED_OUT); + subWorkflowInstance.setStatus(WorkflowModel.Status.TIMED_OUT); subWorkflowInstance.setReasonForIncompletion("unit2"); assertTrue(subWorkflow.execute(workflowInstance, task, workflowExecutor)); - assertEquals(Task.Status.TIMED_OUT, task.getStatus()); + assertEquals(TaskModel.Status.TIMED_OUT, task.getStatus()); assertTrue(task.getReasonForIncompletion().contains("unit2")); - subWorkflowInstance.setStatus(Workflow.WorkflowStatus.TERMINATED); + subWorkflowInstance.setStatus(WorkflowModel.Status.TERMINATED); subWorkflowInstance.setReasonForIncompletion("unit3"); assertTrue(subWorkflow.execute(workflowInstance, task, workflowExecutor)); - assertEquals(Task.Status.CANCELED, task.getStatus()); + assertEquals(TaskModel.Status.CANCELED, task.getStatus()); assertTrue(task.getReasonForIncompletion().contains("unit3")); } @Test public void testCancelWithWorkflowId() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); - Workflow subWorkflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); + WorkflowModel subWorkflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setSubWorkflowId("sub-workflow-id"); Map inputData = new HashMap<>(); @@ -410,20 +410,20 @@ public void testCancelWithWorkflowId() { when(workflowExecutor.getWorkflow(eq("sub-workflow-id"), eq(true))) .thenReturn(subWorkflowInstance); - workflowInstance.setStatus(Workflow.WorkflowStatus.TIMED_OUT); + workflowInstance.setStatus(WorkflowModel.Status.TIMED_OUT); subWorkflow.cancel(workflowInstance, task, workflowExecutor); - assertEquals(Workflow.WorkflowStatus.TERMINATED, subWorkflowInstance.getStatus()); + assertEquals(WorkflowModel.Status.TERMINATED, subWorkflowInstance.getStatus()); } @Test public void testCancelWithoutWorkflowId() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); - Workflow subWorkflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); + WorkflowModel subWorkflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); - Task task = new Task(); + TaskModel task = new TaskModel(); Map outputData = new HashMap<>(); task.setOutputData(outputData); @@ -448,7 +448,7 @@ public void testCancelWithoutWorkflowId() { subWorkflow.cancel(workflowInstance, task, workflowExecutor); - assertEquals(Workflow.WorkflowStatus.RUNNING, subWorkflowInstance.getStatus()); + assertEquals(WorkflowModel.Status.RUNNING, subWorkflowInstance.getStatus()); } @Test @@ -459,13 +459,13 @@ public void testIsAsync() { @Test public void testStartSubWorkflowWithSubWorkflowDefinition() { WorkflowDef workflowDef = new WorkflowDef(); - Workflow workflowInstance = new Workflow(); + WorkflowModel workflowInstance = new WorkflowModel(); workflowInstance.setWorkflowDefinition(workflowDef); WorkflowDef subWorkflowDef = new WorkflowDef(); subWorkflowDef.setName("subWorkflow_1"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setOutputData(new HashMap<>()); Map inputData = new HashMap<>(); diff --git a/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestTerminate.java b/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestTerminate.java index 02fdc5ca4e..7ecf0d9d2a 100644 --- a/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestTerminate.java +++ b/core/src/test/java/com/netflix/conductor/core/execution/tasks/TestTerminate.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -18,9 +18,9 @@ import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import static com.netflix.conductor.core.execution.tasks.Terminate.getTerminationStatusParameter; import static com.netflix.conductor.core.execution.tasks.Terminate.getTerminationWorkflowOutputParameter; @@ -35,54 +35,54 @@ public class TestTerminate { @Test public void should_fail_if_input_status_is_not_valid() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); Terminate terminateTask = new Terminate(); Map input = new HashMap<>(); input.put(getTerminationStatusParameter(), "PAUSED"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(input); terminateTask.execute(workflow, task, executor); - assertEquals(Task.Status.FAILED, task.getStatus()); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); } @Test public void should_fail_if_input_status_is_empty() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); Terminate terminateTask = new Terminate(); Map input = new HashMap<>(); input.put(getTerminationStatusParameter(), ""); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(input); terminateTask.execute(workflow, task, executor); - assertEquals(Task.Status.FAILED, task.getStatus()); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); } @Test public void should_fail_if_input_status_is_null() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); Terminate terminateTask = new Terminate(); Map input = new HashMap<>(); input.put(getTerminationStatusParameter(), null); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(input); terminateTask.execute(workflow, task, executor); - assertEquals(Task.Status.FAILED, task.getStatus()); + assertEquals(TaskModel.Status.FAILED, task.getStatus()); } @Test public void should_complete_workflow_on_terminate_task_success() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); Terminate terminateTask = new Terminate(); workflow.setOutput(Collections.singletonMap("output", "${task1.output.value}")); HashMap expectedOutput = - new HashMap() { + new HashMap<>() { { put("output", "${task0.output.value}"); } @@ -92,21 +92,21 @@ public void should_complete_workflow_on_terminate_task_success() { input.put(getTerminationStatusParameter(), "COMPLETED"); input.put(getTerminationWorkflowOutputParameter(), "${task0.output.value}"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(input); terminateTask.execute(workflow, task, executor); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertEquals(expectedOutput, task.getOutputData()); } @Test public void should_fail_workflow_on_terminate_task_success() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); Terminate terminateTask = new Terminate(); workflow.setOutput(Collections.singletonMap("output", "${task1.output.value}")); HashMap expectedOutput = - new HashMap() { + new HashMap<>() { { put("output", "${task0.output.value}"); } @@ -116,35 +116,35 @@ public void should_fail_workflow_on_terminate_task_success() { input.put(getTerminationStatusParameter(), "FAILED"); input.put(getTerminationWorkflowOutputParameter(), "${task0.output.value}"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(input); terminateTask.execute(workflow, task, executor); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertEquals(expectedOutput, task.getOutputData()); } @Test public void should_fail_workflow_on_terminate_task_success_with_empty_output() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); Terminate terminateTask = new Terminate(); Map input = new HashMap<>(); input.put(getTerminationStatusParameter(), "FAILED"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(input); terminateTask.execute(workflow, task, executor); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); assertTrue(task.getOutputData().isEmpty()); } @Test public void should_fail_workflow_on_terminate_task_success_with_resolved_output() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); Terminate terminateTask = new Terminate(); HashMap expectedOutput = - new HashMap() { + new HashMap<>() { { put("result", 1); } @@ -154,9 +154,9 @@ public void should_fail_workflow_on_terminate_task_success_with_resolved_output( input.put(getTerminationStatusParameter(), "FAILED"); input.put(getTerminationWorkflowOutputParameter(), expectedOutput); - Task task = new Task(); + TaskModel task = new TaskModel(); task.getInputData().putAll(input); terminateTask.execute(workflow, task, executor); - assertEquals(Task.Status.COMPLETED, task.getStatus()); + assertEquals(TaskModel.Status.COMPLETED, task.getStatus()); } } diff --git a/core/src/test/java/com/netflix/conductor/core/reconciliation/TestWorkflowRepairService.java b/core/src/test/java/com/netflix/conductor/core/reconciliation/TestWorkflowRepairService.java index 5e246d21ae..dd7e891d6d 100644 --- a/core/src/test/java/com/netflix/conductor/core/reconciliation/TestWorkflowRepairService.java +++ b/core/src/test/java/com/netflix/conductor/core/reconciliation/TestWorkflowRepairService.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,24 +17,17 @@ import org.junit.Before; import org.junit.Test; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.core.execution.WorkflowExecutor; -import com.netflix.conductor.core.execution.tasks.Decision; -import com.netflix.conductor.core.execution.tasks.SubWorkflow; -import com.netflix.conductor.core.execution.tasks.Switch; -import com.netflix.conductor.core.execution.tasks.SystemTaskRegistry; -import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; +import com.netflix.conductor.core.execution.tasks.*; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.dao.QueueDAO; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_DECISION; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_SUB_WORKFLOW; -import static com.netflix.conductor.common.metadata.tasks.TaskType.TASK_TYPE_SWITCH; +import static com.netflix.conductor.common.metadata.tasks.TaskType.*; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -67,9 +60,9 @@ public void setUp() { @Test public void verifyAndRepairSimpleTaskInScheduledState() { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType("SIMPLE"); - task.setStatus(Task.Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); task.setTaskId("abcd"); task.setCallbackAfterSeconds(60); @@ -83,9 +76,9 @@ public void verifyAndRepairSimpleTaskInScheduledState() { @Test public void verifySimpleTaskInProgressState() { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType("SIMPLE"); - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); task.setTaskId("abcd"); task.setCallbackAfterSeconds(60); @@ -100,9 +93,9 @@ public void verifySimpleTaskInProgressState() { @Test public void verifyAndRepairSystemTask() { String taskType = "TEST_SYS_TASK"; - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType(taskType); - task.setStatus(Task.Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); task.setTaskId("abcd"); task.setCallbackAfterSeconds(60); @@ -116,13 +109,15 @@ public boolean isAsync() { } @Override - public boolean isAsyncComplete(Task task) { + public boolean isAsyncComplete(TaskModel task) { return false; } @Override public void start( - Workflow workflow, Task task, WorkflowExecutor executor) { + WorkflowModel workflow, + TaskModel task, + WorkflowExecutor executor) { super.start(workflow, task, executor); } }); @@ -135,7 +130,7 @@ public void start( // Verify a system task in IN_PROGRESS state can be recovered. reset(queueDAO); - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); assertTrue(workflowRepairService.verifyAndRepairTask(task)); // Verify that a new queue message is pushed for async System task in IN_PROGRESS state that // fails queue contains check. @@ -144,15 +139,15 @@ public void start( @Test public void assertSyncSystemTasksAreNotCheckedAgainstQueue() { - // Return a Decision object to init WorkflowSystemTask registry. + // Return a Switch task object to init WorkflowSystemTask registry. when(systemTaskRegistry.get(TASK_TYPE_DECISION)).thenReturn(new Decision()); when(systemTaskRegistry.isSystemTask(TASK_TYPE_DECISION)).thenReturn(true); when(systemTaskRegistry.get(TASK_TYPE_SWITCH)).thenReturn(new Switch()); when(systemTaskRegistry.isSystemTask(TASK_TYPE_SWITCH)).thenReturn(true); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType(TASK_TYPE_DECISION); - task.setStatus(Task.Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); assertFalse(workflowRepairService.verifyAndRepairTask(task)); // Verify that queue contains is never checked for sync system tasks @@ -160,9 +155,9 @@ public void assertSyncSystemTasksAreNotCheckedAgainstQueue() { // Verify that queue message is never pushed for sync system tasks verify(queueDAO, never()).push(anyString(), anyString(), anyLong()); - task = new Task(); + task = new TaskModel(); task.setTaskType(TASK_TYPE_SWITCH); - task.setStatus(Task.Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); assertFalse(workflowRepairService.verifyAndRepairTask(task)); // Verify that queue contains is never checked for sync system tasks @@ -173,9 +168,9 @@ public void assertSyncSystemTasksAreNotCheckedAgainstQueue() { @Test public void assertAsyncCompleteInProgressSystemTasksAreNotCheckedAgainstQueue() { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType(TASK_TYPE_SUB_WORKFLOW); - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); task.setTaskId("abcd"); task.setCallbackAfterSeconds(60); @@ -192,9 +187,9 @@ public void assertAsyncCompleteInProgressSystemTasksAreNotCheckedAgainstQueue() @Test public void assertAsyncCompleteScheduledSystemTasksAreCheckedAgainstQueue() { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskType(TASK_TYPE_SUB_WORKFLOW); - task.setStatus(Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); task.setTaskId("abcd"); task.setCallbackAfterSeconds(60); @@ -212,7 +207,7 @@ public void assertAsyncCompleteScheduledSystemTasksAreCheckedAgainstQueue() { @Test public void verifyAndRepairParentWorkflow() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowId("abcd"); workflow.setParentWorkflowId("parentWorkflowId"); diff --git a/core/src/test/java/com/netflix/conductor/core/utils/ExternalPayloadStorageUtilsTest.java b/core/src/test/java/com/netflix/conductor/core/utils/ExternalPayloadStorageUtilsTest.java index 186be1d18a..88941e19b3 100644 --- a/core/src/test/java/com/netflix/conductor/core/utils/ExternalPayloadStorageUtilsTest.java +++ b/core/src/test/java/com/netflix/conductor/core/utils/ExternalPayloadStorageUtilsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -30,25 +30,19 @@ import org.springframework.util.unit.DataSize; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; import com.netflix.conductor.common.run.ExternalStorageLocation; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.utils.ExternalPayloadStorage; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.core.exception.TerminateWorkflowException; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.databind.ObjectMapper; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.junit.Assert.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; @ContextConfiguration(classes = {TestObjectMapperConfiguration.class}) @RunWith(SpringRunner.class) @@ -129,7 +123,7 @@ public void testUploadTaskPayload() throws IOException { .when(externalPayloadStorage) .upload(anyString(), any(), anyLong()); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setInputData(payload); externalPayloadStorageUtils.verifyAndUpload( task, ExternalPayloadStorage.PayloadType.TASK_INPUT); @@ -161,7 +155,7 @@ public void testUploadWorkflowPayload() throws IOException { .when(externalPayloadStorage) .upload(anyString(), any(), anyLong()); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); WorkflowDef def = new WorkflowDef(); def.setName("name"); def.setVersion(1); @@ -199,7 +193,7 @@ public void testUploadHelper() { @Test public void testFailTaskWithInputPayload() { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setInputData(new HashMap<>()); expectedException.expect(TerminateWorkflowException.class); @@ -211,7 +205,7 @@ public void testFailTaskWithInputPayload() { @Test public void testFailTaskWithOutputPayload() { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setOutputData(new HashMap<>()); expectedException.expect(TerminateWorkflowException.class); @@ -223,7 +217,7 @@ public void testFailTaskWithOutputPayload() { @Test public void testFailWorkflowWithInputPayload() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setInput(new HashMap<>()); expectedException.expect(TerminateWorkflowException.class); @@ -231,12 +225,12 @@ public void testFailWorkflowWithInputPayload() { workflow, ExternalPayloadStorage.PayloadType.TASK_INPUT, "error"); assertNotNull(workflow); assertTrue(workflow.getInput().isEmpty()); - assertEquals(Workflow.WorkflowStatus.FAILED, workflow.getStatus()); + assertEquals(WorkflowModel.Status.FAILED, workflow.getStatus()); } @Test public void testFailWorkflowWithOutputPayload() { - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setOutput(new HashMap<>()); expectedException.expect(TerminateWorkflowException.class); @@ -244,6 +238,6 @@ public void testFailWorkflowWithOutputPayload() { workflow, ExternalPayloadStorage.PayloadType.TASK_OUTPUT, "error"); assertNotNull(workflow); assertTrue(workflow.getOutput().isEmpty()); - assertEquals(Workflow.WorkflowStatus.FAILED, workflow.getStatus()); + assertEquals(WorkflowModel.Status.FAILED, workflow.getStatus()); } } diff --git a/core/src/test/java/com/netflix/conductor/dao/ExecutionDAOTest.java b/core/src/test/java/com/netflix/conductor/dao/ExecutionDAOTest.java index 408984193e..5133bfa0bc 100644 --- a/core/src/test/java/com/netflix/conductor/dao/ExecutionDAOTest.java +++ b/core/src/test/java/com/netflix/conductor/dao/ExecutionDAOTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -27,17 +27,14 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; 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.core.exception.ApplicationException; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; public abstract class ExecutionDAOTest { @@ -60,9 +57,9 @@ public void testTaskExceedsLimit() { workflowTask.setTaskDefinition(taskDefinition); workflowTask.setTaskDefinition(taskDefinition); - List tasks = new LinkedList<>(); + List tasks = new LinkedList<>(); for (int i = 0; i < 15; i++) { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(i + 1); task.setTaskId("t_" + i); @@ -70,23 +67,23 @@ public void testTaskExceedsLimit() { task.setReferenceTaskName("task1"); task.setTaskDefName("task1"); tasks.add(task); - task.setStatus(Task.Status.SCHEDULED); + task.setStatus(TaskModel.Status.SCHEDULED); task.setWorkflowTask(workflowTask); } getExecutionDAO().createTasks(tasks); assertFalse(getConcurrentExecutionLimitDAO().exceedsLimit(tasks.get(0))); - tasks.get(0).setStatus(Task.Status.IN_PROGRESS); + tasks.get(0).setStatus(TaskModel.Status.IN_PROGRESS); getExecutionDAO().updateTask(tasks.get(0)); - for (Task task : tasks) { + for (TaskModel task : tasks) { assertTrue(getConcurrentExecutionLimitDAO().exceedsLimit(task)); } } @Test public void testCreateTaskException() { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(1); task.setTaskId(UUID.randomUUID().toString()); @@ -104,7 +101,7 @@ public void testCreateTaskException() { @Test public void testCreateTaskException2() { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(1); task.setTaskId(UUID.randomUUID().toString()); @@ -118,11 +115,11 @@ public void testCreateTaskException2() { @Test public void testTaskCreateDups() { - List tasks = new LinkedList<>(); + List tasks = new LinkedList<>(); String workflowId = UUID.randomUUID().toString(); for (int i = 0; i < 3; i++) { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(i + 1); task.setTaskId(workflowId + "_t" + i); @@ -130,12 +127,12 @@ public void testTaskCreateDups() { task.setRetryCount(0); task.setWorkflowInstanceId(workflowId); task.setTaskDefName("task" + i); - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); tasks.add(task); } // Let's insert a retried task - Task task = new Task(); + TaskModel task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(1); task.setTaskId(workflowId + "_t" + 2); @@ -143,11 +140,11 @@ public void testTaskCreateDups() { task.setRetryCount(1); task.setWorkflowInstanceId(workflowId); task.setTaskDefName("task" + 2); - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); tasks.add(task); // Duplicate task! - task = new Task(); + task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(1); task.setTaskId(workflowId + "_t" + 1); @@ -155,10 +152,10 @@ public void testTaskCreateDups() { task.setRetryCount(0); task.setWorkflowInstanceId(workflowId); task.setTaskDefName("task" + 1); - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); tasks.add(task); - List created = getExecutionDAO().createTasks(tasks); + List created = getExecutionDAO().createTasks(tasks); assertEquals(tasks.size() - 1, created.size()); // 1 less Set srcIds = @@ -172,12 +169,12 @@ public void testTaskCreateDups() { assertEquals(srcIds, createdIds); - List pending = getExecutionDAO().getPendingTasksByWorkflow("task0", workflowId); + List pending = getExecutionDAO().getPendingTasksByWorkflow("task0", workflowId); assertNotNull(pending); assertEquals(1, pending.size()); assertTrue(EqualsBuilder.reflectionEquals(tasks.get(0), pending.get(0))); - List found = getExecutionDAO().getTasks(tasks.get(0).getTaskDefName(), null, 1); + List found = getExecutionDAO().getTasks(tasks.get(0).getTaskDefName(), null, 1); assertNotNull(found); assertEquals(1, found.size()); assertTrue(EqualsBuilder.reflectionEquals(tasks.get(0), found.get(0))); @@ -185,11 +182,11 @@ public void testTaskCreateDups() { @Test public void testTaskOps() { - List tasks = new LinkedList<>(); + List tasks = new LinkedList<>(); String workflowId = UUID.randomUUID().toString(); for (int i = 0; i < 3; i++) { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(1); task.setTaskId(workflowId + "_t" + i); @@ -197,12 +194,12 @@ public void testTaskOps() { task.setRetryCount(0); task.setWorkflowInstanceId(workflowId); task.setTaskDefName("testTaskOps" + i); - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); tasks.add(task); } for (int i = 0; i < 3; i++) { - Task task = new Task(); + TaskModel task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(1); task.setTaskId("x" + workflowId + "_t" + i); @@ -210,20 +207,20 @@ public void testTaskOps() { task.setRetryCount(0); task.setWorkflowInstanceId("x" + workflowId); task.setTaskDefName("testTaskOps" + i); - task.setStatus(Task.Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); getExecutionDAO().createTasks(Collections.singletonList(task)); } - List created = getExecutionDAO().createTasks(tasks); + List created = getExecutionDAO().createTasks(tasks); assertEquals(tasks.size(), created.size()); - List pending = + List pending = getExecutionDAO().getPendingTasksForTaskType(tasks.get(0).getTaskDefName()); assertNotNull(pending); assertEquals(2, pending.size()); // Pending list can come in any order. finding the one we are looking for and then // comparing - Task matching = + TaskModel matching = pending.stream() .filter(task -> task.getTaskId().equals(tasks.get(0).getTaskId())) .findAny() @@ -231,15 +228,16 @@ public void testTaskOps() { assertTrue(EqualsBuilder.reflectionEquals(matching, tasks.get(0))); for (int i = 0; i < 3; i++) { - Task found = getExecutionDAO().getTask(workflowId + "_t" + i); + TaskModel found = getExecutionDAO().getTask(workflowId + "_t" + i); assertNotNull(found); found.getOutputData().put("updated", true); - found.setStatus(Task.Status.COMPLETED); + found.setStatus(TaskModel.Status.COMPLETED); getExecutionDAO().updateTask(found); } - List taskIds = tasks.stream().map(Task::getTaskId).collect(Collectors.toList()); - List found = getExecutionDAO().getTasks(taskIds); + List taskIds = + tasks.stream().map(TaskModel::getTaskId).collect(Collectors.toList()); + List found = getExecutionDAO().getTasks(taskIds); assertEquals(taskIds.size(), found.size()); found.forEach( task -> { @@ -258,7 +256,7 @@ public void testPending() { WorkflowDef def = new WorkflowDef(); def.setName("pending_count_test"); - Workflow workflow = createTestWorkflow(); + WorkflowModel workflow = createTestWorkflow(); workflow.setWorkflowDefinition(def); List workflowIds = generateWorkflows(workflow, 10); @@ -275,20 +273,21 @@ public void testPending() { @Test public void complexExecutionTest() { - Workflow workflow = createTestWorkflow(); + WorkflowModel workflow = createTestWorkflow(); int numTasks = workflow.getTasks().size(); String workflowId = getExecutionDAO().createWorkflow(workflow); assertEquals(workflow.getWorkflowId(), workflowId); - List created = getExecutionDAO().createTasks(workflow.getTasks()); + List created = getExecutionDAO().createTasks(workflow.getTasks()); assertEquals(workflow.getTasks().size(), created.size()); - Workflow workflowWithTasks = getExecutionDAO().getWorkflow(workflow.getWorkflowId(), true); + WorkflowModel workflowWithTasks = + getExecutionDAO().getWorkflow(workflow.getWorkflowId(), true); assertEquals(workflowId, workflowWithTasks.getWorkflowId()); assertEquals(numTasks, workflowWithTasks.getTasks().size()); - Workflow found = getExecutionDAO().getWorkflow(workflowId, false); + WorkflowModel found = getExecutionDAO().getWorkflow(workflowId, false); assertTrue(found.getTasks().isEmpty()); workflow.getTasks().clear(); @@ -308,7 +307,7 @@ public void complexExecutionTest() { assertNotNull(running); assertTrue(running.isEmpty()); - workflow.setStatus(Workflow.WorkflowStatus.RUNNING); + workflow.setStatus(WorkflowModel.Status.RUNNING); getExecutionDAO().updateWorkflow(workflow); running = @@ -319,7 +318,7 @@ public void complexExecutionTest() { assertEquals(1, running.size()); assertEquals(workflow.getWorkflowId(), running.get(0)); - List pending = + List pending = getExecutionDAO() .getPendingWorkflowsByType( workflow.getWorkflowName(), workflow.getWorkflowVersion()); @@ -329,7 +328,7 @@ public void complexExecutionTest() { pending.get(0).getTasks().clear(); assertEquals(workflow, pending.get(0)); - workflow.setStatus(Workflow.WorkflowStatus.COMPLETED); + workflow.setStatus(WorkflowModel.Status.COMPLETED); getExecutionDAO().updateWorkflow(workflow); running = getExecutionDAO() @@ -338,7 +337,7 @@ public void complexExecutionTest() { assertNotNull(running); assertTrue(running.isEmpty()); - List bytime = + List bytime = getExecutionDAO() .getWorkflowsByType( workflow.getWorkflowName(), @@ -357,13 +356,13 @@ public void complexExecutionTest() { assertEquals(1, bytime.size()); } - protected Workflow createTestWorkflow() { + protected WorkflowModel createTestWorkflow() { WorkflowDef def = new WorkflowDef(); def.setName("Junit Workflow"); def.setVersion(3); def.setSchemaVersion(2); - Workflow workflow = new Workflow(); + WorkflowModel workflow = new WorkflowModel(); workflow.setWorkflowDefinition(def); workflow.setCorrelationId("correlationX"); workflow.setCreatedBy("junit_tester"); @@ -384,13 +383,13 @@ protected Workflow createTestWorkflow() { workflow.setParentWorkflowTaskId("parentWFTaskId"); workflow.setReasonForIncompletion("missing recipe"); workflow.setReRunFromWorkflowId("re-run from id1"); - workflow.setStartTime(90L); - workflow.setStatus(Workflow.WorkflowStatus.FAILED); + workflow.setCreateTime(90L); + workflow.setStatus(WorkflowModel.Status.FAILED); workflow.setWorkflowId(UUID.randomUUID().toString()); - List tasks = new LinkedList<>(); + List tasks = new LinkedList<>(); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setScheduledTime(1L); task.setSeq(1); task.setTaskId(UUID.randomUUID().toString()); @@ -398,7 +397,7 @@ protected Workflow createTestWorkflow() { task.setWorkflowInstanceId(workflow.getWorkflowId()); task.setTaskDefName("task1"); - Task task2 = new Task(); + TaskModel task2 = new TaskModel(); task2.setScheduledTime(2L); task2.setSeq(2); task2.setTaskId(UUID.randomUUID().toString()); @@ -406,7 +405,7 @@ protected Workflow createTestWorkflow() { task2.setWorkflowInstanceId(workflow.getWorkflowId()); task2.setTaskDefName("task2"); - Task task3 = new Task(); + TaskModel task3 = new TaskModel(); task3.setScheduledTime(2L); task3.setSeq(3); task3.setTaskId(UUID.randomUUID().toString()); @@ -421,18 +420,18 @@ protected Workflow createTestWorkflow() { workflow.setTasks(tasks); workflow.setUpdatedBy("junit_tester"); - workflow.setUpdateTime(800L); + workflow.setUpdatedTime(800L); return workflow; } - protected List generateWorkflows(Workflow base, int count) { + protected List generateWorkflows(WorkflowModel base, int count) { List workflowIds = new ArrayList<>(); for (int i = 0; i < count; i++) { String workflowId = UUID.randomUUID().toString(); base.setWorkflowId(workflowId); base.setCorrelationId("corr001"); - base.setStatus(Workflow.WorkflowStatus.RUNNING); + base.setStatus(WorkflowModel.Status.RUNNING); getExecutionDAO().createWorkflow(base); workflowIds.add(workflowId); } diff --git a/core/src/test/java/com/netflix/conductor/service/ExecutionServiceTest.java b/core/src/test/java/com/netflix/conductor/service/ExecutionServiceTest.java index 3996e8e7e6..e2b7525fb3 100644 --- a/core/src/test/java/com/netflix/conductor/service/ExecutionServiceTest.java +++ b/core/src/test/java/com/netflix/conductor/service/ExecutionServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -31,9 +31,10 @@ import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.common.utils.ExternalPayloadStorage; import com.netflix.conductor.core.config.ConductorProperties; +import com.netflix.conductor.core.dal.ExecutionDAOFacade; +import com.netflix.conductor.core.dal.ModelMapper; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.tasks.SystemTaskRegistry; -import com.netflix.conductor.core.orchestration.ExecutionDAOFacade; import com.netflix.conductor.dao.QueueDAO; import static junit.framework.TestCase.assertEquals; @@ -43,6 +44,7 @@ public class ExecutionServiceTest { @Mock private WorkflowExecutor workflowExecutor; + @Mock private ModelMapper modelMapper; @Mock private ExecutionDAOFacade executionDAOFacade; @Mock private QueueDAO queueDAO; @Mock private ConductorProperties conductorProperties; @@ -64,6 +66,7 @@ public void setup() { executionService = new ExecutionService( workflowExecutor, + modelMapper, executionDAOFacade, queueDAO, conductorProperties, @@ -92,9 +95,9 @@ public void workflowSearchTest() { 2, Arrays.asList( workflow1.getWorkflowId(), workflow2.getWorkflowId()))); - when(executionDAOFacade.getWorkflowById(workflow1.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow1.getWorkflowId(), false)) .thenReturn(workflow1); - when(executionDAOFacade.getWorkflowById(workflow2.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow2.getWorkflowId(), false)) .thenReturn(workflow2); SearchResult searchResult = executionService.search("query", "*", 0, 2, sort); @@ -112,9 +115,9 @@ public void workflowSearchExceptionTest() { 2, Arrays.asList( workflow1.getWorkflowId(), workflow2.getWorkflowId()))); - when(executionDAOFacade.getWorkflowById(workflow1.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow1.getWorkflowId(), false)) .thenReturn(workflow1); - when(executionDAOFacade.getWorkflowById(workflow2.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow2.getWorkflowId(), false)) .thenThrow(new RuntimeException()); SearchResult searchResult = executionService.search("query", "*", 0, 2, sort); @@ -131,9 +134,9 @@ public void workflowSearchV2Test() { 2, Arrays.asList( workflow1.getWorkflowId(), workflow2.getWorkflowId()))); - when(executionDAOFacade.getWorkflowById(workflow1.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow1.getWorkflowId(), false)) .thenReturn(workflow1); - when(executionDAOFacade.getWorkflowById(workflow2.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow2.getWorkflowId(), false)) .thenReturn(workflow2); SearchResult searchResult = executionService.searchV2("query", "*", 0, 2, sort); assertEquals(2, searchResult.getTotalHits()); @@ -148,9 +151,9 @@ public void workflowSearchV2ExceptionTest() { 2, Arrays.asList( workflow1.getWorkflowId(), workflow2.getWorkflowId()))); - when(executionDAOFacade.getWorkflowById(workflow1.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow1.getWorkflowId(), false)) .thenReturn(workflow1); - when(executionDAOFacade.getWorkflowById(workflow2.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow2.getWorkflowId(), false)) .thenThrow(new RuntimeException()); SearchResult searchResult = executionService.searchV2("query", "*", 0, 2, sort); assertEquals(1, searchResult.getTotalHits()); @@ -165,11 +168,11 @@ public void workflowSearchByTasksTest() { 2, Arrays.asList( taskWorkflow1.getTaskId(), taskWorkflow2.getTaskId()))); - when(executionDAOFacade.getTaskById(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); - when(executionDAOFacade.getTaskById(taskWorkflow2.getTaskId())).thenReturn(taskWorkflow2); - when(executionDAOFacade.getWorkflowById(workflow1.getWorkflowId(), false)) + when(executionDAOFacade.getTask(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); + when(executionDAOFacade.getTask(taskWorkflow2.getTaskId())).thenReturn(taskWorkflow2); + when(executionDAOFacade.getWorkflow(workflow1.getWorkflowId(), false)) .thenReturn(workflow1); - when(executionDAOFacade.getWorkflowById(workflow2.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow2.getWorkflowId(), false)) .thenReturn(workflow2); SearchResult searchResult = executionService.searchWorkflowByTasks("query", "*", 0, 2, sort); @@ -187,10 +190,10 @@ public void workflowSearchByTasksExceptionTest() { 2, Arrays.asList( taskWorkflow1.getTaskId(), taskWorkflow2.getTaskId()))); - when(executionDAOFacade.getTaskById(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); - when(executionDAOFacade.getTaskById(taskWorkflow2.getTaskId())) + when(executionDAOFacade.getTask(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); + when(executionDAOFacade.getTask(taskWorkflow2.getTaskId())) .thenThrow(new RuntimeException()); - when(executionDAOFacade.getWorkflowById(workflow1.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow1.getWorkflowId(), false)) .thenReturn(workflow1); SearchResult searchResult = executionService.searchWorkflowByTasks("query", "*", 0, 2, sort); @@ -207,11 +210,11 @@ public void workflowSearchByTasksV2Test() { 2, Arrays.asList( taskWorkflow1.getTaskId(), taskWorkflow2.getTaskId()))); - when(executionDAOFacade.getTaskById(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); - when(executionDAOFacade.getTaskById(taskWorkflow2.getTaskId())).thenReturn(taskWorkflow2); - when(executionDAOFacade.getWorkflowById(workflow1.getWorkflowId(), false)) + when(executionDAOFacade.getTask(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); + when(executionDAOFacade.getTask(taskWorkflow2.getTaskId())).thenReturn(taskWorkflow2); + when(executionDAOFacade.getWorkflow(workflow1.getWorkflowId(), false)) .thenReturn(workflow1); - when(executionDAOFacade.getWorkflowById(workflow2.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow2.getWorkflowId(), false)) .thenReturn(workflow2); SearchResult searchResult = executionService.searchWorkflowByTasksV2("query", "*", 0, 2, sort); @@ -227,10 +230,10 @@ public void workflowSearchByTasksV2ExceptionTest() { 2, Arrays.asList( taskWorkflow1.getTaskId(), taskWorkflow2.getTaskId()))); - when(executionDAOFacade.getTaskById(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); - when(executionDAOFacade.getTaskById(taskWorkflow2.getTaskId())) + when(executionDAOFacade.getTask(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); + when(executionDAOFacade.getTask(taskWorkflow2.getTaskId())) .thenThrow(new RuntimeException()); - when(executionDAOFacade.getWorkflowById(workflow1.getWorkflowId(), false)) + when(executionDAOFacade.getWorkflow(workflow1.getWorkflowId(), false)) .thenReturn(workflow1); SearchResult searchResult = executionService.searchWorkflowByTasksV2("query", "*", 0, 2, sort); @@ -243,8 +246,8 @@ public void TaskSearchTest() { List taskList = Arrays.asList(taskWorkflow1.getTaskId(), taskWorkflow2.getTaskId()); when(executionDAOFacade.searchTasks("query", "*", 0, 2, sort)) .thenReturn(new SearchResult<>(2, taskList)); - when(executionDAOFacade.getTaskById(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); - when(executionDAOFacade.getTaskById(taskWorkflow2.getTaskId())).thenReturn(taskWorkflow2); + when(executionDAOFacade.getTask(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); + when(executionDAOFacade.getTask(taskWorkflow2.getTaskId())).thenReturn(taskWorkflow2); SearchResult searchResult = executionService.getSearchTasks("query", "*", 0, 2, "Sort"); assertEquals(2, searchResult.getTotalHits()); @@ -258,8 +261,8 @@ public void TaskSearchExceptionTest() { List taskList = Arrays.asList(taskWorkflow1.getTaskId(), taskWorkflow2.getTaskId()); when(executionDAOFacade.searchTasks("query", "*", 0, 2, sort)) .thenReturn(new SearchResult<>(2, taskList)); - when(executionDAOFacade.getTaskById(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); - when(executionDAOFacade.getTaskById(taskWorkflow2.getTaskId())) + when(executionDAOFacade.getTask(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); + when(executionDAOFacade.getTask(taskWorkflow2.getTaskId())) .thenThrow(new RuntimeException()); SearchResult searchResult = executionService.getSearchTasks("query", "*", 0, 2, "Sort"); @@ -276,8 +279,8 @@ public void TaskSearchV2Test() { 2, Arrays.asList( taskWorkflow1.getTaskId(), taskWorkflow2.getTaskId()))); - when(executionDAOFacade.getTaskById(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); - when(executionDAOFacade.getTaskById(taskWorkflow2.getTaskId())).thenReturn(taskWorkflow2); + when(executionDAOFacade.getTask(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); + when(executionDAOFacade.getTask(taskWorkflow2.getTaskId())).thenReturn(taskWorkflow2); SearchResult searchResult = executionService.getSearchTasksV2("query", "*", 0, 2, "Sort"); assertEquals(2, searchResult.getTotalHits()); @@ -292,8 +295,8 @@ public void TaskSearchV2ExceptionTest() { 2, Arrays.asList( taskWorkflow1.getTaskId(), taskWorkflow2.getTaskId()))); - when(executionDAOFacade.getTaskById(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); - when(executionDAOFacade.getTaskById(taskWorkflow2.getTaskId())) + when(executionDAOFacade.getTask(taskWorkflow1.getTaskId())).thenReturn(taskWorkflow1); + when(executionDAOFacade.getTask(taskWorkflow2.getTaskId())) .thenThrow(new RuntimeException()); SearchResult searchResult = executionService.getSearchTasksV2("query", "*", 0, 2, "Sort"); diff --git a/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchConditions.java b/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchConditions.java index 2b3dbb3ffc..e8edae2188 100644 --- a/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchConditions.java +++ b/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchConditions.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchProperties.java b/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchProperties.java index f8b711a627..fc7340be15 100644 --- a/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchProperties.java +++ b/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchV6Configuration.java b/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchV6Configuration.java index 5ed23ac950..fcc267f713 100644 --- a/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchV6Configuration.java +++ b/es6-persistence/src/main/java/com/netflix/conductor/es6/config/ElasticSearchV6Configuration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/es6-persistence/src/main/java/com/netflix/conductor/es6/dao/index/ElasticSearchDAOV6.java b/es6-persistence/src/main/java/com/netflix/conductor/es6/dao/index/ElasticSearchDAOV6.java index 4aebdc5db9..0b36f01f9e 100644 --- a/es6-persistence/src/main/java/com/netflix/conductor/es6/dao/index/ElasticSearchDAOV6.java +++ b/es6-persistence/src/main/java/com/netflix/conductor/es6/dao/index/ElasticSearchDAOV6.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -16,20 +16,8 @@ import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.*; +import java.util.concurrent.*; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -71,11 +59,9 @@ import com.netflix.conductor.annotations.Trace; import com.netflix.conductor.common.metadata.events.EventExecution; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.run.SearchResult; import com.netflix.conductor.common.run.TaskSummary; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.common.utils.RetryUtil; import com.netflix.conductor.core.events.queue.Message; @@ -365,12 +351,11 @@ private void addTypeMapping(String indexName, String type, String sourcePath) { } @Override - public void indexWorkflow(Workflow workflow) { + public void indexWorkflow(WorkflowSummary workflow) { try { long startTime = Instant.now().toEpochMilli(); String id = workflow.getWorkflowId(); - WorkflowSummary summary = new WorkflowSummary(workflow); - byte[] doc = objectMapper.writeValueAsBytes(summary); + byte[] doc = objectMapper.writeValueAsBytes(workflow); String docType = StringUtils.isBlank(docTypeOverride) ? WORKFLOW_DOC_TYPE : docTypeOverride; @@ -399,17 +384,16 @@ public void indexWorkflow(Workflow workflow) { } @Override - public CompletableFuture asyncIndexWorkflow(Workflow workflow) { + public CompletableFuture asyncIndexWorkflow(WorkflowSummary workflow) { return CompletableFuture.runAsync(() -> indexWorkflow(workflow), executorService); } @Override - public void indexTask(Task task) { + public void indexTask(TaskSummary task) { try { long startTime = Instant.now().toEpochMilli(); String id = task.getTaskId(); - TaskSummary summary = new TaskSummary(task); - byte[] doc = objectMapper.writeValueAsBytes(summary); + byte[] doc = objectMapper.writeValueAsBytes(task); String docType = StringUtils.isBlank(docTypeOverride) ? TASK_DOC_TYPE : docTypeOverride; UpdateRequest req = new UpdateRequest(taskIndexName, docType, id); @@ -421,7 +405,7 @@ public void indexTask(Task task) { "Time taken {} for indexing task:{} in workflow: {}", endTime - startTime, task.getTaskId(), - task.getWorkflowInstanceId()); + task.getWorkflowId()); Monitors.recordESIndexTime("index_task", TASK_DOC_TYPE, endTime - startTime); Monitors.recordWorkerQueueSize( "indexQueue", ((ThreadPoolExecutor) executorService).getQueue().size()); @@ -431,7 +415,7 @@ public void indexTask(Task task) { } @Override - public CompletableFuture asyncIndexTask(Task task) { + public CompletableFuture asyncIndexTask(TaskSummary task) { return CompletableFuture.runAsync(() -> indexTask(task), executorService); } diff --git a/es6-persistence/src/main/java/com/netflix/conductor/es6/dao/index/ElasticSearchRestDAOV6.java b/es6-persistence/src/main/java/com/netflix/conductor/es6/dao/index/ElasticSearchRestDAOV6.java index 1e1e41c3fa..2e2083ea43 100644 --- a/es6-persistence/src/main/java/com/netflix/conductor/es6/dao/index/ElasticSearchRestDAOV6.java +++ b/es6-persistence/src/main/java/com/netflix/conductor/es6/dao/index/ElasticSearchRestDAOV6.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,21 +17,8 @@ import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.*; +import java.util.concurrent.*; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -59,12 +46,7 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.ResponseException; -import org.elasticsearch.client.RestClient; -import org.elasticsearch.client.RestClientBuilder; -import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.*; import org.elasticsearch.client.core.CountRequest; import org.elasticsearch.client.core.CountResponse; import org.elasticsearch.common.xcontent.XContentType; @@ -80,11 +62,9 @@ import com.netflix.conductor.annotations.Trace; import com.netflix.conductor.common.metadata.events.EventExecution; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.run.SearchResult; import com.netflix.conductor.common.run.TaskSummary; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.common.utils.RetryUtil; import com.netflix.conductor.core.events.queue.Message; @@ -463,12 +443,11 @@ public boolean doesResourceNotExist(final String resourcePath) throws IOExceptio } @Override - public void indexWorkflow(Workflow workflow) { + public void indexWorkflow(WorkflowSummary workflow) { try { long startTime = Instant.now().toEpochMilli(); String workflowId = workflow.getWorkflowId(); - WorkflowSummary summary = new WorkflowSummary(workflow); - byte[] docBytes = objectMapper.writeValueAsBytes(summary); + byte[] docBytes = objectMapper.writeValueAsBytes(workflow); String docType = StringUtils.isBlank(docTypeOverride) ? WORKFLOW_DOC_TYPE : docTypeOverride; @@ -502,25 +481,24 @@ public void indexWorkflow(Workflow workflow) { } @Override - public CompletableFuture asyncIndexWorkflow(Workflow workflow) { + public CompletableFuture asyncIndexWorkflow(WorkflowSummary workflow) { return CompletableFuture.runAsync(() -> indexWorkflow(workflow), executorService); } @Override - public void indexTask(Task task) { + public void indexTask(TaskSummary task) { try { long startTime = Instant.now().toEpochMilli(); String taskId = task.getTaskId(); - TaskSummary summary = new TaskSummary(task); String docType = StringUtils.isBlank(docTypeOverride) ? TASK_DOC_TYPE : docTypeOverride; - indexObject(taskIndexName, docType, taskId, summary); + indexObject(taskIndexName, docType, taskId, task); long endTime = Instant.now().toEpochMilli(); LOGGER.debug( "Time taken {} for indexing task:{} in workflow: {}", endTime - startTime, taskId, - task.getWorkflowInstanceId()); + task.getWorkflowId()); Monitors.recordESIndexTime("index_task", TASK_DOC_TYPE, endTime - startTime); Monitors.recordWorkerQueueSize( "indexQueue", ((ThreadPoolExecutor) executorService).getQueue().size()); @@ -530,7 +508,7 @@ public void indexTask(Task task) { } @Override - public CompletableFuture asyncIndexTask(Task task) { + public CompletableFuture asyncIndexTask(TaskSummary task) { return CompletableFuture.runAsync(() -> indexTask(task), executorService); } diff --git a/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchDAOV6.java b/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchDAOV6.java index 6275b33c7a..fc6517be7c 100644 --- a/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchDAOV6.java +++ b/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchDAOV6.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -13,13 +13,7 @@ package com.netflix.conductor.es6.dao.index; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ExecutionException; import java.util.function.Supplier; @@ -30,10 +24,9 @@ import com.netflix.conductor.common.metadata.events.EventExecution; import com.netflix.conductor.common.metadata.events.EventHandler; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.run.TaskSummary; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.common.run.Workflow.WorkflowStatus; import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.es6.utils.TestUtils; @@ -106,27 +99,23 @@ private boolean doesMappingExist(final String index, final String mappingName) { @Test public void shouldIndexWorkflow() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - + WorkflowSummary workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); indexDAO.indexWorkflow(workflow); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + assertWorkflowSummary(workflow.getWorkflowId(), workflow); } @Test public void shouldIndexWorkflowAsync() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - + WorkflowSummary workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); indexDAO.asyncIndexWorkflow(workflow).get(); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + assertWorkflowSummary(workflow.getWorkflowId(), workflow); } @Test public void shouldRemoveWorkflow() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); + WorkflowSummary workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); indexDAO.indexWorkflow(workflow); // wait for workflow to be indexed @@ -142,7 +131,7 @@ public void shouldRemoveWorkflow() { @Test public void shouldAsyncRemoveWorkflow() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); + WorkflowSummary workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); indexDAO.indexWorkflow(workflow); // wait for workflow to be indexed @@ -158,63 +147,52 @@ public void shouldAsyncRemoveWorkflow() throws Exception { @Test public void shouldUpdateWorkflow() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - + WorkflowSummary workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); indexDAO.indexWorkflow(workflow); indexDAO.updateWorkflow( workflow.getWorkflowId(), new String[] {"status"}, - new Object[] {Workflow.WorkflowStatus.COMPLETED}); + new Object[] {WorkflowStatus.COMPLETED}); - summary.setStatus(Workflow.WorkflowStatus.COMPLETED); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + workflow.setStatus(WorkflowStatus.COMPLETED); + assertWorkflowSummary(workflow.getWorkflowId(), workflow); } @Test public void shouldAsyncUpdateWorkflow() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - + WorkflowSummary workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); indexDAO.indexWorkflow(workflow); indexDAO.asyncUpdateWorkflow( workflow.getWorkflowId(), new String[] {"status"}, - new Object[] {Workflow.WorkflowStatus.FAILED}) + new Object[] {WorkflowStatus.FAILED}) .get(); - summary.setStatus(Workflow.WorkflowStatus.FAILED); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + workflow.setStatus(WorkflowStatus.FAILED); + assertWorkflowSummary(workflow.getWorkflowId(), workflow); } @Test public void shouldIndexTask() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - Task task = workflow.getTasks().get(0); + TaskSummary taskSummary = TestUtils.loadTaskSnapshot(objectMapper, "task_summary"); + indexDAO.indexTask(taskSummary); - TaskSummary summary = new TaskSummary(task); + List tasks = tryFindResults(() -> searchTasks(taskSummary)); - indexDAO.indexTask(task); - - List tasks = tryFindResults(() -> searchTasks(workflow)); - - assertEquals(summary.getTaskId(), tasks.get(0)); + assertEquals(taskSummary.getTaskId(), tasks.get(0)); } @Test public void shouldIndexTaskAsync() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - Task task = workflow.getTasks().get(0); - - TaskSummary summary = new TaskSummary(task); + TaskSummary taskSummary = TestUtils.loadTaskSnapshot(objectMapper, "task_summary"); - indexDAO.asyncIndexTask(task).get(); + indexDAO.asyncIndexTask(taskSummary).get(); - List tasks = tryFindResults(() -> searchTasks(workflow)); + List tasks = tryFindResults(() -> searchTasks(taskSummary)); - assertEquals(summary.getTaskId(), tasks.get(0)); + assertEquals(taskSummary.getTaskId(), tasks.get(0)); } @Test @@ -322,7 +300,8 @@ public void shouldAddIndexPrefixToIndexTemplate() throws Exception { public void shouldCountWorkflows() { int counts = 1100; for (int i = 0; i < counts; i++) { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); + WorkflowSummary workflow = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); indexDAO.indexWorkflow(workflow); } @@ -402,10 +381,10 @@ private List searchWorkflows(String workflowId) { .getResults(); } - private List searchTasks(Workflow workflow) { + private List searchTasks(TaskSummary taskSummary) { return indexDAO.searchTasks( "", - "workflowId:\"" + workflow.getWorkflowId() + "\"", + "workflowId:\"" + taskSummary.getWorkflowId() + "\"", 0, 100, Collections.emptyList()) diff --git a/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchDAOV6Batch.java b/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchDAOV6Batch.java index 8384382117..8a1f14ef95 100644 --- a/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchDAOV6Batch.java +++ b/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchDAOV6Batch.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -18,8 +18,11 @@ import org.junit.Test; import org.springframework.test.context.TestPropertySource; -import com.netflix.conductor.common.metadata.tasks.Task; +import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.run.SearchResult; +import com.netflix.conductor.common.run.TaskSummary; + +import com.fasterxml.jackson.core.JsonProcessingException; import static org.awaitility.Awaitility.await; import static org.junit.Assert.assertEquals; @@ -31,24 +34,28 @@ public class TestElasticSearchDAOV6Batch extends ElasticSearchDaoBaseTest { @Test public void indexTaskWithBatchSizeTwo() { String correlationId = "some-correlation-id"; + TaskSummary taskSummary = new TaskSummary(); + taskSummary.setTaskId("some-task-id"); + taskSummary.setWorkflowId("some-workflow-instance-id"); + taskSummary.setTaskType("some-task-type"); + taskSummary.setStatus(Status.FAILED); + try { + taskSummary.setInput( + objectMapper.writeValueAsString( + new HashMap() { + { + put("input_key", "input_value"); + } + })); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + taskSummary.setCorrelationId(correlationId); + taskSummary.setTaskDefName("some-task-def-name"); + taskSummary.setReasonForIncompletion("some-failure-reason"); - Task task = new Task(); - task.setTaskId("some-task-id"); - task.setWorkflowInstanceId("some-workflow-instance-id"); - task.setTaskType("some-task-type"); - task.setStatus(Task.Status.FAILED); - task.setInputData( - new HashMap() { - { - put("input_key", "input_value"); - } - }); - task.setCorrelationId(correlationId); - task.setTaskDefName("some-task-def-name"); - task.setReasonForIncompletion("some-failure-reason"); - - indexDAO.indexTask(task); - indexDAO.indexTask(task); + indexDAO.indexTask(taskSummary); + indexDAO.indexTask(taskSummary); await().atMost(5, TimeUnit.SECONDS) .untilAsserted( diff --git a/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchRestDAOV6.java b/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchRestDAOV6.java index 0677f534f0..50bcd5a6f4 100644 --- a/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchRestDAOV6.java +++ b/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchRestDAOV6.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -27,10 +27,9 @@ import com.netflix.conductor.common.metadata.events.EventExecution; import com.netflix.conductor.common.metadata.events.EventHandler; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.run.TaskSummary; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.common.run.Workflow.WorkflowStatus; import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.es6.utils.TestUtils; @@ -91,115 +90,107 @@ public void assertInitialSetup() throws IOException { @Test public void shouldIndexWorkflow() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); - indexDAO.indexWorkflow(workflow); - - assertWorkflowSummary(workflow.getWorkflowId(), summary); + assertWorkflowSummary(workflowSummary.getWorkflowId(), workflowSummary); } @Test public void shouldIndexWorkflowAsync() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - - indexDAO.asyncIndexWorkflow(workflow).get(); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.asyncIndexWorkflow(workflowSummary).get(); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + assertWorkflowSummary(workflowSummary.getWorkflowId(), workflowSummary); } @Test public void shouldRemoveWorkflow() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); // wait for workflow to be indexed - List workflows = tryFindResults(() -> searchWorkflows(workflow.getWorkflowId()), 1); + List workflows = + tryFindResults(() -> searchWorkflows(workflowSummary.getWorkflowId()), 1); assertEquals(1, workflows.size()); - indexDAO.removeWorkflow(workflow.getWorkflowId()); + indexDAO.removeWorkflow(workflowSummary.getWorkflowId()); - workflows = tryFindResults(() -> searchWorkflows(workflow.getWorkflowId()), 0); + workflows = tryFindResults(() -> searchWorkflows(workflowSummary.getWorkflowId()), 0); assertTrue("Workflow was not removed.", workflows.isEmpty()); } @Test public void shouldAsyncRemoveWorkflow() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); // wait for workflow to be indexed - List workflows = tryFindResults(() -> searchWorkflows(workflow.getWorkflowId()), 1); + List workflows = + tryFindResults(() -> searchWorkflows(workflowSummary.getWorkflowId()), 1); assertEquals(1, workflows.size()); - indexDAO.asyncRemoveWorkflow(workflow.getWorkflowId()).get(); + indexDAO.asyncRemoveWorkflow(workflowSummary.getWorkflowId()).get(); - workflows = tryFindResults(() -> searchWorkflows(workflow.getWorkflowId()), 0); + workflows = tryFindResults(() -> searchWorkflows(workflowSummary.getWorkflowId()), 0); assertTrue("Workflow was not removed.", workflows.isEmpty()); } @Test public void shouldUpdateWorkflow() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); indexDAO.updateWorkflow( - workflow.getWorkflowId(), + workflowSummary.getWorkflowId(), new String[] {"status"}, - new Object[] {Workflow.WorkflowStatus.COMPLETED}); + new Object[] {WorkflowStatus.COMPLETED}); - summary.setStatus(Workflow.WorkflowStatus.COMPLETED); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + workflowSummary.setStatus(WorkflowStatus.COMPLETED); + assertWorkflowSummary(workflowSummary.getWorkflowId(), workflowSummary); } @Test public void shouldAsyncUpdateWorkflow() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); indexDAO.asyncUpdateWorkflow( - workflow.getWorkflowId(), + workflowSummary.getWorkflowId(), new String[] {"status"}, - new Object[] {Workflow.WorkflowStatus.FAILED}) + new Object[] {WorkflowStatus.FAILED}) .get(); - summary.setStatus(Workflow.WorkflowStatus.FAILED); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + workflowSummary.setStatus(WorkflowStatus.FAILED); + assertWorkflowSummary(workflowSummary.getWorkflowId(), workflowSummary); } @Test public void shouldIndexTask() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - Task task = workflow.getTasks().get(0); + TaskSummary taskSummary = TestUtils.loadTaskSnapshot(objectMapper, "task_summary"); + indexDAO.indexTask(taskSummary); - TaskSummary summary = new TaskSummary(task); + List tasks = tryFindResults(() -> searchTasks(taskSummary)); - indexDAO.indexTask(task); - - List tasks = tryFindResults(() -> searchTasks(workflow)); - - assertEquals(summary.getTaskId(), tasks.get(0)); + assertEquals(taskSummary.getTaskId(), tasks.get(0)); } @Test public void shouldIndexTaskAsync() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - Task task = workflow.getTasks().get(0); - - TaskSummary summary = new TaskSummary(task); - - indexDAO.asyncIndexTask(task).get(); + TaskSummary taskSummary = TestUtils.loadTaskSnapshot(objectMapper, "task_summary"); + indexDAO.asyncIndexTask(taskSummary).get(); - List tasks = tryFindResults(() -> searchTasks(workflow)); + List tasks = tryFindResults(() -> searchTasks(taskSummary)); - assertEquals(summary.getTaskId(), tasks.get(0)); + assertEquals(taskSummary.getTaskId(), tasks.get(0)); } @Test @@ -307,8 +298,9 @@ public void shouldAddIndexPrefixToIndexTemplate() throws Exception { public void shouldCountWorkflows() { int counts = 1100; for (int i = 0; i < counts; i++) { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); } // wait for workflow to be indexed @@ -399,10 +391,10 @@ private List searchWorkflows(String workflowName, String status) { .getResults(); } - private List searchTasks(Workflow workflow) { + private List searchTasks(TaskSummary taskSummary) { return indexDAO.searchTasks( "", - "workflowId:\"" + workflow.getWorkflowId() + "\"", + "workflowId:\"" + taskSummary.getWorkflowId() + "\"", 0, 100, Collections.emptyList()) diff --git a/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchRestDAOV6Batch.java b/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchRestDAOV6Batch.java index 91f6fea5ef..98f503923c 100644 --- a/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchRestDAOV6Batch.java +++ b/es6-persistence/src/test/java/com/netflix/conductor/es6/dao/index/TestElasticSearchRestDAOV6Batch.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -18,8 +18,11 @@ import org.junit.Test; import org.springframework.test.context.TestPropertySource; -import com.netflix.conductor.common.metadata.tasks.Task; +import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.run.SearchResult; +import com.netflix.conductor.common.run.TaskSummary; + +import com.fasterxml.jackson.core.JsonProcessingException; import static org.awaitility.Awaitility.await; import static org.junit.Assert.assertEquals; @@ -31,24 +34,28 @@ public class TestElasticSearchRestDAOV6Batch extends ElasticSearchRestDaoBaseTes @Test public void indexTaskWithBatchSizeTwo() { String correlationId = "some-correlation-id"; + TaskSummary taskSummary = new TaskSummary(); + taskSummary.setTaskId("some-task-id"); + taskSummary.setWorkflowId("some-workflow-instance-id"); + taskSummary.setTaskType("some-task-type"); + taskSummary.setStatus(Status.FAILED); + try { + taskSummary.setInput( + objectMapper.writeValueAsString( + new HashMap() { + { + put("input_key", "input_value"); + } + })); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + taskSummary.setCorrelationId(correlationId); + taskSummary.setTaskDefName("some-task-def-name"); + taskSummary.setReasonForIncompletion("some-failure-reason"); - Task task = new Task(); - task.setTaskId("some-task-id"); - task.setWorkflowInstanceId("some-workflow-instance-id"); - task.setTaskType("some-task-type"); - task.setStatus(Task.Status.FAILED); - task.setInputData( - new HashMap() { - { - put("input_key", "input_value"); - } - }); - task.setCorrelationId(correlationId); - task.setTaskDefName("some-task-def-name"); - task.setReasonForIncompletion("some-failure-reason"); - - indexDAO.indexTask(task); - indexDAO.indexTask(task); + indexDAO.indexTask(taskSummary); + indexDAO.indexTask(taskSummary); await().atMost(5, TimeUnit.SECONDS) .untilAsserted( diff --git a/es6-persistence/src/test/java/com/netflix/conductor/es6/utils/TestUtils.java b/es6-persistence/src/test/java/com/netflix/conductor/es6/utils/TestUtils.java index 3cc3ce41b2..87a90276c9 100644 --- a/es6-persistence/src/test/java/com/netflix/conductor/es6/utils/TestUtils.java +++ b/es6-persistence/src/test/java/com/netflix/conductor/es6/utils/TestUtils.java @@ -17,7 +17,8 @@ import org.apache.commons.io.FileUtils; import org.springframework.util.ResourceUtils; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.common.run.TaskSummary; +import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.core.utils.IDGenerator; import com.fasterxml.jackson.databind.ObjectMapper; @@ -26,17 +27,26 @@ public class TestUtils { private static final String WORKFLOW_INSTANCE_ID_PLACEHOLDER = "WORKFLOW_INSTANCE_ID"; - public static Workflow loadWorkflowSnapshot( + public static WorkflowSummary loadWorkflowSnapshot( ObjectMapper objectMapper, String resourceFileName) { try { String content = loadJsonResource(resourceFileName); String workflowId = IDGenerator.generate(); content = content.replace(WORKFLOW_INSTANCE_ID_PLACEHOLDER, workflowId); - Workflow workflow = objectMapper.readValue(content, Workflow.class); - workflow.setWorkflowId(workflowId); + return objectMapper.readValue(content, WorkflowSummary.class); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + public static TaskSummary loadTaskSnapshot(ObjectMapper objectMapper, String resourceFileName) { + try { + String content = loadJsonResource(resourceFileName); + String workflowId = IDGenerator.generate(); + content = content.replace(WORKFLOW_INSTANCE_ID_PLACEHOLDER, workflowId); - return workflow; + return objectMapper.readValue(content, TaskSummary.class); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } diff --git a/es6-persistence/src/test/resources/task_summary.json b/es6-persistence/src/test/resources/task_summary.json new file mode 100644 index 0000000000..a409a22f13 --- /dev/null +++ b/es6-persistence/src/test/resources/task_summary.json @@ -0,0 +1,17 @@ +{ + "taskId": "9dea4567-0240-4eab-bde8-99f4535ea3fc", + "taskDefName": "templated_task", + "taskType": "templated_task", + "workflowId": "WORKFLOW_INSTANCE_ID", + "workflowType": "template_workflow", + "correlationId": "testTaskDefTemplate", + "scheduledTime": "2021-08-22T05:18:25.121Z", + "startTime": "0", + "endTime": "0", + "updateTime": "2021-08-23T00:18:25.121Z", + "status": "SCHEDULED", + "workflowPriority": 1, + "queueWaitTime": 0, + "executionTime": 0, + "input": "{http_request={method=GET, vipStack=test_stack, body={requestDetails={key1=value1, key2=42}, outputPath=s3://bucket/outputPath, inputPaths=[file://path1, file://path2]}, uri=/get/something}}" +} \ No newline at end of file diff --git a/es6-persistence/src/test/resources/workflow.json b/es6-persistence/src/test/resources/workflow.json deleted file mode 100644 index 627ccf2e78..0000000000 --- a/es6-persistence/src/test/resources/workflow.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "ownerApp": "junit_app", - "createTime": 1534983505050, - "updateTime": 1534983505131, - "status": "RUNNING", - "endTime": 0, - "workflowId": "WORKFLOW_INSTANCE_ID", - "tasks": [ - { - "taskType": "templated_task", - "status": "SCHEDULED", - "inputData": { - "http_request": { - "method": "GET", - "vipStack": "test_stack", - "body": { - "requestDetails": { - "key1": "value1", - "key2": 42 - }, - "outputPath": "s3://bucket/outputPath", - "inputPaths": [ - "file://path1", - "file://path2" - ] - }, - "uri": "/get/something" - } - }, - "referenceTaskName": "t0", - "retryCount": 0, - "seq": 1, - "correlationId": "testTaskDefTemplate", - "pollCount": 0, - "taskDefName": "templated_task", - "scheduledTime": 1534983505121, - "startTime": 0, - "endTime": 0, - "updateTime": 1534983505121, - "startDelayInSeconds": 0, - "retried": false, - "executed": false, - "callbackFromWorker": true, - "responseTimeoutSeconds": 3600, - "workflowInstanceId": "WORKFLOW_INSTANCE_ID", - "workflowType": "template_workflow", - "taskId": "9dea4567-0240-4eab-bde8-99f4535ea3fc", - "callbackAfterSeconds": 0, - "workflowTask": { - "name": "templated_task", - "taskReferenceName": "t0", - "type": "SIMPLE", - "startDelay": 0, - "optional": false - }, - "rateLimitPerSecond": 0, - "taskStatus": "SCHEDULED", - "queueWaitTime": 0 - } - ], - "input": { - "path1": "file://path1", - "path2": "file://path2", - "requestDetails": { - "key1": "value1", - "key2": 42 - }, - "outputPath": "s3://bucket/outputPath" - }, - "workflowDefinition": { - "name": "template_workflow", - "version": 1 - }, - "correlationId": "testTaskDefTemplate", - "schemaVersion": 2, - "startTime": 1534983505050 -} diff --git a/es6-persistence/src/test/resources/workflow_summary.json b/es6-persistence/src/test/resources/workflow_summary.json new file mode 100644 index 0000000000..443d8464eb --- /dev/null +++ b/es6-persistence/src/test/resources/workflow_summary.json @@ -0,0 +1,12 @@ +{ + "workflowType": "template_workflow", + "version": 1, + "workflowId": "WORKFLOW_INSTANCE_ID", + "priority": 1, + "correlationId": "testTaskDefTemplate", + "startTime": 1534983505050, + "updateTime": 1534983505131, + "endTime": 0, + "status": "RUNNING", + "input": "{path1=file://path1, path2=file://path2, requestDetails={key1=value1, key2=42}, outputPath=s3://bucket/outputPath}" +} diff --git a/es7-persistence/src/main/java/com/netflix/conductor/es7/dao/index/ElasticSearchRestDAOV7.java b/es7-persistence/src/main/java/com/netflix/conductor/es7/dao/index/ElasticSearchRestDAOV7.java index 4753194778..dd32f39827 100644 --- a/es7-persistence/src/main/java/com/netflix/conductor/es7/dao/index/ElasticSearchRestDAOV7.java +++ b/es7-persistence/src/main/java/com/netflix/conductor/es7/dao/index/ElasticSearchRestDAOV7.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -17,21 +17,8 @@ import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.TimeZone; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.*; +import java.util.concurrent.*; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -58,13 +45,7 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; -import org.elasticsearch.client.Request; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.ResponseException; -import org.elasticsearch.client.RestClient; -import org.elasticsearch.client.RestClientBuilder; -import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.*; import org.elasticsearch.client.core.CountRequest; import org.elasticsearch.client.core.CountResponse; import org.elasticsearch.common.xcontent.XContentType; @@ -81,11 +62,9 @@ import com.netflix.conductor.annotations.Trace; import com.netflix.conductor.common.metadata.events.EventExecution; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.run.SearchResult; import com.netflix.conductor.common.run.TaskSummary; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.common.utils.RetryUtil; import com.netflix.conductor.core.events.queue.Message; @@ -504,12 +483,11 @@ public boolean doesResourceNotExist(final String resourcePath) throws IOExceptio } @Override - public void indexWorkflow(Workflow workflow) { + public void indexWorkflow(WorkflowSummary workflow) { try { long startTime = Instant.now().toEpochMilli(); String workflowId = workflow.getWorkflowId(); - WorkflowSummary summary = new WorkflowSummary(workflow); - byte[] docBytes = objectMapper.writeValueAsBytes(summary); + byte[] docBytes = objectMapper.writeValueAsBytes(workflow); IndexRequest request = new IndexRequest(workflowIndexName) @@ -544,24 +522,23 @@ public void indexWorkflow(Workflow workflow) { } @Override - public CompletableFuture asyncIndexWorkflow(Workflow workflow) { + public CompletableFuture asyncIndexWorkflow(WorkflowSummary workflow) { return CompletableFuture.runAsync(() -> indexWorkflow(workflow), executorService); } @Override - public void indexTask(Task task) { + public void indexTask(TaskSummary task) { try { long startTime = Instant.now().toEpochMilli(); String taskId = task.getTaskId(); - TaskSummary summary = new TaskSummary(task); - indexObject(taskIndexName, TASK_DOC_TYPE, taskId, summary); + indexObject(taskIndexName, TASK_DOC_TYPE, taskId, task); long endTime = Instant.now().toEpochMilli(); logger.debug( "Time taken {} for indexing task:{} in workflow: {}", endTime - startTime, taskId, - task.getWorkflowInstanceId()); + task.getWorkflowId()); Monitors.recordESIndexTime("index_task", TASK_DOC_TYPE, endTime - startTime); Monitors.recordWorkerQueueSize( "indexQueue", ((ThreadPoolExecutor) executorService).getQueue().size()); @@ -571,7 +548,7 @@ public void indexTask(Task task) { } @Override - public CompletableFuture asyncIndexTask(Task task) { + public CompletableFuture asyncIndexTask(TaskSummary task) { return CompletableFuture.runAsync(() -> indexTask(task), executorService); } diff --git a/es7-persistence/src/test/java/com/netflix/conductor/es7/dao/index/TestElasticSearchRestDAOV7.java b/es7-persistence/src/test/java/com/netflix/conductor/es7/dao/index/TestElasticSearchRestDAOV7.java index c06635c861..e055025a25 100644 --- a/es7-persistence/src/test/java/com/netflix/conductor/es7/dao/index/TestElasticSearchRestDAOV7.java +++ b/es7-persistence/src/test/java/com/netflix/conductor/es7/dao/index/TestElasticSearchRestDAOV7.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -22,10 +22,9 @@ import com.netflix.conductor.common.metadata.events.EventExecution; import com.netflix.conductor.common.metadata.events.EventHandler; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskExecLog; import com.netflix.conductor.common.run.TaskSummary; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.common.run.Workflow.WorkflowStatus; import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.es7.utils.TestUtils; @@ -89,115 +88,107 @@ public void assertInitialSetup() throws IOException { @Test public void shouldIndexWorkflow() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); - indexDAO.indexWorkflow(workflow); - - assertWorkflowSummary(workflow.getWorkflowId(), summary); + assertWorkflowSummary(workflowSummary.getWorkflowId(), workflowSummary); } @Test public void shouldIndexWorkflowAsync() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - - indexDAO.asyncIndexWorkflow(workflow).get(); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.asyncIndexWorkflow(workflowSummary).get(); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + assertWorkflowSummary(workflowSummary.getWorkflowId(), workflowSummary); } @Test public void shouldRemoveWorkflow() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); // wait for workflow to be indexed - List workflows = tryFindResults(() -> searchWorkflows(workflow.getWorkflowId()), 1); + List workflows = + tryFindResults(() -> searchWorkflows(workflowSummary.getWorkflowId()), 1); assertEquals(1, workflows.size()); - indexDAO.removeWorkflow(workflow.getWorkflowId()); + indexDAO.removeWorkflow(workflowSummary.getWorkflowId()); - workflows = tryFindResults(() -> searchWorkflows(workflow.getWorkflowId()), 0); + workflows = tryFindResults(() -> searchWorkflows(workflowSummary.getWorkflowId()), 0); assertTrue("Workflow was not removed.", workflows.isEmpty()); } @Test public void shouldAsyncRemoveWorkflow() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); // wait for workflow to be indexed - List workflows = tryFindResults(() -> searchWorkflows(workflow.getWorkflowId()), 1); + List workflows = + tryFindResults(() -> searchWorkflows(workflowSummary.getWorkflowId()), 1); assertEquals(1, workflows.size()); - indexDAO.asyncRemoveWorkflow(workflow.getWorkflowId()).get(); + indexDAO.asyncRemoveWorkflow(workflowSummary.getWorkflowId()).get(); - workflows = tryFindResults(() -> searchWorkflows(workflow.getWorkflowId()), 0); + workflows = tryFindResults(() -> searchWorkflows(workflowSummary.getWorkflowId()), 0); assertTrue("Workflow was not removed.", workflows.isEmpty()); } @Test public void shouldUpdateWorkflow() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); indexDAO.updateWorkflow( - workflow.getWorkflowId(), + workflowSummary.getWorkflowId(), new String[] {"status"}, - new Object[] {Workflow.WorkflowStatus.COMPLETED}); + new Object[] {WorkflowStatus.COMPLETED}); - summary.setStatus(Workflow.WorkflowStatus.COMPLETED); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + workflowSummary.setStatus(WorkflowStatus.COMPLETED); + assertWorkflowSummary(workflowSummary.getWorkflowId(), workflowSummary); } @Test public void shouldAsyncUpdateWorkflow() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - WorkflowSummary summary = new WorkflowSummary(workflow); - - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); indexDAO.asyncUpdateWorkflow( - workflow.getWorkflowId(), + workflowSummary.getWorkflowId(), new String[] {"status"}, - new Object[] {Workflow.WorkflowStatus.FAILED}) + new Object[] {WorkflowStatus.FAILED}) .get(); - summary.setStatus(Workflow.WorkflowStatus.FAILED); - assertWorkflowSummary(workflow.getWorkflowId(), summary); + workflowSummary.setStatus(WorkflowStatus.FAILED); + assertWorkflowSummary(workflowSummary.getWorkflowId(), workflowSummary); } @Test public void shouldIndexTask() { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - Task task = workflow.getTasks().get(0); - - TaskSummary summary = new TaskSummary(task); + TaskSummary taskSummary = TestUtils.loadTaskSnapshot(objectMapper, "task_summary"); + indexDAO.indexTask(taskSummary); - indexDAO.indexTask(task); + List tasks = tryFindResults(() -> searchTasks(taskSummary)); - List tasks = tryFindResults(() -> searchTasks(workflow)); - - assertEquals(summary.getTaskId(), tasks.get(0)); + assertEquals(taskSummary.getTaskId(), tasks.get(0)); } @Test public void shouldIndexTaskAsync() throws Exception { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - Task task = workflow.getTasks().get(0); - - TaskSummary summary = new TaskSummary(task); - - indexDAO.asyncIndexTask(task).get(); + TaskSummary taskSummary = TestUtils.loadTaskSnapshot(objectMapper, "task_summary"); + indexDAO.asyncIndexTask(taskSummary).get(); - List tasks = tryFindResults(() -> searchTasks(workflow)); + List tasks = tryFindResults(() -> searchTasks(taskSummary)); - assertEquals(summary.getTaskId(), tasks.get(0)); + assertEquals(taskSummary.getTaskId(), tasks.get(0)); } @Test @@ -302,17 +293,20 @@ public void shouldAddIndexPrefixToIndexTemplate() throws Exception { @Test public void shouldSearchRecentRunningWorkflows() throws Exception { - Workflow oldWorkflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - oldWorkflow.setStatus(Workflow.WorkflowStatus.RUNNING); - oldWorkflow.setUpdateTime(new DateTime().minusHours(2).toDate().getTime()); + WorkflowSummary oldWorkflow = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + oldWorkflow.setStatus(WorkflowStatus.RUNNING); + oldWorkflow.setUpdateTime(getFormattedTime(new DateTime().minusHours(2).toDate())); - Workflow recentWorkflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - recentWorkflow.setStatus(Workflow.WorkflowStatus.RUNNING); - recentWorkflow.setUpdateTime(new DateTime().minusHours(1).toDate().getTime()); + WorkflowSummary recentWorkflow = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + recentWorkflow.setStatus(WorkflowStatus.RUNNING); + recentWorkflow.setUpdateTime(getFormattedTime(new DateTime().minusHours(1).toDate())); - Workflow tooRecentWorkflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - tooRecentWorkflow.setStatus(Workflow.WorkflowStatus.RUNNING); - tooRecentWorkflow.setUpdateTime(new DateTime().toDate().getTime()); + WorkflowSummary tooRecentWorkflow = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + tooRecentWorkflow.setStatus(WorkflowStatus.RUNNING); + tooRecentWorkflow.setUpdateTime(getFormattedTime(new DateTime().toDate())); indexDAO.indexWorkflow(oldWorkflow); indexDAO.indexWorkflow(recentWorkflow); @@ -330,8 +324,9 @@ public void shouldSearchRecentRunningWorkflows() throws Exception { public void shouldCountWorkflows() { int counts = 1100; for (int i = 0; i < counts; i++) { - Workflow workflow = TestUtils.loadWorkflowSnapshot(objectMapper, "workflow"); - indexDAO.indexWorkflow(workflow); + WorkflowSummary workflowSummary = + TestUtils.loadWorkflowSnapshot(objectMapper, "workflow_summary"); + indexDAO.indexWorkflow(workflowSummary); } // wait for workflow to be indexed @@ -384,6 +379,12 @@ private void assertWorkflowSummary(String workflowId, WorkflowSummary summary) { indexDAO.get(workflowId, "failedReferenceTaskNames")); } + private String getFormattedTime(Date time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + sdf.setTimeZone(TimeZone.getTimeZone("GMT")); + return sdf.format(time); + } + private List tryFindResults(Supplier> searchFunction) { return tryFindResults(searchFunction, 1); } @@ -410,10 +411,10 @@ private List searchWorkflows(String workflowId) { .getResults(); } - private List searchTasks(Workflow workflow) { + private List searchTasks(TaskSummary taskSummary) { return indexDAO.searchTasks( "", - "workflowId:\"" + workflow.getWorkflowId() + "\"", + "workflowId:\"" + taskSummary.getWorkflowId() + "\"", 0, 100, Collections.emptyList()) diff --git a/es7-persistence/src/test/java/com/netflix/conductor/es7/dao/index/TestElasticSearchRestDAOV7Batch.java b/es7-persistence/src/test/java/com/netflix/conductor/es7/dao/index/TestElasticSearchRestDAOV7Batch.java index 4a4ae96025..81b5971dff 100644 --- a/es7-persistence/src/test/java/com/netflix/conductor/es7/dao/index/TestElasticSearchRestDAOV7Batch.java +++ b/es7-persistence/src/test/java/com/netflix/conductor/es7/dao/index/TestElasticSearchRestDAOV7Batch.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -18,8 +18,11 @@ import org.junit.Test; import org.springframework.test.context.TestPropertySource; -import com.netflix.conductor.common.metadata.tasks.Task; +import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.run.SearchResult; +import com.netflix.conductor.common.run.TaskSummary; + +import com.fasterxml.jackson.core.JsonProcessingException; import static org.awaitility.Awaitility.await; import static org.junit.Assert.assertEquals; @@ -32,23 +35,28 @@ public class TestElasticSearchRestDAOV7Batch extends ElasticSearchRestDaoBaseTes public void indexTaskWithBatchSizeTwo() { String correlationId = "some-correlation-id"; - Task task = new Task(); - task.setTaskId("some-task-id"); - task.setWorkflowInstanceId("some-workflow-instance-id"); - task.setTaskType("some-task-type"); - task.setStatus(Task.Status.FAILED); - task.setInputData( - new HashMap() { - { - put("input_key", "input_value"); - } - }); - task.setCorrelationId(correlationId); - task.setTaskDefName("some-task-def-name"); - task.setReasonForIncompletion("some-failure-reason"); + TaskSummary taskSummary = new TaskSummary(); + taskSummary.setTaskId("some-task-id"); + taskSummary.setWorkflowId("some-workflow-instance-id"); + taskSummary.setTaskType("some-task-type"); + taskSummary.setStatus(Status.FAILED); + try { + taskSummary.setInput( + objectMapper.writeValueAsString( + new HashMap() { + { + put("input_key", "input_value"); + } + })); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + taskSummary.setCorrelationId(correlationId); + taskSummary.setTaskDefName("some-task-def-name"); + taskSummary.setReasonForIncompletion("some-failure-reason"); - indexDAO.indexTask(task); - indexDAO.indexTask(task); + indexDAO.indexTask(taskSummary); + indexDAO.indexTask(taskSummary); await().atMost(5, TimeUnit.SECONDS) .untilAsserted( diff --git a/es7-persistence/src/test/java/com/netflix/conductor/es7/utils/TestUtils.java b/es7-persistence/src/test/java/com/netflix/conductor/es7/utils/TestUtils.java index afd1a72c6e..e713eb9243 100644 --- a/es7-persistence/src/test/java/com/netflix/conductor/es7/utils/TestUtils.java +++ b/es7-persistence/src/test/java/com/netflix/conductor/es7/utils/TestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -14,7 +14,8 @@ import org.apache.commons.io.Charsets; -import com.netflix.conductor.common.run.Workflow; +import com.netflix.conductor.common.run.TaskSummary; +import com.netflix.conductor.common.run.WorkflowSummary; import com.netflix.conductor.core.utils.IDGenerator; import com.fasterxml.jackson.databind.ObjectMapper; @@ -25,17 +26,26 @@ public class TestUtils { private static final String WORKFLOW_SCENARIO_EXTENSION = ".json"; private static final String WORKFLOW_INSTANCE_ID_PLACEHOLDER = "WORKFLOW_INSTANCE_ID"; - public static Workflow loadWorkflowSnapshot( + public static WorkflowSummary loadWorkflowSnapshot( ObjectMapper objectMapper, String resourceFileName) { try { String content = loadJsonResource(resourceFileName); String workflowId = IDGenerator.generate(); content = content.replace(WORKFLOW_INSTANCE_ID_PLACEHOLDER, workflowId); - Workflow workflow = objectMapper.readValue(content, Workflow.class); - workflow.setWorkflowId(workflowId); + return objectMapper.readValue(content, WorkflowSummary.class); + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + public static TaskSummary loadTaskSnapshot(ObjectMapper objectMapper, String resourceFileName) { + try { + String content = loadJsonResource(resourceFileName); + String workflowId = IDGenerator.generate(); + content = content.replace(WORKFLOW_INSTANCE_ID_PLACEHOLDER, workflowId); - return workflow; + return objectMapper.readValue(content, TaskSummary.class); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } diff --git a/es7-persistence/src/test/resources/task_summary.json b/es7-persistence/src/test/resources/task_summary.json new file mode 100644 index 0000000000..a409a22f13 --- /dev/null +++ b/es7-persistence/src/test/resources/task_summary.json @@ -0,0 +1,17 @@ +{ + "taskId": "9dea4567-0240-4eab-bde8-99f4535ea3fc", + "taskDefName": "templated_task", + "taskType": "templated_task", + "workflowId": "WORKFLOW_INSTANCE_ID", + "workflowType": "template_workflow", + "correlationId": "testTaskDefTemplate", + "scheduledTime": "2021-08-22T05:18:25.121Z", + "startTime": "0", + "endTime": "0", + "updateTime": "2021-08-23T00:18:25.121Z", + "status": "SCHEDULED", + "workflowPriority": 1, + "queueWaitTime": 0, + "executionTime": 0, + "input": "{http_request={method=GET, vipStack=test_stack, body={requestDetails={key1=value1, key2=42}, outputPath=s3://bucket/outputPath, inputPaths=[file://path1, file://path2]}, uri=/get/something}}" +} \ No newline at end of file diff --git a/es7-persistence/src/test/resources/workflow.json b/es7-persistence/src/test/resources/workflow.json deleted file mode 100644 index 627ccf2e78..0000000000 --- a/es7-persistence/src/test/resources/workflow.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "ownerApp": "junit_app", - "createTime": 1534983505050, - "updateTime": 1534983505131, - "status": "RUNNING", - "endTime": 0, - "workflowId": "WORKFLOW_INSTANCE_ID", - "tasks": [ - { - "taskType": "templated_task", - "status": "SCHEDULED", - "inputData": { - "http_request": { - "method": "GET", - "vipStack": "test_stack", - "body": { - "requestDetails": { - "key1": "value1", - "key2": 42 - }, - "outputPath": "s3://bucket/outputPath", - "inputPaths": [ - "file://path1", - "file://path2" - ] - }, - "uri": "/get/something" - } - }, - "referenceTaskName": "t0", - "retryCount": 0, - "seq": 1, - "correlationId": "testTaskDefTemplate", - "pollCount": 0, - "taskDefName": "templated_task", - "scheduledTime": 1534983505121, - "startTime": 0, - "endTime": 0, - "updateTime": 1534983505121, - "startDelayInSeconds": 0, - "retried": false, - "executed": false, - "callbackFromWorker": true, - "responseTimeoutSeconds": 3600, - "workflowInstanceId": "WORKFLOW_INSTANCE_ID", - "workflowType": "template_workflow", - "taskId": "9dea4567-0240-4eab-bde8-99f4535ea3fc", - "callbackAfterSeconds": 0, - "workflowTask": { - "name": "templated_task", - "taskReferenceName": "t0", - "type": "SIMPLE", - "startDelay": 0, - "optional": false - }, - "rateLimitPerSecond": 0, - "taskStatus": "SCHEDULED", - "queueWaitTime": 0 - } - ], - "input": { - "path1": "file://path1", - "path2": "file://path2", - "requestDetails": { - "key1": "value1", - "key2": 42 - }, - "outputPath": "s3://bucket/outputPath" - }, - "workflowDefinition": { - "name": "template_workflow", - "version": 1 - }, - "correlationId": "testTaskDefTemplate", - "schemaVersion": 2, - "startTime": 1534983505050 -} diff --git a/es7-persistence/src/test/resources/workflow_summary.json b/es7-persistence/src/test/resources/workflow_summary.json new file mode 100644 index 0000000000..443d8464eb --- /dev/null +++ b/es7-persistence/src/test/resources/workflow_summary.json @@ -0,0 +1,12 @@ +{ + "workflowType": "template_workflow", + "version": 1, + "workflowId": "WORKFLOW_INSTANCE_ID", + "priority": 1, + "correlationId": "testTaskDefTemplate", + "startTime": 1534983505050, + "updateTime": 1534983505131, + "endTime": 0, + "status": "RUNNING", + "input": "{path1=file://path1, path2=file://path2, requestDetails={key1=value1, key2=42}, outputPath=s3://bucket/outputPath}" +} diff --git a/grpc-client/src/main/java/com/netflix/conductor/client/grpc/TaskClient.java b/grpc-client/src/main/java/com/netflix/conductor/client/grpc/TaskClient.java index 44b4256ee9..7bc654123c 100644 --- a/grpc-client/src/main/java/com/netflix/conductor/client/grpc/TaskClient.java +++ b/grpc-client/src/main/java/com/netflix/conductor/client/grpc/TaskClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/config/MySQLConfiguration.java b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/config/MySQLConfiguration.java index 046195c324..d0ec108207 100644 --- a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/config/MySQLConfiguration.java +++ b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/config/MySQLConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -28,7 +28,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(MySQLProperties.class) @ConditionalOnProperty(name = "conductor.db.type", havingValue = "mysql") diff --git a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAO.java b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAO.java index 274506b64f..fb07329854 100644 --- a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAO.java +++ b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -15,27 +15,22 @@ import java.sql.Connection; import java.sql.SQLException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import javax.sql.DataSource; import com.netflix.conductor.common.metadata.events.EventExecution; import com.netflix.conductor.common.metadata.tasks.PollData; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.dao.ConcurrentExecutionLimitDAO; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.dao.PollDataDAO; import com.netflix.conductor.dao.RateLimitingDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.mysql.util.Query; import com.fasterxml.jackson.databind.ObjectMapper; @@ -66,7 +61,7 @@ private static String dateStr(Date date) { } @Override - public List getPendingTasksByWorkflow(String taskDefName, String workflowId) { + public List getPendingTasksByWorkflow(String taskDefName, String workflowId) { // @formatter:off String GET_IN_PROGRESS_TASKS_FOR_WORKFLOW = "SELECT json_data FROM task_in_progress tip " @@ -79,17 +74,17 @@ public List getPendingTasksByWorkflow(String taskDefName, String workflowI q -> q.addParameter(taskDefName) .addParameter(workflowId) - .executeAndFetch(Task.class)); + .executeAndFetch(TaskModel.class)); } @Override - public List getTasks(String taskDefName, String startKey, int count) { - List tasks = new ArrayList<>(count); + public List getTasks(String taskDefName, String startKey, int count) { + List tasks = new ArrayList<>(count); - List pendingTasks = getPendingTasksForTaskType(taskDefName); + List pendingTasks = getPendingTasksForTaskType(taskDefName); boolean startKeyFound = startKey == null; int found = 0; - for (Task pendingTask : pendingTasks) { + for (TaskModel pendingTask : pendingTasks) { if (!startKeyFound) { if (pendingTask.getTaskId().equals(startKey)) { startKeyFound = true; @@ -108,17 +103,17 @@ public List getTasks(String taskDefName, String startKey, int count) { return tasks; } - private static String taskKey(Task task) { + private static String taskKey(TaskModel task) { return task.getReferenceTaskName() + "_" + task.getRetryCount(); } @Override - public List createTasks(List tasks) { - List created = Lists.newArrayListWithCapacity(tasks.size()); + public List createTasks(List tasks) { + List created = Lists.newArrayListWithCapacity(tasks.size()); withTransaction( connection -> { - for (Task task : tasks) { + for (TaskModel task : tasks) { validate(task); task.setScheduledTime(System.currentTimeMillis()); @@ -151,7 +146,7 @@ public List createTasks(List tasks) { } @Override - public void updateTask(Task task) { + public void updateTask(TaskModel task) { withTransaction(connection -> updateTask(connection, task)); } @@ -161,15 +156,15 @@ public void updateTask(Task task) { * @param task: which needs to be evaluated whether it is rateLimited or not */ @Override - public boolean exceedsRateLimitPerFrequency(Task task, TaskDef taskDef) { + public boolean exceedsRateLimitPerFrequency(TaskModel task, TaskDef taskDef) { return false; } @Override - public boolean exceedsLimit(Task task) { + public boolean exceedsLimit(TaskModel task) { Optional taskDefinition = task.getTaskDefinition(); - if (!taskDefinition.isPresent()) { + if (taskDefinition.isEmpty()) { return false; } @@ -214,7 +209,7 @@ public boolean exceedsLimit(Task task) { @Override public boolean removeTask(String taskId) { - Task task = getTask(taskId); + TaskModel task = getTask(taskId); if (task == null) { logger.warn("No such task found by id {}", taskId); @@ -234,14 +229,14 @@ public boolean removeTask(String taskId) { } @Override - public Task getTask(String taskId) { + public TaskModel getTask(String taskId) { String GET_TASK = "SELECT json_data FROM task WHERE task_id = ?"; return queryWithTransaction( - GET_TASK, q -> q.addParameter(taskId).executeAndFetchFirst(Task.class)); + GET_TASK, q -> q.addParameter(taskId).executeAndFetchFirst(TaskModel.class)); } @Override - public List getTasks(List taskIds) { + public List getTasks(List taskIds) { if (taskIds.isEmpty()) { return Lists.newArrayList(); } @@ -249,7 +244,7 @@ public List getTasks(List taskIds) { } @Override - public List getPendingTasksForTaskType(String taskName) { + public List getPendingTasksForTaskType(String taskName) { Preconditions.checkNotNull(taskName, "task name cannot be null"); // @formatter:off String GET_IN_PROGRESS_TASKS_FOR_TYPE = @@ -260,11 +255,11 @@ public List getPendingTasksForTaskType(String taskName) { return queryWithTransaction( GET_IN_PROGRESS_TASKS_FOR_TYPE, - q -> q.addParameter(taskName).executeAndFetch(Task.class)); + q -> q.addParameter(taskName).executeAndFetch(TaskModel.class)); } @Override - public List getTasksForWorkflow(String workflowId) { + public List getTasksForWorkflow(String workflowId) { String GET_TASKS_FOR_WORKFLOW = "SELECT task_id FROM workflow_to_task WHERE workflow_id = ?"; return getWithRetriedTransactions( @@ -281,19 +276,19 @@ public List getTasksForWorkflow(String workflowId) { } @Override - public String createWorkflow(Workflow workflow) { + public String createWorkflow(WorkflowModel workflow) { return insertOrUpdateWorkflow(workflow, false); } @Override - public String updateWorkflow(Workflow workflow) { + public String updateWorkflow(WorkflowModel workflow) { return insertOrUpdateWorkflow(workflow, true); } @Override public boolean removeWorkflow(String workflowId) { boolean removed = false; - Workflow workflow = getWorkflow(workflowId, true); + WorkflowModel workflow = getWorkflow(workflowId, true); if (workflow != null) { withTransaction( connection -> { @@ -303,7 +298,7 @@ public boolean removeWorkflow(String workflowId) { }); removed = true; - for (Task task : workflow.getTasks()) { + for (TaskModel task : workflow.getTasks()) { if (!removeTask(task.getTaskId())) { removed = false; } @@ -327,20 +322,20 @@ public void removeFromPendingWorkflow(String workflowType, String workflowId) { } @Override - public Workflow getWorkflow(String workflowId) { + public WorkflowModel getWorkflow(String workflowId) { return getWorkflow(workflowId, true); } @Override - public Workflow getWorkflow(String workflowId, boolean includeTasks) { - Workflow workflow = getWithRetriedTransactions(tx -> readWorkflow(tx, workflowId)); + public WorkflowModel getWorkflow(String workflowId, boolean includeTasks) { + WorkflowModel workflow = getWithRetriedTransactions(tx -> readWorkflow(tx, workflowId)); if (workflow != null) { if (includeTasks) { - List tasks = getTasksForWorkflow(workflowId); + List tasks = getTasksForWorkflow(workflowId); tasks.sort( - Comparator.comparingLong(Task::getScheduledTime) - .thenComparingInt(Task::getSeq)); + Comparator.comparingLong(TaskModel::getScheduledTime) + .thenComparingInt(TaskModel::getSeq)); workflow.setTasks(tasks); } } @@ -370,7 +365,7 @@ public List getRunningWorkflowIds(String workflowName, int version) { * @return list of workflows that are in RUNNING state */ @Override - public List getPendingWorkflowsByType(String workflowName, int version) { + public List getPendingWorkflowsByType(String workflowName, int version) { Preconditions.checkNotNull(workflowName, "workflowName cannot be null"); return getRunningWorkflowIds(workflowName, version).stream() .map(this::getWorkflow) @@ -398,12 +393,13 @@ public long getInProgressTaskCount(String taskDefName) { } @Override - public List getWorkflowsByType(String workflowName, Long startTime, Long endTime) { + public List getWorkflowsByType( + String workflowName, Long startTime, Long endTime) { Preconditions.checkNotNull(workflowName, "workflowName cannot be null"); Preconditions.checkNotNull(startTime, "startTime cannot be null"); Preconditions.checkNotNull(endTime, "endTime cannot be null"); - List workflows = new LinkedList<>(); + List workflows = new LinkedList<>(); withTransaction( tx -> { @@ -425,7 +421,7 @@ public List getWorkflowsByType(String workflowName, Long startTime, Lo workflowIds.forEach( workflowId -> { try { - Workflow wf = getWorkflow(workflowId); + WorkflowModel wf = getWorkflow(workflowId); if (wf.getCreateTime() >= startTime && wf.getCreateTime() <= endTime) { workflows.add(wf); @@ -444,7 +440,7 @@ public List getWorkflowsByType(String workflowName, Long startTime, Lo } @Override - public List getWorkflowsByCorrelationId( + public List getWorkflowsByCorrelationId( String workflowName, String correlationId, boolean includeTasks) { Preconditions.checkNotNull(correlationId, "correlationId cannot be null"); String GET_WORKFLOWS_BY_CORRELATION_ID = @@ -455,7 +451,7 @@ public List getWorkflowsByCorrelationId( q -> q.addParameter(correlationId) .addParameter(workflowName) - .executeAndFetch(Workflow.class)); + .executeAndFetch(WorkflowModel.class)); } @Override @@ -573,7 +569,7 @@ public List getAllPollData() { } } - private List getTasks(Connection connection, List taskIds) { + private List getTasks(Connection connection, List taskIds) { if (taskIds.isEmpty()) { return Lists.newArrayList(); } @@ -588,15 +584,15 @@ private List getTasks(Connection connection, List taskIds) { return query( connection, GET_TASKS_FOR_IDS, - q -> q.addParameters(taskIds).executeAndFetch(Task.class)); + q -> q.addParameters(taskIds).executeAndFetch(TaskModel.class)); } - private String insertOrUpdateWorkflow(Workflow workflow, boolean update) { + private String insertOrUpdateWorkflow(WorkflowModel workflow, boolean update) { Preconditions.checkNotNull(workflow, "workflow object cannot be null"); boolean terminal = workflow.getStatus().isTerminal(); - List tasks = workflow.getTasks(); + List tasks = workflow.getTasks(); workflow.setTasks(Lists.newLinkedList()); withTransaction( @@ -621,12 +617,13 @@ private String insertOrUpdateWorkflow(Workflow workflow, boolean update) { return workflow.getWorkflowId(); } - private void updateTask(Connection connection, Task task) { + private void updateTask(Connection connection, TaskModel task) { Optional taskDefinition = task.getTaskDefinition(); if (taskDefinition.isPresent() && taskDefinition.get().concurrencyLimit() > 0) { boolean inProgress = - task.getStatus() != null && task.getStatus().equals(Task.Status.IN_PROGRESS); + task.getStatus() != null + && task.getStatus().equals(TaskModel.Status.IN_PROGRESS); updateInProgressStatus(connection, task, inProgress); } @@ -639,16 +636,16 @@ private void updateTask(Connection connection, Task task) { addWorkflowToTaskMapping(connection, task); } - private Workflow readWorkflow(Connection connection, String workflowId) { + private WorkflowModel readWorkflow(Connection connection, String workflowId) { String GET_WORKFLOW = "SELECT json_data FROM workflow WHERE workflow_id = ?"; return query( connection, GET_WORKFLOW, - q -> q.addParameter(workflowId).executeAndFetchFirst(Workflow.class)); + q -> q.addParameter(workflowId).executeAndFetchFirst(WorkflowModel.class)); } - private void addWorkflow(Connection connection, Workflow workflow) { + private void addWorkflow(Connection connection, WorkflowModel workflow) { String INSERT_WORKFLOW = "INSERT INTO workflow (workflow_id, correlation_id, json_data) VALUES (?, ?, ?)"; @@ -662,7 +659,7 @@ private void addWorkflow(Connection connection, Workflow workflow) { .executeUpdate()); } - private void updateWorkflow(Connection connection, Workflow workflow) { + private void updateWorkflow(Connection connection, WorkflowModel workflow) { String UPDATE_WORKFLOW = "UPDATE workflow SET json_data = ?, modified_on = CURRENT_TIMESTAMP WHERE workflow_id = ?"; @@ -713,7 +710,7 @@ private void removePendingWorkflow( q -> q.addParameter(workflowType).addParameter(workflowId).executeDelete()); } - private void insertOrUpdateTaskData(Connection connection, Task task) { + private void insertOrUpdateTaskData(Connection connection, TaskModel task) { /* * Most times the row will be updated so let's try the update first. This used to be an 'INSERT/ON DUPLICATE KEY update' sql statement. The problem with that * is that if we try the INSERT first, the sequence will be increased even if the ON DUPLICATE KEY happens. @@ -739,12 +736,12 @@ private void insertOrUpdateTaskData(Connection connection, Task task) { } } - private void removeTaskData(Connection connection, Task task) { + private void removeTaskData(Connection connection, TaskModel task) { String REMOVE_TASK = "DELETE FROM task WHERE task_id = ?"; execute(connection, REMOVE_TASK, q -> q.addParameter(task.getTaskId()).executeDelete()); } - private void addWorkflowToTaskMapping(Connection connection, Task task) { + private void addWorkflowToTaskMapping(Connection connection, TaskModel task) { String EXISTS_WORKFLOW_TO_TASK = "SELECT EXISTS(SELECT 1 FROM workflow_to_task WHERE workflow_id = ? AND task_id = ?)"; @@ -772,7 +769,7 @@ private void addWorkflowToTaskMapping(Connection connection, Task task) { } } - private void removeWorkflowToTaskMapping(Connection connection, Task task) { + private void removeWorkflowToTaskMapping(Connection connection, TaskModel task) { String REMOVE_WORKFLOW_TO_TASK = "DELETE FROM workflow_to_task WHERE workflow_id = ? AND task_id = ?"; @@ -785,7 +782,7 @@ private void removeWorkflowToTaskMapping(Connection connection, Task task) { .executeDelete()); } - private void addWorkflowDefToWorkflowMapping(Connection connection, Workflow workflow) { + private void addWorkflowDefToWorkflowMapping(Connection connection, WorkflowModel workflow) { String INSERT_WORKFLOW_DEF_TO_WORKFLOW = "INSERT INTO workflow_def_to_workflow (workflow_def, date_str, workflow_id) VALUES (?, ?, ?)"; @@ -799,7 +796,7 @@ private void addWorkflowDefToWorkflowMapping(Connection connection, Workflow wor .executeUpdate()); } - private void removeWorkflowDefToWorkflowMapping(Connection connection, Workflow workflow) { + private void removeWorkflowDefToWorkflowMapping(Connection connection, WorkflowModel workflow) { String REMOVE_WORKFLOW_DEF_TO_WORKFLOW = "DELETE FROM workflow_def_to_workflow WHERE workflow_def = ? AND date_str = ? AND workflow_id = ?"; @@ -814,7 +811,7 @@ private void removeWorkflowDefToWorkflowMapping(Connection connection, Workflow } @VisibleForTesting - boolean addScheduledTask(Connection connection, Task task, String taskKey) { + boolean addScheduledTask(Connection connection, TaskModel task, String taskKey) { final String EXISTS_SCHEDULED_TASK = "SELECT EXISTS(SELECT 1 FROM task_scheduled where workflow_id = ? AND task_key = ?)"; @@ -847,7 +844,7 @@ boolean addScheduledTask(Connection connection, Task task, String taskKey) { } } - private void removeScheduledTask(Connection connection, Task task, String taskKey) { + private void removeScheduledTask(Connection connection, TaskModel task, String taskKey) { String REMOVE_SCHEDULED_TASK = "DELETE FROM task_scheduled WHERE workflow_id = ? AND task_key = ?"; execute( @@ -859,7 +856,7 @@ private void removeScheduledTask(Connection connection, Task task, String taskKe .executeDelete()); } - private void addTaskInProgress(Connection connection, Task task) { + private void addTaskInProgress(Connection connection, TaskModel task) { String EXISTS_IN_PROGRESS_TASK = "SELECT EXISTS(SELECT 1 FROM task_in_progress WHERE task_def_name = ? AND task_id = ?)"; @@ -887,7 +884,7 @@ private void addTaskInProgress(Connection connection, Task task) { } } - private void removeTaskInProgress(Connection connection, Task task) { + private void removeTaskInProgress(Connection connection, TaskModel task) { String REMOVE_IN_PROGRESS_TASK = "DELETE FROM task_in_progress WHERE task_def_name = ? AND task_id = ?"; @@ -900,7 +897,7 @@ private void removeTaskInProgress(Connection connection, Task task) { .executeUpdate()); } - private void updateInProgressStatus(Connection connection, Task task, boolean inProgress) { + private void updateInProgressStatus(Connection connection, TaskModel task, boolean inProgress) { String UPDATE_IN_PROGRESS_TASK_STATUS = "UPDATE task_in_progress SET in_progress_status = ?, modified_on = CURRENT_TIMESTAMP " + "WHERE task_def_name = ? AND task_id = ?"; @@ -1053,7 +1050,7 @@ private List readAllPollData(String queueName) { GET_ALL_POLL_DATA, q -> q.addParameter(queueName).executeAndFetch(PollData.class)); } - private List findAllTasksInProgressInOrderOfArrival(Task task, int limit) { + private List findAllTasksInProgressInOrderOfArrival(TaskModel task, int limit) { String GET_IN_PROGRESS_TASKS_WITH_LIMIT = "SELECT task_id FROM task_in_progress WHERE task_def_name = ? ORDER BY created_on LIMIT ?"; @@ -1065,7 +1062,7 @@ private List findAllTasksInProgressInOrderOfArrival(Task task, int limit .executeScalarList(String.class)); } - private void validate(Task task) { + private void validate(TaskModel task) { Preconditions.checkNotNull(task, "task object cannot be null"); Preconditions.checkNotNull(task.getTaskId(), "Task id cannot be null"); Preconditions.checkNotNull( diff --git a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLMetadataDAO.java b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLMetadataDAO.java index f87d8c5802..775c825887 100644 --- a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLMetadataDAO.java +++ b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLMetadataDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLQueueDAO.java b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLQueueDAO.java index cf39c5d056..e6164eab7a 100644 --- a/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLQueueDAO.java +++ b/mysql-persistence/src/main/java/com/netflix/conductor/mysql/dao/MySQLQueueDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAOTest.java b/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAOTest.java index 259f356b15..da0769e421 100644 --- a/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAOTest.java +++ b/mysql-persistence/src/test/java/com/netflix/conductor/mysql/dao/MySQLExecutionDAOTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -26,9 +26,9 @@ import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.dao.ExecutionDAOTest; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.mysql.config.MySQLConfiguration; import static org.junit.Assert.assertEquals; @@ -61,12 +61,12 @@ public void testPendingByCorrelationId() { WorkflowDef def = new WorkflowDef(); def.setName("pending_count_correlation_jtest"); - Workflow workflow = createTestWorkflow(); + WorkflowModel workflow = createTestWorkflow(); workflow.setWorkflowDefinition(def); generateWorkflows(workflow, 10); - List bycorrelationId = + List bycorrelationId = getExecutionDAO() .getWorkflowsByCorrelationId( "pending_count_correlation_jtest", "corr001", true); diff --git a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresConfiguration.java b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresConfiguration.java index 11f97c8503..c1b9e533d7 100644 --- a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresConfiguration.java +++ b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresConfiguration.java @@ -30,12 +30,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; -@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(PostgresProperties.class) @ConditionalOnProperty(name = "conductor.db.type", havingValue = "postgres") // Import the DataSourceAutoConfiguration when postgres database is selected. -// By default the datasource configuration is excluded in the main module. +// By default, the datasource configuration is excluded in the main module. @Import(DataSourceAutoConfiguration.class) public class PostgresConfiguration { diff --git a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresProperties.java b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresProperties.java index 80081a0a4c..93f0442d0a 100644 --- a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresProperties.java +++ b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/config/PostgresProperties.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresBaseDAO.java b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresBaseDAO.java index 6d6e46fb7b..173cad887b 100644 --- a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresBaseDAO.java +++ b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresBaseDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAO.java b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAO.java index 9571522bd3..ed42620ac9 100644 --- a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAO.java +++ b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -16,26 +16,22 @@ import java.sql.Date; import java.sql.SQLException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import javax.sql.DataSource; import com.netflix.conductor.common.metadata.events.EventExecution; import com.netflix.conductor.common.metadata.tasks.PollData; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.dao.ConcurrentExecutionLimitDAO; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.dao.PollDataDAO; import com.netflix.conductor.dao.RateLimitingDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.postgres.util.Query; import com.fasterxml.jackson.databind.ObjectMapper; @@ -66,7 +62,7 @@ private static String dateStr(Date date) { } @Override - public List getPendingTasksByWorkflow(String taskDefName, String workflowId) { + public List getPendingTasksByWorkflow(String taskDefName, String workflowId) { // @formatter:off String GET_IN_PROGRESS_TASKS_FOR_WORKFLOW = "SELECT json_data FROM task_in_progress tip " @@ -79,17 +75,17 @@ public List getPendingTasksByWorkflow(String taskDefName, String workflowI q -> q.addParameter(taskDefName) .addParameter(workflowId) - .executeAndFetch(Task.class)); + .executeAndFetch(TaskModel.class)); } @Override - public List getTasks(String taskDefName, String startKey, int count) { - List tasks = new ArrayList<>(count); + public List getTasks(String taskDefName, String startKey, int count) { + List tasks = new ArrayList<>(count); - List pendingTasks = getPendingTasksForTaskType(taskDefName); + List pendingTasks = getPendingTasksForTaskType(taskDefName); boolean startKeyFound = startKey == null; int found = 0; - for (Task pendingTask : pendingTasks) { + for (TaskModel pendingTask : pendingTasks) { if (!startKeyFound) { if (pendingTask.getTaskId().equals(startKey)) { startKeyFound = true; @@ -108,15 +104,15 @@ public List getTasks(String taskDefName, String startKey, int count) { return tasks; } - private static String taskKey(Task task) { + private static String taskKey(TaskModel task) { return task.getReferenceTaskName() + "_" + task.getRetryCount(); } @Override - public List createTasks(List tasks) { - List created = Lists.newArrayListWithCapacity(tasks.size()); + public List createTasks(List tasks) { + List created = Lists.newArrayListWithCapacity(tasks.size()); - for (Task task : tasks) { + for (TaskModel task : tasks) { withTransaction( connection -> { validate(task); @@ -151,7 +147,7 @@ public List createTasks(List tasks) { } @Override - public void updateTask(Task task) { + public void updateTask(TaskModel task) { withTransaction(connection -> updateTask(connection, task)); } @@ -161,15 +157,15 @@ public void updateTask(Task task) { * @param task: which needs to be evaluated whether it is rateLimited or not */ @Override - public boolean exceedsRateLimitPerFrequency(Task task, TaskDef taskDef) { + public boolean exceedsRateLimitPerFrequency(TaskModel task, TaskDef taskDef) { return false; } @Override - public boolean exceedsLimit(Task task) { + public boolean exceedsLimit(TaskModel task) { Optional taskDefinition = task.getTaskDefinition(); - if (!taskDefinition.isPresent()) { + if (taskDefinition.isEmpty()) { return false; } @@ -214,7 +210,7 @@ public boolean exceedsLimit(Task task) { @Override public boolean removeTask(String taskId) { - Task task = getTask(taskId); + TaskModel task = getTask(taskId); if (task == null) { logger.warn("No such task found by id {}", taskId); @@ -234,14 +230,14 @@ public boolean removeTask(String taskId) { } @Override - public Task getTask(String taskId) { + public TaskModel getTask(String taskId) { String GET_TASK = "SELECT json_data FROM task WHERE task_id = ?"; return queryWithTransaction( - GET_TASK, q -> q.addParameter(taskId).executeAndFetchFirst(Task.class)); + GET_TASK, q -> q.addParameter(taskId).executeAndFetchFirst(TaskModel.class)); } @Override - public List getTasks(List taskIds) { + public List getTasks(List taskIds) { if (taskIds.isEmpty()) { return Lists.newArrayList(); } @@ -249,7 +245,7 @@ public List getTasks(List taskIds) { } @Override - public List getPendingTasksForTaskType(String taskName) { + public List getPendingTasksForTaskType(String taskName) { Preconditions.checkNotNull(taskName, "task name cannot be null"); // @formatter:off String GET_IN_PROGRESS_TASKS_FOR_TYPE = @@ -260,11 +256,11 @@ public List getPendingTasksForTaskType(String taskName) { return queryWithTransaction( GET_IN_PROGRESS_TASKS_FOR_TYPE, - q -> q.addParameter(taskName).executeAndFetch(Task.class)); + q -> q.addParameter(taskName).executeAndFetch(TaskModel.class)); } @Override - public List getTasksForWorkflow(String workflowId) { + public List getTasksForWorkflow(String workflowId) { String GET_TASKS_FOR_WORKFLOW = "SELECT task_id FROM workflow_to_task WHERE workflow_id = ? FOR SHARE"; return getWithRetriedTransactions( @@ -281,19 +277,19 @@ public List getTasksForWorkflow(String workflowId) { } @Override - public String createWorkflow(Workflow workflow) { + public String createWorkflow(WorkflowModel workflow) { return insertOrUpdateWorkflow(workflow, false); } @Override - public String updateWorkflow(Workflow workflow) { + public String updateWorkflow(WorkflowModel workflow) { return insertOrUpdateWorkflow(workflow, true); } @Override public boolean removeWorkflow(String workflowId) { boolean removed = false; - Workflow workflow = getWorkflow(workflowId, true); + WorkflowModel workflow = getWorkflow(workflowId, true); if (workflow != null) { withTransaction( connection -> { @@ -303,7 +299,7 @@ public boolean removeWorkflow(String workflowId) { }); removed = true; - for (Task task : workflow.getTasks()) { + for (TaskModel task : workflow.getTasks()) { if (!removeTask(task.getTaskId())) { removed = false; } @@ -328,20 +324,20 @@ public void removeFromPendingWorkflow(String workflowType, String workflowId) { } @Override - public Workflow getWorkflow(String workflowId) { + public WorkflowModel getWorkflow(String workflowId) { return getWorkflow(workflowId, true); } @Override - public Workflow getWorkflow(String workflowId, boolean includeTasks) { - Workflow workflow = getWithRetriedTransactions(tx -> readWorkflow(tx, workflowId)); + public WorkflowModel getWorkflow(String workflowId, boolean includeTasks) { + WorkflowModel workflow = getWithRetriedTransactions(tx -> readWorkflow(tx, workflowId)); if (workflow != null) { if (includeTasks) { - List tasks = getTasksForWorkflow(workflowId); + List tasks = getTasksForWorkflow(workflowId); tasks.sort( - Comparator.comparingLong(Task::getScheduledTime) - .thenComparingInt(Task::getSeq)); + Comparator.comparingLong(TaskModel::getScheduledTime) + .thenComparingInt(TaskModel::getSeq)); workflow.setTasks(tasks); } } @@ -371,7 +367,7 @@ public List getRunningWorkflowIds(String workflowName, int version) { * @return list of workflows that are in RUNNING state */ @Override - public List getPendingWorkflowsByType(String workflowName, int version) { + public List getPendingWorkflowsByType(String workflowName, int version) { Preconditions.checkNotNull(workflowName, "workflowName cannot be null"); return getRunningWorkflowIds(workflowName, version).stream() .map(this::getWorkflow) @@ -399,12 +395,13 @@ public long getInProgressTaskCount(String taskDefName) { } @Override - public List getWorkflowsByType(String workflowName, Long startTime, Long endTime) { + public List getWorkflowsByType( + String workflowName, Long startTime, Long endTime) { Preconditions.checkNotNull(workflowName, "workflowName cannot be null"); Preconditions.checkNotNull(startTime, "startTime cannot be null"); Preconditions.checkNotNull(endTime, "endTime cannot be null"); - List workflows = new LinkedList<>(); + List workflows = new LinkedList<>(); withTransaction( tx -> { @@ -426,7 +423,7 @@ public List getWorkflowsByType(String workflowName, Long startTime, Lo workflowIds.forEach( workflowId -> { try { - Workflow wf = getWorkflow(workflowId); + WorkflowModel wf = getWorkflow(workflowId); if (wf.getCreateTime() >= startTime && wf.getCreateTime() <= endTime) { workflows.add(wf); @@ -445,7 +442,7 @@ public List getWorkflowsByType(String workflowName, Long startTime, Lo } @Override - public List getWorkflowsByCorrelationId( + public List getWorkflowsByCorrelationId( String workflowName, String correlationId, boolean includeTasks) { Preconditions.checkNotNull(correlationId, "correlationId cannot be null"); String GET_WORKFLOWS_BY_CORRELATION_ID = @@ -456,7 +453,7 @@ public List getWorkflowsByCorrelationId( q -> q.addParameter(correlationId) .addParameter(workflowName) - .executeAndFetch(Workflow.class)); + .executeAndFetch(WorkflowModel.class)); } @Override @@ -574,7 +571,7 @@ public List getAllPollData() { } } - private List getTasks(Connection connection, List taskIds) { + private List getTasks(Connection connection, List taskIds) { if (taskIds.isEmpty()) { return Lists.newArrayList(); } @@ -589,15 +586,15 @@ private List getTasks(Connection connection, List taskIds) { return query( connection, GET_TASKS_FOR_IDS, - q -> q.addParameters(taskIds).executeAndFetch(Task.class)); + q -> q.addParameters(taskIds).executeAndFetch(TaskModel.class)); } - private String insertOrUpdateWorkflow(Workflow workflow, boolean update) { + private String insertOrUpdateWorkflow(WorkflowModel workflow, boolean update) { Preconditions.checkNotNull(workflow, "workflow object cannot be null"); boolean terminal = workflow.getStatus().isTerminal(); - List tasks = workflow.getTasks(); + List tasks = workflow.getTasks(); workflow.setTasks(Lists.newLinkedList()); withTransaction( @@ -622,12 +619,13 @@ private String insertOrUpdateWorkflow(Workflow workflow, boolean update) { return workflow.getWorkflowId(); } - private void updateTask(Connection connection, Task task) { + private void updateTask(Connection connection, TaskModel task) { Optional taskDefinition = task.getTaskDefinition(); if (taskDefinition.isPresent() && taskDefinition.get().concurrencyLimit() > 0) { boolean inProgress = - task.getStatus() != null && task.getStatus().equals(Task.Status.IN_PROGRESS); + task.getStatus() != null + && task.getStatus().equals(TaskModel.Status.IN_PROGRESS); updateInProgressStatus(connection, task, inProgress); } @@ -640,16 +638,16 @@ private void updateTask(Connection connection, Task task) { addWorkflowToTaskMapping(connection, task); } - private Workflow readWorkflow(Connection connection, String workflowId) { + private WorkflowModel readWorkflow(Connection connection, String workflowId) { String GET_WORKFLOW = "SELECT json_data FROM workflow WHERE workflow_id = ?"; return query( connection, GET_WORKFLOW, - q -> q.addParameter(workflowId).executeAndFetchFirst(Workflow.class)); + q -> q.addParameter(workflowId).executeAndFetchFirst(WorkflowModel.class)); } - private void addWorkflow(Connection connection, Workflow workflow) { + private void addWorkflow(Connection connection, WorkflowModel workflow) { String INSERT_WORKFLOW = "INSERT INTO workflow (workflow_id, correlation_id, json_data) VALUES (?, ?, ?)"; @@ -663,7 +661,7 @@ private void addWorkflow(Connection connection, Workflow workflow) { .executeUpdate()); } - private void updateWorkflow(Connection connection, Workflow workflow) { + private void updateWorkflow(Connection connection, WorkflowModel workflow) { String UPDATE_WORKFLOW = "UPDATE workflow SET json_data = ?, modified_on = CURRENT_TIMESTAMP WHERE workflow_id = ?"; @@ -714,7 +712,7 @@ private void removePendingWorkflow( q -> q.addParameter(workflowType).addParameter(workflowId).executeDelete()); } - private void insertOrUpdateTaskData(Connection connection, Task task) { + private void insertOrUpdateTaskData(Connection connection, TaskModel task) { /* * Most times the row will be updated so let's try the update first. This used to be an 'INSERT/ON CONFLICT do update' sql statement. The problem with that * is that if we try the INSERT first, the sequence will be increased even if the ON CONFLICT happens. @@ -740,12 +738,12 @@ private void insertOrUpdateTaskData(Connection connection, Task task) { } } - private void removeTaskData(Connection connection, Task task) { + private void removeTaskData(Connection connection, TaskModel task) { String REMOVE_TASK = "DELETE FROM task WHERE task_id = ?"; execute(connection, REMOVE_TASK, q -> q.addParameter(task.getTaskId()).executeDelete()); } - private void addWorkflowToTaskMapping(Connection connection, Task task) { + private void addWorkflowToTaskMapping(Connection connection, TaskModel task) { String EXISTS_WORKFLOW_TO_TASK = "SELECT EXISTS(SELECT 1 FROM workflow_to_task WHERE workflow_id = ? AND task_id = ?)"; @@ -773,7 +771,7 @@ private void addWorkflowToTaskMapping(Connection connection, Task task) { } } - private void removeWorkflowToTaskMapping(Connection connection, Task task) { + private void removeWorkflowToTaskMapping(Connection connection, TaskModel task) { String REMOVE_WORKFLOW_TO_TASK = "DELETE FROM workflow_to_task WHERE workflow_id = ? AND task_id = ?"; @@ -786,7 +784,7 @@ private void removeWorkflowToTaskMapping(Connection connection, Task task) { .executeDelete()); } - private void addWorkflowDefToWorkflowMapping(Connection connection, Workflow workflow) { + private void addWorkflowDefToWorkflowMapping(Connection connection, WorkflowModel workflow) { String INSERT_WORKFLOW_DEF_TO_WORKFLOW = "INSERT INTO workflow_def_to_workflow (workflow_def, date_str, workflow_id) VALUES (?, ?, ?)"; @@ -800,7 +798,7 @@ private void addWorkflowDefToWorkflowMapping(Connection connection, Workflow wor .executeUpdate()); } - private void removeWorkflowDefToWorkflowMapping(Connection connection, Workflow workflow) { + private void removeWorkflowDefToWorkflowMapping(Connection connection, WorkflowModel workflow) { String REMOVE_WORKFLOW_DEF_TO_WORKFLOW = "DELETE FROM workflow_def_to_workflow WHERE workflow_def = ? AND date_str = ? AND workflow_id = ?"; @@ -815,7 +813,7 @@ private void removeWorkflowDefToWorkflowMapping(Connection connection, Workflow } @VisibleForTesting - boolean addScheduledTask(Connection connection, Task task, String taskKey) { + boolean addScheduledTask(Connection connection, TaskModel task, String taskKey) { final String EXISTS_SCHEDULED_TASK = "SELECT EXISTS(SELECT 1 FROM task_scheduled where workflow_id = ? AND task_key = ?)"; @@ -848,7 +846,7 @@ boolean addScheduledTask(Connection connection, Task task, String taskKey) { } } - private void removeScheduledTask(Connection connection, Task task, String taskKey) { + private void removeScheduledTask(Connection connection, TaskModel task, String taskKey) { String REMOVE_SCHEDULED_TASK = "DELETE FROM task_scheduled WHERE workflow_id = ? AND task_key = ?"; execute( @@ -860,7 +858,7 @@ private void removeScheduledTask(Connection connection, Task task, String taskKe .executeDelete()); } - private void addTaskInProgress(Connection connection, Task task) { + private void addTaskInProgress(Connection connection, TaskModel task) { String EXISTS_IN_PROGRESS_TASK = "SELECT EXISTS(SELECT 1 FROM task_in_progress WHERE task_def_name = ? AND task_id = ?)"; @@ -888,7 +886,7 @@ private void addTaskInProgress(Connection connection, Task task) { } } - private void removeTaskInProgress(Connection connection, Task task) { + private void removeTaskInProgress(Connection connection, TaskModel task) { String REMOVE_IN_PROGRESS_TASK = "DELETE FROM task_in_progress WHERE task_def_name = ? AND task_id = ?"; @@ -901,7 +899,7 @@ private void removeTaskInProgress(Connection connection, Task task) { .executeUpdate()); } - private void updateInProgressStatus(Connection connection, Task task, boolean inProgress) { + private void updateInProgressStatus(Connection connection, TaskModel task, boolean inProgress) { String UPDATE_IN_PROGRESS_TASK_STATUS = "UPDATE task_in_progress SET in_progress_status = ?, modified_on = CURRENT_TIMESTAMP " + "WHERE task_def_name = ? AND task_id = ?"; @@ -1053,7 +1051,7 @@ private List readAllPollData(String queueName) { GET_ALL_POLL_DATA, q -> q.addParameter(queueName).executeAndFetch(PollData.class)); } - private List findAllTasksInProgressInOrderOfArrival(Task task, int limit) { + private List findAllTasksInProgressInOrderOfArrival(TaskModel task, int limit) { String GET_IN_PROGRESS_TASKS_WITH_LIMIT = "SELECT task_id FROM task_in_progress WHERE task_def_name = ? ORDER BY created_on LIMIT ?"; @@ -1065,7 +1063,7 @@ private List findAllTasksInProgressInOrderOfArrival(Task task, int limit .executeScalarList(String.class)); } - private void validate(Task task) { + private void validate(TaskModel task) { Preconditions.checkNotNull(task, "task object cannot be null"); Preconditions.checkNotNull(task.getTaskId(), "Task id cannot be null"); Preconditions.checkNotNull( diff --git a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAO.java b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAO.java index da8a2dd317..b461a399e1 100644 --- a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAO.java +++ b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresQueueDAO.java b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresQueueDAO.java index 4acc8ec996..8b4175f653 100644 --- a/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresQueueDAO.java +++ b/postgres-persistence/src/main/java/com/netflix/conductor/postgres/dao/PostgresQueueDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAOTest.java b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAOTest.java index be471c1502..3fb12ab8c9 100644 --- a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAOTest.java +++ b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresExecutionDAOTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -26,9 +26,9 @@ import com.netflix.conductor.common.config.TestObjectMapperConfiguration; import com.netflix.conductor.common.metadata.workflow.WorkflowDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.dao.ExecutionDAOTest; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.postgres.config.PostgresConfiguration; import static org.junit.Assert.assertEquals; @@ -61,12 +61,12 @@ public void testPendingByCorrelationId() { WorkflowDef def = new WorkflowDef(); def.setName("pending_count_correlation_jtest"); - Workflow workflow = createTestWorkflow(); + WorkflowModel workflow = createTestWorkflow(); workflow.setWorkflowDefinition(def); generateWorkflows(workflow, 10); - List bycorrelationId = + List bycorrelationId = getExecutionDAO() .getWorkflowsByCorrelationId( "pending_count_correlation_jtest", "corr001", true); @@ -79,7 +79,7 @@ public void testRemoveWorkflow() { WorkflowDef def = new WorkflowDef(); def.setName("workflow"); - Workflow workflow = createTestWorkflow(); + WorkflowModel workflow = createTestWorkflow(); workflow.setWorkflowDefinition(def); List ids = generateWorkflows(workflow, 1); diff --git a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAOTest.java b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAOTest.java index 2cc7ec7fec..b9a03ebd1a 100644 --- a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAOTest.java +++ b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresMetadataDAOTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresQueueDAOTest.java b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresQueueDAOTest.java index 02db8c50c4..d435d2bfb9 100644 --- a/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresQueueDAOTest.java +++ b/postgres-persistence/src/test/java/com/netflix/conductor/postgres/dao/PostgresQueueDAOTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/redis-concurrency-limit/src/main/java/com/netflix/conductor/redis/limit/RedisConcurrentExecutionLimitDAO.java b/redis-concurrency-limit/src/main/java/com/netflix/conductor/redis/limit/RedisConcurrentExecutionLimitDAO.java index d8990fce5f..4107997252 100644 --- a/redis-concurrency-limit/src/main/java/com/netflix/conductor/redis/limit/RedisConcurrentExecutionLimitDAO.java +++ b/redis-concurrency-limit/src/main/java/com/netflix/conductor/redis/limit/RedisConcurrentExecutionLimitDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -23,11 +23,11 @@ import org.springframework.stereotype.Component; import com.netflix.conductor.annotations.Trace; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.dao.ConcurrentExecutionLimitDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; import com.netflix.conductor.redis.limit.config.RedisConcurrentExecutionLimitProperties; @Trace @@ -52,12 +52,12 @@ public RedisConcurrentExecutionLimitDAO( } /** - * Adds the {@link Task} identifier to a Redis Set for the {@link TaskDef}'s name. + * Adds the {@link TaskModel} identifier to a Redis Set for the {@link TaskDef}'s name. * - * @param task The {@link Task} object. + * @param task The {@link TaskModel} object. */ @Override - public void addTaskToLimit(Task task) { + public void addTaskToLimit(TaskModel task) { try { Monitors.recordDaoRequests( CLASS_NAME, "addTaskToLimit", task.getTaskType(), task.getWorkflowType()); @@ -80,12 +80,12 @@ public void addTaskToLimit(Task task) { } /** - * Remove the {@link Task} identifier from the Redis Set for the {@link TaskDef}'s name. + * Remove the {@link TaskModel} identifier from the Redis Set for the {@link TaskDef}'s name. * - * @param task The {@link Task} object. + * @param task The {@link TaskModel} object. */ @Override - public void removeTaskFromLimit(Task task) { + public void removeTaskFromLimit(TaskModel task) { try { Monitors.recordDaoRequests( CLASS_NAME, "removeTaskFromLimit", task.getTaskType(), task.getWorkflowType()); @@ -109,15 +109,15 @@ public void removeTaskFromLimit(Task task) { } /** - * Checks if the {@link Task} identifier is in the Redis Set and size of the set is more than - * the {@link TaskDef#concurrencyLimit()}. + * Checks if the {@link TaskModel} identifier is in the Redis Set and size of the set is more + * than the {@link TaskDef#concurrencyLimit()}. * - * @param task The {@link Task} object. + * @param task The {@link TaskModel} object. * @return true if the task id is not in the set and size of the set is more than the {@link * TaskDef#concurrencyLimit()}. */ @Override - public boolean exceedsLimit(Task task) { + public boolean exceedsLimit(TaskModel task) { Optional taskDefinition = task.getTaskDefinition(); if (taskDefinition.isEmpty()) { return false; diff --git a/redis-concurrency-limit/src/test/groovy/com/netflix/conductor/redis/limit/RedisConcurrentExecutionLimitDAOSpec.groovy b/redis-concurrency-limit/src/test/groovy/com/netflix/conductor/redis/limit/RedisConcurrentExecutionLimitDAOSpec.groovy index e74039387d..c14bc38001 100644 --- a/redis-concurrency-limit/src/test/groovy/com/netflix/conductor/redis/limit/RedisConcurrentExecutionLimitDAOSpec.groovy +++ b/redis-concurrency-limit/src/test/groovy/com/netflix/conductor/redis/limit/RedisConcurrentExecutionLimitDAOSpec.groovy @@ -1,27 +1,28 @@ /* - * Copyright 2021 Netflix, Inc. - *

    - * 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. + * Copyright 2022 Netflix, Inc. + *

    + * 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.redis.limit -import com.netflix.conductor.common.metadata.tasks.Task -import com.netflix.conductor.common.metadata.tasks.TaskDef -import com.netflix.conductor.common.metadata.workflow.WorkflowTask -import com.netflix.conductor.redis.limit.config.RedisConcurrentExecutionLimitProperties import org.springframework.data.redis.connection.RedisStandaloneConfiguration import org.springframework.data.redis.connection.jedis.JedisConnectionFactory import org.springframework.data.redis.core.StringRedisTemplate import org.testcontainers.containers.GenericContainer import org.testcontainers.spock.Testcontainers + +import com.netflix.conductor.common.metadata.tasks.TaskDef +import com.netflix.conductor.common.metadata.workflow.WorkflowTask +import com.netflix.conductor.model.TaskModel +import com.netflix.conductor.redis.limit.config.RedisConcurrentExecutionLimitProperties + import spock.lang.Specification import spock.lang.Subject import spock.lang.Unroll @@ -51,7 +52,7 @@ class RedisConcurrentExecutionLimitDAOSpec extends Specification { def taskDefName = 'task_def_name1' def keyName = "${properties.namespace}:$taskDefName" as String - Task task = new Task(taskId: taskId, taskDefName: taskDefName) + TaskModel task = new TaskModel(taskId: taskId, taskDefName: taskDefName) when: dao.addTaskToLimit(task) @@ -70,7 +71,7 @@ class RedisConcurrentExecutionLimitDAOSpec extends Specification { redisTemplate.opsForSet().add(keyName, taskId) - Task task = new Task(taskId: taskId, taskDefName: taskDefName) + TaskModel task = new TaskModel(taskId: taskId, taskDefName: taskDefName) when: dao.removeTaskFromLimit(task) @@ -85,7 +86,7 @@ class RedisConcurrentExecutionLimitDAOSpec extends Specification { def taskId = 'task1' def taskDefName = 'task_def_name1' - Task task = new Task(taskId: taskId, taskDefName: taskDefName, workflowTask: workflowTask) + TaskModel task = new TaskModel(taskId: taskId, taskDefName: taskDefName, workflowTask: workflowTask) when: def retVal = dao.exceedsLimit(task) @@ -104,7 +105,7 @@ class RedisConcurrentExecutionLimitDAOSpec extends Specification { def taskDefName = 'task_def_name1' def keyName = "${properties.namespace}:$taskDefName" as String - Task task = new Task(taskId: taskId, taskDefName: taskDefName, workflowTask: new WorkflowTask(taskDefinition: new TaskDef(concurrentExecLimit: 2))) + TaskModel task = new TaskModel(taskId: taskId, taskDefName: taskDefName, workflowTask: new WorkflowTask(taskDefinition: new TaskDef(concurrentExecLimit: 2))) redisTemplate.opsForSet().add(keyName, taskId) @@ -121,7 +122,7 @@ class RedisConcurrentExecutionLimitDAOSpec extends Specification { def taskDefName = 'task_def_name1' def keyName = "${properties.namespace}:$taskDefName" as String - Task task = new Task(taskId: taskId, taskDefName: taskDefName, workflowTask: new WorkflowTask(taskDefinition: new TaskDef(concurrentExecLimit: 2))) + TaskModel task = new TaskModel(taskId: taskId, taskDefName: taskDefName, workflowTask: new WorkflowTask(taskDefinition: new TaskDef(concurrentExecLimit: 2))) redisTemplate.opsForSet().add(keyName, taskId) // add the id of the task passed as argument to exceedsLimit redisTemplate.opsForSet().add(keyName, 'taskId2') @@ -139,7 +140,7 @@ class RedisConcurrentExecutionLimitDAOSpec extends Specification { def taskDefName = 'task_def_name1' def keyName = "${properties.namespace}:$taskDefName" as String - Task task = new Task(taskId: taskId, taskDefName: taskDefName, workflowTask: new WorkflowTask(taskDefinition: new TaskDef(concurrentExecLimit: 2))) + TaskModel task = new TaskModel(taskId: taskId, taskDefName: taskDefName, workflowTask: new WorkflowTask(taskDefinition: new TaskDef(concurrentExecLimit: 2))) // add task ids different from the id of the task passed to exceedsLimit redisTemplate.opsForSet().add(keyName, 'taskId2') diff --git a/redis-lock/build.gradle b/redis-lock/build.gradle index fd81d4d9a3..bc3c074cb4 100644 --- a/redis-lock/build.gradle +++ b/redis-lock/build.gradle @@ -1,5 +1,4 @@ dependencies { - implementation project(':conductor-common') implementation project(':conductor-core') compileOnly 'org.springframework.boot:spring-boot-starter' diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/BaseDynoDAO.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/BaseDynoDAO.java index 8b9e2d54fc..bdf881fbbc 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/BaseDynoDAO.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/BaseDynoDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/DynoQueueDAO.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/DynoQueueDAO.java index ea28adef41..3901931dc4 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/DynoQueueDAO.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/DynoQueueDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisEventHandlerDAO.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisEventHandlerDAO.java index e275be25a7..263e4ec77f 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisEventHandlerDAO.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisEventHandlerDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisExecutionDAO.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisExecutionDAO.java index 81e17b4efd..f41d413569 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisExecutionDAO.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisExecutionDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -13,16 +13,7 @@ package com.netflix.conductor.redis.dao; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Comparator; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import org.slf4j.Logger; @@ -31,16 +22,15 @@ import org.springframework.stereotype.Component; import com.netflix.conductor.common.metadata.events.EventExecution; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.metadata.tasks.TaskDef; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.core.exception.ApplicationException; import com.netflix.conductor.core.exception.ApplicationException.Code; import com.netflix.conductor.dao.ConcurrentExecutionLimitDAO; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.redis.config.AnyRedisCondition; import com.netflix.conductor.redis.config.RedisProperties; import com.netflix.conductor.redis.jedis.JedisProxy; @@ -106,10 +96,10 @@ private static List dateStrBetweenDates(Long startdatems, Long enddatems } @Override - public List getPendingTasksByWorkflow(String taskName, String workflowId) { - List tasks = new LinkedList<>(); + public List getPendingTasksByWorkflow(String taskName, String workflowId) { + List tasks = new LinkedList<>(); - List pendingTasks = getPendingTasksForTaskType(taskName); + List pendingTasks = getPendingTasksForTaskType(taskName); pendingTasks.forEach( pendingTask -> { if (pendingTask.getWorkflowInstanceId().equals(workflowId)) { @@ -121,13 +111,13 @@ public List getPendingTasksByWorkflow(String taskName, String workflowId) } @Override - public List getTasks(String taskDefName, String startKey, int count) { - List tasks = new LinkedList<>(); + public List getTasks(String taskDefName, String startKey, int count) { + List tasks = new LinkedList<>(); - List pendingTasks = getPendingTasksForTaskType(taskDefName); + List pendingTasks = getPendingTasksForTaskType(taskDefName); boolean startKeyFound = startKey == null; int foundcount = 0; - for (Task pendingTask : pendingTasks) { + for (TaskModel pendingTask : pendingTasks) { if (!startKeyFound) { if (pendingTask.getTaskId().equals(startKey)) { startKeyFound = true; @@ -145,11 +135,11 @@ public List getTasks(String taskDefName, String startKey, int count) { } @Override - public List createTasks(List tasks) { + public List createTasks(List tasks) { - List tasksCreated = new LinkedList<>(); + List tasksCreated = new LinkedList<>(); - for (Task task : tasks) { + for (TaskModel task : tasks) { validate(task); recordRedisDaoRequests("createTask", task.getTaskType(), task.getWorkflowType()); @@ -201,12 +191,12 @@ public List createTasks(List tasks) { } @Override - public void updateTask(Task task) { + public void updateTask(TaskModel task) { Optional taskDefinition = task.getTaskDefinition(); if (taskDefinition.isPresent() && taskDefinition.get().concurrencyLimit() > 0) { - if (task.getStatus() != null && task.getStatus().equals(Status.IN_PROGRESS)) { + if (task.getStatus() != null && task.getStatus().equals(TaskModel.Status.IN_PROGRESS)) { jedisProxy.sadd( nsKey(TASKS_IN_PROGRESS_STATUS, task.getTaskDefName()), task.getTaskId()); LOGGER.debug( @@ -272,7 +262,7 @@ public void updateTask(Task task) { } @Override - public boolean exceedsLimit(Task task) { + public boolean exceedsLimit(TaskModel task) { Optional taskDefinition = task.getTaskDefinition(); if (taskDefinition.isEmpty()) { return false; @@ -320,7 +310,7 @@ public boolean exceedsLimit(Task task) { return rateLimited; } - private void removeTaskMappings(Task task) { + private void removeTaskMappings(TaskModel task) { String taskKey = task.getReferenceTaskName() + "" + task.getRetryCount(); jedisProxy.hdel(nsKey(SCHEDULED_TASKS, task.getWorkflowInstanceId()), taskKey); @@ -330,7 +320,7 @@ private void removeTaskMappings(Task task) { jedisProxy.zrem(nsKey(TASK_LIMIT_BUCKET, task.getTaskDefName()), task.getTaskId()); } - private void removeTaskMappingsWithExpiry(Task task) { + private void removeTaskMappingsWithExpiry(TaskModel task) { String taskKey = task.getReferenceTaskName() + "" + task.getRetryCount(); jedisProxy.hdel(nsKey(SCHEDULED_TASKS, task.getWorkflowInstanceId()), taskKey); @@ -341,7 +331,7 @@ private void removeTaskMappingsWithExpiry(Task task) { @Override public boolean removeTask(String taskId) { - Task task = getTask(taskId); + TaskModel task = getTask(taskId); if (task == null) { LOGGER.warn("No such task found by id {}", taskId); return false; @@ -354,7 +344,7 @@ public boolean removeTask(String taskId) { } private boolean removeTaskWithExpiry(String taskId, int ttlSeconds) { - Task task = getTask(taskId); + TaskModel task = getTask(taskId); if (task == null) { LOGGER.warn("No such task found by id {}", taskId); return false; @@ -367,12 +357,12 @@ private boolean removeTaskWithExpiry(String taskId, int ttlSeconds) { } @Override - public Task getTask(String taskId) { + public TaskModel getTask(String taskId) { Preconditions.checkNotNull(taskId, "taskId cannot be null"); return Optional.ofNullable(jedisProxy.get(nsKey(TASK, taskId))) .map( json -> { - Task task = readValue(json, Task.class); + TaskModel task = readValue(json, TaskModel.class); recordRedisDaoRequests( "getTask", task.getTaskType(), task.getWorkflowType()); recordRedisDaoPayloadSize( @@ -386,14 +376,14 @@ public Task getTask(String taskId) { } @Override - public List getTasks(List taskIds) { + public List getTasks(List taskIds) { return taskIds.stream() .map(taskId -> nsKey(TASK, taskId)) .map(jedisProxy::get) .filter(Objects::nonNull) .map( jsonString -> { - Task task = readValue(jsonString, Task.class); + TaskModel task = readValue(jsonString, TaskModel.class); recordRedisDaoRequests( "getTask", task.getTaskType(), task.getWorkflowType()); recordRedisDaoPayloadSize( @@ -407,7 +397,7 @@ public List getTasks(List taskIds) { } @Override - public List getTasksForWorkflow(String workflowId) { + public List getTasksForWorkflow(String workflowId) { Preconditions.checkNotNull(workflowId, "workflowId cannot be null"); Set taskIds = jedisProxy.smembers(nsKey(WORKFLOW_TO_TASKS, workflowId)); recordRedisDaoRequests("getTasksForWorkflow"); @@ -415,7 +405,7 @@ public List getTasksForWorkflow(String workflowId) { } @Override - public List getPendingTasksForTaskType(String taskName) { + public List getPendingTasksForTaskType(String taskName) { Preconditions.checkNotNull(taskName, "task name cannot be null"); Set taskIds = jedisProxy.smembers(nsKey(IN_PROGRESS_TASKS, taskName)); recordRedisDaoRequests("getPendingTasksForTaskType"); @@ -423,18 +413,18 @@ public List getPendingTasksForTaskType(String taskName) { } @Override - public String createWorkflow(Workflow workflow) { + public String createWorkflow(WorkflowModel workflow) { return insertOrUpdateWorkflow(workflow, false); } @Override - public String updateWorkflow(Workflow workflow) { + public String updateWorkflow(WorkflowModel workflow) { return insertOrUpdateWorkflow(workflow, true); } @Override public boolean removeWorkflow(String workflowId) { - Workflow workflow = getWorkflow(workflowId, true); + WorkflowModel workflow = getWorkflow(workflowId, true); if (workflow != null) { recordRedisDaoRequests("removeWorkflow"); @@ -450,7 +440,7 @@ public boolean removeWorkflow(String workflowId) { // Remove the object jedisProxy.del(nsKey(WORKFLOW, workflowId)); - for (Task task : workflow.getTasks()) { + for (TaskModel task : workflow.getTasks()) { removeTask(task.getTaskId()); } return true; @@ -459,7 +449,7 @@ public boolean removeWorkflow(String workflowId) { } public boolean removeWorkflowWithExpiry(String workflowId, int ttlSeconds) { - Workflow workflow = getWorkflow(workflowId, true); + WorkflowModel workflow = getWorkflow(workflowId, true); if (workflow != null) { recordRedisDaoRequests("removeWorkflow"); @@ -475,7 +465,7 @@ public boolean removeWorkflowWithExpiry(String workflowId, int ttlSeconds) { // Remove the object jedisProxy.expire(nsKey(WORKFLOW, workflowId), ttlSeconds); - for (Task task : workflow.getTasks()) { + for (TaskModel task : workflow.getTasks()) { removeTaskWithExpiry(task.getTaskId(), ttlSeconds); } jedisProxy.expire(nsKey(WORKFLOW_TO_TASKS, workflowId), ttlSeconds); @@ -493,25 +483,25 @@ public void removeFromPendingWorkflow(String workflowType, String workflowId) { } @Override - public Workflow getWorkflow(String workflowId) { + public WorkflowModel getWorkflow(String workflowId) { return getWorkflow(workflowId, true); } @Override - public Workflow getWorkflow(String workflowId, boolean includeTasks) { + public WorkflowModel getWorkflow(String workflowId, boolean includeTasks) { String json = jedisProxy.get(nsKey(WORKFLOW, workflowId)); - Workflow workflow = null; + WorkflowModel workflow = null; if (json != null) { - workflow = readValue(json, Workflow.class); + workflow = readValue(json, WorkflowModel.class); recordRedisDaoRequests("getWorkflow", "n/a", workflow.getWorkflowName()); recordRedisDaoPayloadSize( "getWorkflow", json.length(), "n/a", workflow.getWorkflowName()); if (includeTasks) { - List tasks = getTasksForWorkflow(workflowId); + List tasks = getTasksForWorkflow(workflowId); tasks.sort( - Comparator.comparingLong(Task::getScheduledTime) - .thenComparingInt(Task::getSeq)); + Comparator.comparingLong(TaskModel::getScheduledTime) + .thenComparingInt(TaskModel::getSeq)); workflow.setTasks(tasks); } } @@ -540,7 +530,7 @@ public List getRunningWorkflowIds(String workflowName, int version) { * @return list of workflows that are in RUNNING state */ @Override - public List getPendingWorkflowsByType(String workflowName, int version) { + public List getPendingWorkflowsByType(String workflowName, int version) { Preconditions.checkNotNull(workflowName, "workflowName cannot be null"); List workflowIds = getRunningWorkflowIds(workflowName, version); return workflowIds.stream() @@ -550,12 +540,13 @@ public List getPendingWorkflowsByType(String workflowName, int version } @Override - public List getWorkflowsByType(String workflowName, Long startTime, Long endTime) { + public List getWorkflowsByType( + String workflowName, Long startTime, Long endTime) { Preconditions.checkNotNull(workflowName, "workflowName cannot be null"); Preconditions.checkNotNull(startTime, "startTime cannot be null"); Preconditions.checkNotNull(endTime, "endTime cannot be null"); - List workflows = new LinkedList<>(); + List workflows = new LinkedList<>(); // Get all date strings between start and end List dateStrs = dateStrBetweenDates(startTime, endTime); @@ -567,7 +558,7 @@ public List getWorkflowsByType(String workflowName, Long startTime, Lo .forEach( workflowId -> { try { - Workflow workflow = getWorkflow(workflowId); + WorkflowModel workflow = getWorkflow(workflowId); if (workflow.getCreateTime() >= startTime && workflow.getCreateTime() <= endTime) { workflows.add(workflow); @@ -583,7 +574,7 @@ public List getWorkflowsByType(String workflowName, Long startTime, Lo } @Override - public List getWorkflowsByCorrelationId( + public List getWorkflowsByCorrelationId( String workflowName, String correlationId, boolean includeTasks) { throw new UnsupportedOperationException( "This method is not implemented in RedisExecutionDAO. Please use ExecutionDAOFacade instead."); @@ -602,10 +593,10 @@ public boolean canSearchAcrossWorkflows() { * @param update flag to identify if update or create operation * @return the workflowId */ - private String insertOrUpdateWorkflow(Workflow workflow, boolean update) { + private String insertOrUpdateWorkflow(WorkflowModel workflow, boolean update) { Preconditions.checkNotNull(workflow, "workflow object cannot be null"); - List tasks = workflow.getTasks(); + List tasks = workflow.getTasks(); workflow.setTasks(new LinkedList<>()); String payload = toJson(workflow); @@ -772,7 +763,7 @@ public List getEventExecutions( } } - private void validate(Task task) { + private void validate(TaskModel task) { try { Preconditions.checkNotNull(task, "task object cannot be null"); Preconditions.checkNotNull(task.getTaskId(), "Task id cannot be null"); diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisMetadataDAO.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisMetadataDAO.java index df7fa98313..81d671b481 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisMetadataDAO.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisMetadataDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisPollDataDAO.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisPollDataDAO.java index d8e25268ba..717e582a72 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisPollDataDAO.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisPollDataDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisRateLimitingDAO.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisRateLimitingDAO.java index d3b1ef4806..9535dc4cce 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisRateLimitingDAO.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dao/RedisRateLimitingDAO.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,11 +20,11 @@ import org.springframework.context.annotation.Conditional; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.dao.RateLimitingDAO; import com.netflix.conductor.metrics.Monitors; +import com.netflix.conductor.model.TaskModel; import com.netflix.conductor.redis.config.AnyRedisCondition; import com.netflix.conductor.redis.config.RedisProperties; import com.netflix.conductor.redis.jedis.JedisProxy; @@ -49,9 +49,9 @@ public RedisRateLimitingDAO( /** * This method evaluates if the {@link TaskDef} is rate limited or not based on {@link - * Task#getRateLimitPerFrequency()} and {@link Task#getRateLimitFrequencyInSeconds()} if not - * checks the {@link Task} is rate limited or not based on {@link - * Task#getRateLimitPerFrequency()} and {@link Task#getRateLimitFrequencyInSeconds()} + * TaskModel#getRateLimitPerFrequency()} and {@link TaskModel#getRateLimitFrequencyInSeconds()} + * if not checks the {@link TaskModel} is rate limited or not based on {@link + * TaskModel#getRateLimitPerFrequency()} and {@link TaskModel#getRateLimitFrequencyInSeconds()} * *

    The rate limiting is implemented using the Redis constructs of sorted set and TTL of each * element in the rate limited bucket. @@ -62,19 +62,19 @@ public RedisRateLimitingDAO( * make the next step of evaluation efficient *

  • A current count(tasks executed within the frequency) is calculated based on the current * time and the beginning of the rate limit frequency time(which is current time - {@link - * Task#getRateLimitFrequencyInSeconds()} in millis), this is achieved by using {@link - * JedisProxy#zcount(String, double, double)} + * TaskModel#getRateLimitFrequencyInSeconds()} in millis), this is achieved by using + * {@link JedisProxy#zcount(String, double, double)} *
  • Once the count is calculated then a evaluation is made to determine if it is within the - * bounds of {@link Task#getRateLimitPerFrequency()}, if so the count is increased and an - * expiry TTL is added to the entry + * bounds of {@link TaskModel#getRateLimitPerFrequency()}, if so the count is increased + * and an expiry TTL is added to the entry * * * @param task: which needs to be evaluated whether it is rateLimited or not - * @return true: If the {@link Task} is rateLimited false: If the {@link Task} is not + * @return true: If the {@link TaskModel} is rateLimited false: If the {@link TaskModel} is not * rateLimited */ @Override - public boolean exceedsRateLimitPerFrequency(Task task, TaskDef taskDef) { + public boolean exceedsRateLimitPerFrequency(TaskModel task, TaskDef taskDef) { // Check if the TaskDefinition is not null then pick the definition values or else pick from // the Task ImmutablePair rateLimitPair = @@ -107,7 +107,7 @@ public boolean exceedsRateLimitPerFrequency(Task task, TaskDef taskDef) { rateLimitFrequencyInSeconds); long currentTimeEpochMillis = System.currentTimeMillis(); long currentTimeEpochMinusRateLimitBucket = - currentTimeEpochMillis - (rateLimitFrequencyInSeconds * 1000); + currentTimeEpochMillis - (rateLimitFrequencyInSeconds * 1000L); String key = nsKey(TASK_RATE_LIMIT_BUCKET, task.getTaskDefName()); jedisProxy.zremrangeByScore( key, "-inf", String.valueOf(currentTimeEpochMinusRateLimitBucket)); diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/ConfigurationHostSupplier.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/ConfigurationHostSupplier.java index 50f2e85819..eb83b97c06 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/ConfigurationHostSupplier.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/ConfigurationHostSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/LocalhostHostSupplier.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/LocalhostHostSupplier.java index 1abaaa1053..7f1823af80 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/LocalhostHostSupplier.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/LocalhostHostSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/RedisQueuesShardingStrategyProvider.java b/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/RedisQueuesShardingStrategyProvider.java index 52eaf07ce9..2ba4528bb3 100644 --- a/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/RedisQueuesShardingStrategyProvider.java +++ b/redis-persistence/src/main/java/com/netflix/conductor/redis/dynoqueue/RedisQueuesShardingStrategyProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/redis-persistence/src/test/java/com/netflix/conductor/redis/dao/RedisExecutionDAOTest.java b/redis-persistence/src/test/java/com/netflix/conductor/redis/dao/RedisExecutionDAOTest.java index 8f9d69d583..7bc844f399 100644 --- a/redis-persistence/src/test/java/com/netflix/conductor/redis/dao/RedisExecutionDAOTest.java +++ b/redis-persistence/src/test/java/com/netflix/conductor/redis/dao/RedisExecutionDAOTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -24,12 +24,11 @@ import org.springframework.test.context.junit4.SpringRunner; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.core.config.ConductorProperties; import com.netflix.conductor.dao.ExecutionDAO; import com.netflix.conductor.dao.ExecutionDAOTest; +import com.netflix.conductor.model.TaskModel; import com.netflix.conductor.redis.config.RedisProperties; import com.netflix.conductor.redis.jedis.JedisMock; import com.netflix.conductor.redis.jedis.JedisProxy; @@ -72,14 +71,14 @@ public void testCorrelateTaskToWorkflowInDS() { def.setName("task1"); def.setConcurrentExecLimit(1); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskId(taskId); task.setWorkflowInstanceId(workflowId); task.setReferenceTaskName("ref_name"); task.setTaskDefName(taskDefName); task.setTaskType(taskDefName); - task.setStatus(Status.IN_PROGRESS); - List tasks = executionDAO.createTasks(Collections.singletonList(task)); + task.setStatus(TaskModel.Status.IN_PROGRESS); + List tasks = executionDAO.createTasks(Collections.singletonList(task)); assertNotNull(tasks); assertEquals(1, tasks.size()); diff --git a/redis-persistence/src/test/java/com/netflix/conductor/redis/dao/RedisRateLimitDAOTest.java b/redis-persistence/src/test/java/com/netflix/conductor/redis/dao/RedisRateLimitDAOTest.java index d58dfea6bc..30877fc18a 100644 --- a/redis-persistence/src/test/java/com/netflix/conductor/redis/dao/RedisRateLimitDAOTest.java +++ b/redis-persistence/src/test/java/com/netflix/conductor/redis/dao/RedisRateLimitDAOTest.java @@ -22,9 +22,9 @@ import org.springframework.test.context.junit4.SpringRunner; import com.netflix.conductor.common.config.TestObjectMapperConfiguration; -import com.netflix.conductor.common.metadata.tasks.Task; import com.netflix.conductor.common.metadata.tasks.TaskDef; import com.netflix.conductor.core.config.ConductorProperties; +import com.netflix.conductor.model.TaskModel; import com.netflix.conductor.redis.config.RedisProperties; import com.netflix.conductor.redis.jedis.JedisMock; import com.netflix.conductor.redis.jedis.JedisProxy; @@ -58,7 +58,7 @@ public void init() { @Test public void testExceedsRateLimitWhenNoRateLimitSet() { TaskDef taskDef = new TaskDef("TestTaskDefinition"); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskId(UUID.randomUUID().toString()); task.setTaskDefName(taskDef.getName()); assertFalse(rateLimitingDao.exceedsRateLimitPerFrequency(task, taskDef)); @@ -69,7 +69,7 @@ public void testExceedsRateLimitWithinLimit() { TaskDef taskDef = new TaskDef("TestTaskDefinition"); taskDef.setRateLimitFrequencyInSeconds(60); taskDef.setRateLimitPerFrequency(20); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskId(UUID.randomUUID().toString()); task.setTaskDefName(taskDef.getName()); assertFalse(rateLimitingDao.exceedsRateLimitPerFrequency(task, taskDef)); @@ -80,7 +80,7 @@ public void testExceedsRateLimitOutOfLimit() { TaskDef taskDef = new TaskDef("TestTaskDefinition"); taskDef.setRateLimitFrequencyInSeconds(60); taskDef.setRateLimitPerFrequency(1); - Task task = new Task(); + TaskModel task = new TaskModel(); task.setTaskId(UUID.randomUUID().toString()); task.setTaskDefName(taskDef.getName()); assertFalse(rateLimitingDao.exceedsRateLimitPerFrequency(task, taskDef)); diff --git a/test-harness/build.gradle b/test-harness/build.gradle index 381a01abd6..28911ab80c 100644 --- a/test-harness/build.gradle +++ b/test-harness/build.gradle @@ -1,12 +1,5 @@ apply plugin: 'groovy' -spotless { - groovy { - importOrder('java', 'javax', 'org', 'com.netflix', '', '\\#com.netflix', '\\#') - licenseHeaderFile("$rootDir/licenseheader.txt") - } -} - dependencies { testImplementation project(':conductor-server') testImplementation project(':conductor-common') diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/base/AbstractResiliencySpecification.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/base/AbstractResiliencySpecification.groovy index 60dcf631df..d3270c447a 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/base/AbstractResiliencySpecification.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/base/AbstractResiliencySpecification.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DecisionTaskSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DecisionTaskSpec.groovy index da2179919d..66012e6fbf 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DecisionTaskSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DecisionTaskSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DoWhileSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DoWhileSpec.groovy index 7e92345d39..ab2ecca464 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DoWhileSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DoWhileSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -518,7 +518,7 @@ class DoWhileSpec extends AbstractSpecification { tasks[0].status == Task.Status.IN_PROGRESS tasks[1].taskType == 'integration_task_0' tasks[1].status == Task.Status.FAILED - tasks[1].retried == true + tasks[1].retried tasks[2].taskType == 'integration_task_0' tasks[2].status == Task.Status.SCHEDULED tasks[2].retryCount == 1 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DynamicForkJoinSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DynamicForkJoinSpec.groovy index 7cef58c64c..782996a488 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DynamicForkJoinSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/DynamicForkJoinSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/EventTaskSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/EventTaskSpec.groovy index 3447117dc0..30a64dd6d6 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/EventTaskSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/EventTaskSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ExclusiveJoinSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ExclusiveJoinSpec.groovy index 5bab355183..c445daf468 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ExclusiveJoinSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ExclusiveJoinSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ExternalPayloadStorageSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ExternalPayloadStorageSpec.groovy index a0af7b9bdd..935ce94f69 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ExternalPayloadStorageSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ExternalPayloadStorageSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -78,8 +78,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the workflow is in a RUNNING state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 1 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.SCHEDULED @@ -95,8 +93,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "verify that the 'integration_task1' is complete and the next task is scheduled" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 2 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.COMPLETED @@ -116,8 +112,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the 'integration_task_2' is complete and the workflow is completed" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.COMPLETED - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 2 output.isEmpty() externalOutputPayloadStoragePath == WORKFLOW_OUTPUT_PATH @@ -146,8 +140,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the workflow is in a RUNNING state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 1 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.SCHEDULED @@ -163,8 +155,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "verify that the 'integration_task1' is complete and the next task is scheduled" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 3 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.COMPLETED @@ -186,8 +176,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the user task is in a COMPLETED state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 4 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.COMPLETED @@ -214,8 +202,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the 'integration_task_3' is complete and the workflow is completed" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.COMPLETED - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 4 output.isEmpty() externalOutputPayloadStoragePath == WORKFLOW_OUTPUT_PATH @@ -250,8 +236,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the workflow is in a RUNNING state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 4 tasks[0].status == Task.Status.COMPLETED tasks[0].taskType == 'FORK' @@ -272,8 +256,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "task is completed and the next task in the fork is scheduled" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 5 tasks[0].status == Task.Status.COMPLETED tasks[0].taskType == 'FORK' @@ -297,8 +279,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "task is completed and the workflow is in running state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 5 tasks[0].status == Task.Status.COMPLETED tasks[0].taskType == 'FORK' @@ -321,8 +301,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "task is completed and the next task after join in scheduled" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 6 tasks[0].status == Task.Status.COMPLETED tasks[0].taskType == 'FORK' @@ -353,8 +331,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "task is completed and the workflow is in completed state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.COMPLETED - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 6 tasks[0].status == Task.Status.COMPLETED tasks[0].taskType == 'FORK' @@ -392,8 +368,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the workflow is in a RUNNING state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 1 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.SCHEDULED @@ -409,8 +383,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "verify that the 'integration_task1' is complete and the next task is scheduled" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 2 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.COMPLETED @@ -430,8 +402,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the sub workflow task is in a IN_PROGRESS state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 2 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.COMPLETED @@ -481,8 +451,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { sweep(workflowInstanceId) with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 3 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.COMPLETED @@ -509,8 +477,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "verify that the task is completed and the workflow is in a completed state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.COMPLETED - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 3 output.isEmpty() externalOutputPayloadStoragePath == WORKFLOW_OUTPUT_PATH @@ -556,8 +522,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the workflow is in a RUNNING state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 1 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.SCHEDULED @@ -573,8 +537,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "verify that the 'integration_task1' is complete and the next task is scheduled" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 2 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.COMPLETED @@ -594,8 +556,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "verify that task is retried and workflow is still running" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 3 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.COMPLETED @@ -620,8 +580,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "verify that the workflow is completed" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.COMPLETED - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 3 output.isEmpty() externalOutputPayloadStoragePath == WORKFLOW_OUTPUT_PATH @@ -658,8 +616,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { then: "verify that the workflow is in RUNNING state" with (workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.RUNNING - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 1 tasks[0].taskType == 'integration_task_1' tasks[0].status == Task.Status.SCHEDULED @@ -676,8 +632,6 @@ class ExternalPayloadStorageSpec extends AbstractSpecification { and: "verify that the 'integration_task_1' is COMPLETED and the workflow has FAILED due to terminate task" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { status == Workflow.WorkflowStatus.FAILED - input.isEmpty() - externalInputPayloadStoragePath == workflowInputPath tasks.size() == 3 output.isEmpty() externalOutputPayloadStoragePath == WORKFLOW_OUTPUT_PATH diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ForkJoinSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ForkJoinSpec.groovy index 21e2c17d92..4cdf011fb7 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ForkJoinSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/ForkJoinSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRerunSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRerunSpec.groovy index b4670209cf..62c7031649 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRerunSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRerunSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRestartSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRestartSpec.groovy index f1a59c598f..0416a8c5fa 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRestartSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRestartSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRetrySpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRetrySpec.groovy index 3172a29cc7..8bfebd490b 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRetrySpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/HierarchicalForkJoinSubworkflowRetrySpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/JsonJQTransformSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/JsonJQTransformSpec.groovy index 5787c1e8d9..4c5e916cd6 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/JsonJQTransformSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/JsonJQTransformSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/KafkaPublishTaskSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/KafkaPublishTaskSpec.groovy index 059d3ebf52..fcb860a28d 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/KafkaPublishTaskSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/KafkaPublishTaskSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/LambdaAndTerminateTaskSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/LambdaAndTerminateTaskSpec.groovy index 5ae3da6234..0be8b69c54 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/LambdaAndTerminateTaskSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/LambdaAndTerminateTaskSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/NestedForkJoinSubWorkflowSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/NestedForkJoinSubWorkflowSpec.groovy index 7165ff4275..b1319a9c2a 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/NestedForkJoinSubWorkflowSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/NestedForkJoinSubWorkflowSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SetVariableTaskSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SetVariableTaskSpec.groovy index a3f444a9f5..4fab0de12b 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SetVariableTaskSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SetVariableTaskSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SimpleWorkflowSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SimpleWorkflowSpec.groovy index 410abd8483..943cd3f4eb 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SimpleWorkflowSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SimpleWorkflowSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -279,7 +279,7 @@ class SimpleWorkflowSpec extends AbstractSpecification { def polledTaskRtTry2 = workflowExecutionService.poll('task_rt', 'task1.integration.worker.testTimeout') polledTaskRtTry2.callbackAfterSeconds = 2 polledTaskRtTry2.status = Task.Status.IN_PROGRESS - workflowExecutionService.updateTask(polledTaskRtTry2) + workflowExecutionService.updateTask(new TaskResult(polledTaskRtTry2)) then: "verify that the polled task is not null" polledTaskRtTry2 @@ -560,7 +560,7 @@ class SimpleWorkflowSpec extends AbstractSpecification { polledIntegrationTask1.status = Task.Status.COMPLETED def polledIntegrationTask1Output = "task1.output -> " + polledIntegrationTask1.inputData['p1'] + "." + polledIntegrationTask1.inputData['p2'] polledIntegrationTask1.outputData['op'] = polledIntegrationTask1Output - workflowExecutionService.updateTask(polledIntegrationTask1) + workflowExecutionService.updateTask(new TaskResult(polledIntegrationTask1)) then: "verify that the 'integration_task_1' is polled and completed" ackPolledIntegrationTask1 @@ -735,7 +735,7 @@ class SimpleWorkflowSpec extends AbstractSpecification { pollTaskTry1.outputData['op'] = 'task1.in.progress' pollTaskTry1.callbackAfterSeconds = 5 pollTaskTry1.status = Task.Status.IN_PROGRESS - workflowExecutionService.updateTask(pollTaskTry1) + workflowExecutionService.updateTask(new TaskResult(pollTaskTry1)) then: "verify that the task is polled and acknowledged" pollTaskTry1 @@ -817,7 +817,7 @@ class SimpleWorkflowSpec extends AbstractSpecification { pollTaskTry1.outputData['op'] = 'task1.in.progress' pollTaskTry1.callbackAfterSeconds = 3600 pollTaskTry1.status = Task.Status.IN_PROGRESS - workflowExecutionService.updateTask(pollTaskTry1) + workflowExecutionService.updateTask(new TaskResult(pollTaskTry1)) then: "verify that the task is polled and acknowledged" pollTaskTry1 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRerunSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRerunSpec.groovy index 33de848dea..e2f74c0447 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRerunSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRerunSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRestartSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRestartSpec.groovy index 1b83ca59dc..b651b37186 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRestartSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRestartSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRetrySpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRetrySpec.groovy index 08cbe9321d..895d79da68 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRetrySpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowRetrySpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowSpec.groovy index ba33559f1a..095f40404b 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SubWorkflowSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SwitchTaskSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SwitchTaskSpec.groovy index 1e50d7b4ec..64e62aa6af 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SwitchTaskSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SwitchTaskSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SystemTaskSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SystemTaskSpec.groovy index b05cc40108..5e6c0869e1 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SystemTaskSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/SystemTaskSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/TaskLimitsWorkflowSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/TaskLimitsWorkflowSpec.groovy index 1b43cfbf8e..57e7ebc28c 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/TaskLimitsWorkflowSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/TaskLimitsWorkflowSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -15,6 +15,7 @@ package com.netflix.conductor.test.integration import org.springframework.beans.factory.annotation.Autowired 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.dao.QueueDAO import com.netflix.conductor.test.base.AbstractSpecification @@ -202,7 +203,7 @@ class TaskLimitsWorkflowSpec extends AbstractSpecification { when: "The task that was polled and acknowledged is completed" polledTask1.status = Task.Status.COMPLETED - workflowExecutionService.updateTask(polledTask1) + workflowExecutionService.updateTask(new TaskResult(polledTask1)) and: "The task offset time is reset to ensure that a task is returned on the next poll" queueDAO.resetOffsetTime('test_task_with_concurrency_limit', diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/WaitTaskSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/WaitTaskSpec.groovy index 2593a92be0..4f34fb01bb 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/WaitTaskSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/WaitTaskSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/WorkflowAndTaskConfigurationSpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/WorkflowAndTaskConfigurationSpec.groovy index 5dbb3ea48a..408c884e49 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/integration/WorkflowAndTaskConfigurationSpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/integration/WorkflowAndTaskConfigurationSpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -22,7 +22,7 @@ import com.netflix.conductor.common.metadata.workflow.RerunWorkflowRequest 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.core.execution.WorkflowExecutor +import com.netflix.conductor.core.utils.Utils import com.netflix.conductor.dao.QueueDAO import com.netflix.conductor.test.base.AbstractSpecification @@ -190,7 +190,7 @@ class WorkflowAndTaskConfigurationSpec extends AbstractSpecification { } and: "The decider queue has one task that is ready to be polled" - queueDAO.getSize(WorkflowExecutor.DECIDER_QUEUE) == 1 + queueDAO.getSize(Utils.DECIDER_QUEUE) == 1 when: "The the first task 'integration_task_1' is polled and acknowledged" def task1Try1 = workflowExecutionService.poll('integration_task_1', 'task1.worker') @@ -202,7 +202,7 @@ class WorkflowAndTaskConfigurationSpec extends AbstractSpecification { task1Try1Acknowledgment and: "Ensure that the decider size queue is 1 to to enable the evaluation" - queueDAO.getSize(WorkflowExecutor.DECIDER_QUEUE) == 1 + queueDAO.getSize(Utils.DECIDER_QUEUE) == 1 when: "There is a delay of 3 seconds introduced and the workflow is sweeped to run the evaluation" Thread.sleep(3000) @@ -798,7 +798,7 @@ class WorkflowAndTaskConfigurationSpec extends AbstractSpecification { def task1Try1 = workflowExecutionService.poll('integration_task_1', 'task1.worker') task1Try1.status = Task.Status.IN_PROGRESS task1Try1.callbackAfterSeconds = 2L - workflowExecutionService.updateTask(task1Try1) + workflowExecutionService.updateTask(new TaskResult(task1Try1)) then: "verify that the workflow is in running state and the task is in SCHEDULED" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { @@ -845,7 +845,7 @@ class WorkflowAndTaskConfigurationSpec extends AbstractSpecification { def task2Try1 = workflowExecutionService.poll('integration_task_2', 'task2.worker') task2Try1.status = Task.Status.IN_PROGRESS task2Try1.callbackAfterSeconds = 5L - workflowExecutionService.updateTask(task2Try1) + workflowExecutionService.updateTask(new TaskResult(task2Try1)) then: "Verify that the workflow is in running state and the task is in scheduled state" with(workflowExecutionService.getExecutionStatus(workflowInstanceId, true)) { diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/resiliency/QueueResiliencySpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/resiliency/QueueResiliencySpec.groovy index 358c074fd0..719db6c071 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/resiliency/QueueResiliencySpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/resiliency/QueueResiliencySpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/resiliency/TaskResiliencySpec.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/resiliency/TaskResiliencySpec.groovy index 97854d611a..fb5114849e 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/resiliency/TaskResiliencySpec.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/resiliency/TaskResiliencySpec.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 diff --git a/test-harness/src/test/groovy/com/netflix/conductor/test/util/WorkflowTestUtil.groovy b/test-harness/src/test/groovy/com/netflix/conductor/test/util/WorkflowTestUtil.groovy index a79deaf459..586f3b99e6 100644 --- a/test-harness/src/test/groovy/com/netflix/conductor/test/util/WorkflowTestUtil.groovy +++ b/test-harness/src/test/groovy/com/netflix/conductor/test/util/WorkflowTestUtil.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -20,19 +20,18 @@ import org.springframework.stereotype.Component 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.common.metadata.workflow.WorkflowDef -import com.netflix.conductor.common.run.Workflow import com.netflix.conductor.core.WorkflowContext import com.netflix.conductor.core.exception.ApplicationException import com.netflix.conductor.core.execution.WorkflowExecutor import com.netflix.conductor.dao.QueueDAO +import com.netflix.conductor.model.WorkflowModel import com.netflix.conductor.service.ExecutionService import com.netflix.conductor.service.MetadataService import com.fasterxml.jackson.databind.ObjectMapper -import static com.netflix.conductor.common.metadata.tasks.Task.Status.COMPLETED - /** * This is a helper class used to initialize task definitions required by the tests when loaded up. * The task definitions that are loaded up in {@link WorkflowTestUtil#taskDefinitions()} method as part of the post construct of the bean. @@ -184,7 +183,7 @@ class WorkflowTestUtil { int version = Integer.parseInt(StringUtils.substringAfter(workflowWithVersion, ":")) List running = workflowExecutionService.getRunningWorkflows(workflowName, version) for (String workflowId : running) { - Workflow workflow = workflowExecutor.getWorkflow(workflowId, false) + WorkflowModel workflow = workflowExecutor.getWorkflow(workflowId, false) if (!workflow.getStatus().isTerminal()) { workflowExecutor.terminateWorkflow(workflowId, "cleanup") } @@ -237,19 +236,20 @@ class WorkflowTestUtil { * @param failureReason the reason to fail the task that will added to the task update * @param outputParams An optional output parameters if available will be added to the task before updating to failed * @param waitAtEndSeconds an optional delay before the method returns, if the value is 0 skips the delay - * @return A Tuple of polledTask and acknowledgement of the poll + * @return A Tuple of taskResult and acknowledgement of the poll */ Tuple pollAndFailTask(String taskName, String workerId, String failureReason, Map outputParams = null, int waitAtEndSeconds = 0) { def polledIntegrationTask = workflowExecutionService.poll(taskName, workerId) def ackPolledIntegrationTask = workflowExecutionService.ackTaskReceived(polledIntegrationTask.taskId) - polledIntegrationTask.status = Task.Status.FAILED - polledIntegrationTask.reasonForIncompletion = failureReason + def taskResult = new TaskResult(polledIntegrationTask) + taskResult.status = TaskResult.Status.FAILED + taskResult.reasonForIncompletion = failureReason if (outputParams) { outputParams.forEach { k, v -> - polledIntegrationTask.outputData[k] = v + taskResult.outputData[k] = v } } - workflowExecutionService.updateTask(polledIntegrationTask) + workflowExecutionService.updateTask(taskResult) return waitAtEndSecondsAndReturn(waitAtEndSeconds, polledIntegrationTask, ackPolledIntegrationTask) } @@ -257,7 +257,7 @@ class WorkflowTestUtil { * A helper method to introduce delay and convert the polledIntegrationTask and ackPolledIntegrationTask * into a tuple. This method is intended to be used by pollAndFailTask and pollAndCompleteTask * @param waitAtEndSeconds The total seconds of delay before the method returns - * @param polledIntegrationTask instance of polled task + * @param ackedTaskResult the task result created after ack * @param ackPolledIntegrationTask a acknowledgement of a poll * @return A Tuple of polledTask and acknowledgement of the poll */ @@ -284,30 +284,31 @@ class WorkflowTestUtil { return new Tuple(null, null) } def ackPolledIntegrationTask = workflowExecutionService.ackTaskReceived(polledIntegrationTask.taskId) - polledIntegrationTask.status = COMPLETED + def taskResult = new TaskResult(polledIntegrationTask) + taskResult.status = TaskResult.Status.COMPLETED if (outputParams) { outputParams.forEach { k, v -> - polledIntegrationTask.outputData[k] = v + taskResult.outputData[k] = v } } - workflowExecutionService.updateTask(polledIntegrationTask) + workflowExecutionService.updateTask(taskResult) return waitAtEndSecondsAndReturn(waitAtEndSeconds, polledIntegrationTask, ackPolledIntegrationTask) } Tuple pollAndCompleteLargePayloadTask(String taskName, String workerId, String outputPayloadPath) { def polledIntegrationTask = workflowExecutionService.poll(taskName, workerId) def ackPolledIntegrationTask = workflowExecutionService.ackTaskReceived(polledIntegrationTask.taskId) - polledIntegrationTask.status = COMPLETED - polledIntegrationTask.outputData = null - polledIntegrationTask.externalOutputPayloadStoragePath = outputPayloadPath - polledIntegrationTask.status = COMPLETED - workflowExecutionService.updateTask(polledIntegrationTask) + def taskResult = new TaskResult(polledIntegrationTask) + taskResult.status = TaskResult.Status.COMPLETED + taskResult.outputData = null + taskResult.externalOutputPayloadStoragePath = outputPayloadPath + workflowExecutionService.updateTask(taskResult) return new Tuple(polledIntegrationTask, ackPolledIntegrationTask) } /** * A helper method intended to be used in the then: block of the spock test feature, ideally intended to be called after either: - * pollAndCompleteTask function or pollAndFailTask function + * pollAndCompleteTask function or pollAndFailTask function * @param completedTaskAndAck A Tuple of polledTask and acknowledgement of the poll * @param expectedTaskInputParams a map of input params that are verified against the polledTask that is part of the completedTaskAndAck tuple */ diff --git a/test-harness/src/test/java/com/netflix/conductor/test/listener/WorkflowStatusPublisherIntegrationTest.java b/test-harness/src/test/java/com/netflix/conductor/test/listener/WorkflowStatusPublisherIntegrationTest.java index 8fd75cf963..30e8516e3f 100644 --- a/test-harness/src/test/java/com/netflix/conductor/test/listener/WorkflowStatusPublisherIntegrationTest.java +++ b/test-harness/src/test/java/com/netflix/conductor/test/listener/WorkflowStatusPublisherIntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -31,6 +31,7 @@ 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.common.metadata.workflow.WorkflowDef; import com.netflix.conductor.common.metadata.workflow.WorkflowTask; import com.netflix.conductor.common.run.Workflow; @@ -38,6 +39,7 @@ import com.netflix.conductor.core.events.queue.Message; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.dao.QueueDAO; +import com.netflix.conductor.model.WorkflowModel; import com.netflix.conductor.service.ExecutionService; import com.netflix.conductor.service.MetadataService; @@ -162,7 +164,7 @@ public void testListenerOnCompletedWorkflow() throws IOException, InterruptedExc List tasks = workflowExecutionService.getTasks("junit_task_1", null, 1); tasks.get(0).setStatus(COMPLETED); - workflowExecutionService.updateTask(tasks.get(0)); + workflowExecutionService.updateTask(new TaskResult(tasks.get(0))); checkIfWorkflowIsCompleted(id); @@ -192,7 +194,7 @@ public void testListenerOnCompletedWorkflow() throws IOException, InterruptedExc private void checkIfWorkflowIsCompleted(String id) throws InterruptedException { int statusRetrieveAttempts = 0; while (workflowExecutor.getWorkflow(id, false).getStatus() - != Workflow.WorkflowStatus.COMPLETED) { + != WorkflowModel.Status.COMPLETED) { if (statusRetrieveAttempts > 5) { break; } diff --git a/test-harness/src/test/java/com/netflix/conductor/test/utils/UserTask.java b/test-harness/src/test/java/com/netflix/conductor/test/utils/UserTask.java index 8ceca53701..d0af23206a 100644 --- a/test-harness/src/test/java/com/netflix/conductor/test/utils/UserTask.java +++ b/test-harness/src/test/java/com/netflix/conductor/test/utils/UserTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Netflix, Inc. + * Copyright 2022 Netflix, Inc. *

    * 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 @@ -23,11 +23,10 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.netflix.conductor.common.metadata.tasks.Task; -import com.netflix.conductor.common.metadata.tasks.Task.Status; -import com.netflix.conductor.common.run.Workflow; import com.netflix.conductor.core.execution.WorkflowExecutor; import com.netflix.conductor.core.execution.tasks.WorkflowSystemTask; +import com.netflix.conductor.model.TaskModel; +import com.netflix.conductor.model.WorkflowModel; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; @@ -43,7 +42,7 @@ public class UserTask extends WorkflowSystemTask { private final ObjectMapper objectMapper; private static final TypeReference>>> - mapStringListObjects = new TypeReference>>>() {}; + mapStringListObjects = new TypeReference<>() {}; @Autowired public UserTask(ObjectMapper objectMapper) { @@ -53,11 +52,11 @@ public UserTask(ObjectMapper objectMapper) { } @Override - public void start(Workflow workflow, Task task, WorkflowExecutor executor) { + public void start(WorkflowModel workflow, TaskModel task, WorkflowExecutor executor) { Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); if (task.getWorkflowTask().isAsyncComplete()) { - task.setStatus(Status.IN_PROGRESS); + task.setStatus(TaskModel.Status.IN_PROGRESS); } else { Map>> map = objectMapper.convertValue(task.getInputData(), mapStringListObjects); @@ -68,7 +67,7 @@ public void start(Workflow workflow, Task task, WorkflowExecutor executor) { "size", map.getOrDefault("largeInput", defaultLargeInput).get("TEST_SAMPLE").size()); task.setOutputData(output); - task.setStatus(Status.COMPLETED); + task.setStatus(TaskModel.Status.COMPLETED); } } diff --git a/zookeeper-lock/build.gradle b/zookeeper-lock/build.gradle index 4e79337f21..ea42008da8 100644 --- a/zookeeper-lock/build.gradle +++ b/zookeeper-lock/build.gradle @@ -1,5 +1,4 @@ dependencies { - implementation project(':conductor-common') implementation project(':conductor-core') compileOnly 'org.springframework.boot:spring-boot-starter'