diff --git a/.gitignore b/.gitignore index 85e7c1d..356a1f6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /.idea/ +/src/main/resources/application-mycloud.txt diff --git a/README.md b/README.md index 0e6d8ad..f072005 100644 --- a/README.md +++ b/README.md @@ -8,16 +8,16 @@ Create scenarios to automate any execution of processes. Objectives are * Unit test and regression: You need to verify that a process reacts the same if you create a process instance with the variable "amount=100", and that the process comes to the user task "review". -* Unit performance test: The process calls a service task "getCreditScore" and you want to verify this execution stays under 200 ms +* Unit performance test: The process calls a service task "getCreditScore," and you want to verify this execution stays under 200 ms * Developer reason: you developed the task "getCreditScore", and this task is in the process after 4 user tasks and 3 service tasks that you need to simulate -These goals are covered by the Unit Test section. +The Unit Test section covers these goals. * Load test: to verify that the platform can handle 1000 process instances created every 10 minutes and can process this throughput: it should terminate this 1000 process every 10 minutes. * Generate process instances: For any reason, you want to generate 400 process instances and advance them to the user task "Review" to check your user application -These goals are covered by the Load Test section. +The Load Test section covers these goals. Process-Automator executes scenario. One scenario pilot a process. @@ -32,20 +32,19 @@ system, and to verify that the process reacts as expected. ## Execute a process -From a scenario, Process-Automator calls the Camunda Engine server (C7 or C8) and executes the different +From a scenario, the Process-Automator calls the Camunda Engine server (C7 or C8) and executes the different steps in the scenario. Let's take an example with this scenario: ```` Create a new process instance with the variable "subscriptionLevel: "GOLD", "customerId": 14422 ```` -The process is created and processed by the Camunda Engine (C7 or C8). The `GetContext` operation is executed by -the Camunda Engine, and, according to the information, the process instance moves to the task `Review Level 1`. +The Camunda Engine (C7 or C8) creates and processes the process. The Camunda Engine executes the `GetContext` operation, and, according to the information, the process instance moves to the task `Review Level 1`. In the scenario, Process-Automator waits for this user task. It will execute it and set `ReviewLevel2Needed.` to True. The Camunda Engine moves the process instance to `Review Level 2`. In the scenario, Process-Automator waits for this user task. It will execute it. The Camunda engine continues the execution. It executes `Register Application`, waits for the message, executes `Notify Applicant`, and completes the process instance. -Another scenario can execute only `Review Level 1` or no review at all. +Another scenario can execute only `Review Level 1` or no review. What Process-Automator do: @@ -57,14 +56,14 @@ What Process-Automator do: Process-Automator do not * Execute service task in unit-scenario -* It is not expected to throw a BPMN Message in the flow: a real system is piloted by the Automator. +* It is not expected to throw a BPMN Message in the flow: Process-Automator piloted a real system. ## Requirement -Automator needs to connect to a running platform, Camunda 7 or Camunda 8. Automator is not a process +Process-Automator needs to connect to a running platform, Camunda 7 or Camunda 8. Automator is not a process simulator. The running platform will execute all service tasks. -A scenario can be executed on a Camunda 7 or a Camunda 8 server. Automator provides: +A scenario can be executed on a Camunda 7 or a Camunda 8 server. Process-Automator provides: * a server running under Springboot * a docker image @@ -79,11 +78,11 @@ The unit scenario describes one process instance execution. Creation and user ta This functionality is used to run regression tests, coverage tests, or just advance process instances in the process for the development. -Visit [Unit Scenario](doc/unitscenario/README.md) +Visit [Unit Scenario](doc/unittestscenario/README.md) -### Load test (flowscenario) +### Load test (flow-scenario) -The flow scenario describes an environment and sends a requirement like "generate 500 PI every 40 seconds". +The flow scenario describes an environment and sends requirements like "generate 500 PI every 40 seconds". The flow scenario has a duration and objective to verify. @@ -97,17 +96,44 @@ This section references all the information to build a scenario. Visit [Scenario reference](doc/scenarioreference/README.md) -## Connect to a server +## Connection to a server Process-Automator does not contain any Camunda server. It connects to an existing Camunda Engine. Two communication interfaces exist, one for Camunda 7 and one for Camunda 8. A scenario can then pilot a Camunda 7 or a Camunda 8 server. +The scenario does not contain any server information. It has only the server. + +Process-Automator references a list of servers in the configuration in multiple ways: +* serverConnection : String, containing a list of connections separated by ; +* serverList: List of records. +* camunda7 : information to connnect a Camunda 7 server +* camunda8 : information to connect a Camunda 8 server +* camunda8Saas: information to connect a Camunda 8 Saas server + + +At the execution, two parameters are mandatory: +* the scenario to run +* the server to connect to run the scenario + +In this way, using the same scenario in different environments is possible. + +Example to run the CLI command + +```` +`java -jar target/process-execution-automator.jar \ + -s Camunda8Ruby \ + -v \ + -l MAIN \ + -x run doc/unittestscenario/resources/C8LoanManagementScn.json +```` ## Use in Docker A docker image is created. The image can be used in a docker-compose. Visit [Docker documentation](doc/docker/README.md) +Scenario and Server configuration can be set up at startup. + ## Use in Kubernetes The project can be used in a docker environment to create, for example, @@ -119,11 +145,171 @@ Visit [Kubernetes documentation](doc/kubernetes/README.md) ## Different worker implementation -The service task can be simulated by the project. Different implementations are available: the classical and the Thread implementation. +The project can simulate the service task. Different implementations are available: the classical and the Thread implementation. Visit [Different Worker Implementation](https://github.com/pierre-yves-monnet/C8-workers-implementation) project -to have an explanation of the different implementations. +to have an explanation of the different implementations. + + + +# Application properties + +Different properties: + +## automator.startup + +This section gives different parameters to execute at startup. + +| parameter | explanation | default | +|----------------------------|--------------------------------------------------------------------------------------------------|---------| +| serverName | server to use at startup. The server name must exist in the list of servers | | +| scenarioPath | Path to load the scenario to run at startup. The path must be accessible by the application | | +| scenarioResourceAtStartup | Resource to load the scenario. Useful in the Kubernetes word to give the scenario in a config map | | +| logLevel | "DEBUG", "INFO", "MONITORING", "MAIN", "NOTHING" | | +| policyExecution | "DEPLOYPROCESS", "WARMINGUP", "CREATION", "SERVICETASK"", "USERTASK" see bellow | | +| filterService | in combinaison with SERVICETASK. Topic name | | +| deepTracking | If true, more information are coming on the log (each execution for example) | false | + +**policyExecution** +A combinaison of "DEPLOYPROCESS", "WARMINGUP","CREATION","SERVICETASK"", "USERTASK", for example "WARMINUP|CREATION|USERTASK" + +SERVICETASK is running in combination with the filterService value. +The application runs only these role. Doing that, in a cluster, it's possible to start 10 pods running the creation and 5 pods running specific service tasks. + +## main information + +| parameter | explanation | default | +|----------------------------|---------------------------------|--| +| logDebug | Specify the information to log | false | +## server connection +### String connection + +The string contains a list of connections, separate by a semi-colon (":"). +Each parameter in the connection is separated by a comma (,) + +First parameters are + +* Server name +* Type of server: CAMUNDA_7, CAMUNDA_8, ,CAMUNDA_7,CAMUNDA_8_SAAS + +The following parameters depend on the type. + + +**CAMUNDA_7** + + +* URL to connect the server + +**CAMUNDA_8** + +* ZeebeGatewayAddress, +* OperateUserName, +* OperateUserPassword, +* OperateUrl, +* ExecutionThreads, +* MaxJobActive + + +**CAMUNDA_8_SAAS** + +* zeebeCloudRegion, +* zeebeCloudClusterId, +* zeebeCloudClientId, +* zeebeCloudOAuthUrl, +* zeebeCloudAudience, +* clientSecret, +* OperateUserName, +* OperateUserPassword, +* OperateUrl, +* ExecutionThreads, +* MaxJobActive + +**Example** + +````yaml +automator.serversConnection: \ + Camunda7Diamond,CAMUNDA_7,http://localhost:8080/engine-rest; \ + Camunda8Safir,CAMUNDA_8,127.0.0.1:26500,demo,demo,http://localhost:8081 +```` + + +### List of server connection + +Yaml list + +`````yaml +automator.serversList: + - type: "camunda7" + name: "camunda7Emeraud" + url: "http://localhost:8080/engine-rest" + workerMaxJobsActive: 20 + + - type: "camunda8" + name: "Camunda8Ruby" + zeebeGatewayAddress: "127.0.0.1:26500" + operateUserName: "demo" + operateUserPassword: "demo" + operateUrl: "http://localhost:8081" + taskListUrl: "http://localhost:8082" + workerExecutionThreads: 10 + workerMaxJobsActive: 10 + + - type: "camunda8saas" + name: "Camunda8Grena" + region: "bru-2" + clusterId: "4b...e2" + clientId: "bs...6a" + secret: "-Ez...ZG" + oAuthUrl: "https://login.cloud.camunda.io/oauth/token" + audience: "zeebe.camunda.io" + operateUrl: "https://bru-2.operate.camunda.io/4b..e2" + taskListUrl: "https://bru-2.tasklist.camunda.io/4b..e2" + workerExecutionThreads: 10 + workerMaxJobsActive: 10 +`````` + +### Explicit address + +This definition is straightforward to use in the Kubernetes definition because one variable can be override + + +````yaml + + +automator.servers: + camunda7: + name: "Camunda7Granit" + url: "http://localhost:8080/engine-rest" + workerMaxJobsActive: 20 + + camunda8: + name: "Camunda8Calcair" + zeebeGatewayAddress: "127.0.0.1:26500" + operateUserName: "demo" + operateUserPassword: "demo" + operateUrl: "http://localhost:8081" + taskListUrl: "http://localhost:8082" + workerExecutionThreads: 10 + workerMaxJobsActive: 10 + + camunda8Saas: + name: "Camunda8Marbble" + workerExecutionThreads: 10 + workerMaxJobsActive: 10 + operateUrl: "https://ont-1.operate.camunda.io/25fdd1e6-e4a1-4362-b49c-5eced08cb893" + taskListUrl: "https://ont-1.tasklist.camunda.io/25fdd1e6-e4a1-4362-b49c-5eced08cb893" + + operateUserName: "demo" + operateUserPassword: "demo" + + region: "ont-1" + clusterId: "25fdd1e6-e4a1-4362-b49c-5eced08cb893" + clientId: "eknOoiO5GYDdFf4ZjDSh8yaLG-BVCw9L" + oAuthUrl: "https://login.cloud.camunda.io/oauth/token" + audience: "" + secret: "4BPUva1U4lDtoG2-torvAtx6w5RbHULUFhGZ-bBXOMWwZJG3d3VDlfPHjVO3Kz-N" +```` diff --git a/doc/applicationreference/README.md b/doc/applicationreference/README.md index 30520b3..79733c7 100644 --- a/doc/applicationreference/README.md +++ b/doc/applicationreference/README.md @@ -79,7 +79,12 @@ This section declared how to connect the server "Diamond": is that a Camunda7 se There ed is two ways to declare a list of server: a ServerString Connection. -This is a list of ,CAMUNDA_7|CAMUNDA_8,()* +### URL + +List of server. Easy to use in the CLI on the command line. + + +This is a list of ,CAMUNDA_7|CAMUNDA_8|CAMUNDA_8_SAAS,()* For Camunda 7: ``` @@ -93,17 +98,46 @@ For Camunda 8 to Self-manage For Camunda 8 Saas: ``` -,CAMUNDA_8_SAAS,zeebeCloudRegister,zeebeCloudRegion,zeebeCloudClusterId,zeebeCloudClientId,clientSecret,OperateUserName,OperateUserPassword,OperateUrl,ExecutionThreads,MaxJobActive +,CAMUNDA_8_SAAS,zeebeCloudRegister,zeebeCloudRegion,zeebeCloudClusterId,zeebeCloudClientId,zeebeCloudOAuthUrl,zeebeCloudAudience,clientSecret,OperateUserName,OperateUserPassword,OperateUrl,,ExecutionThreads,MaxJobActive ``` +**Example** +````yaml -# Another way to provide the list of server connection -In the YAML, the list of servers can be done by giving +automator.serversConnection: \ + Camunda7Diamond,CAMUNDA_7,http://localhost:8080/engine-rest; \ + Camunda8Safir,CAMUNDA_8,127.0.0.1:26500,demo,demo,http://localhost:8081 -``` -automator.servers: +```` + +### List of servers +In the YAML, the list of servers can be done by giving a list: + +| Parameter | Explanation | Type | Default | +|------------------------|--------------------------------------------------------------|---------|---------| +| name | Name of server (to be use to define the server to connect) | String | "" | +| type | "CAMUNDA_7", "CAMUNDA_8", "CAMUNDA_8_SAAS" | String | "" | +| workerExecutionThreads | (CAMUNDA_8, CAMUNDA_8_SAAS) Number of threads to use | Integer | 20 | +| workerMaxJobsActive | (all) Number of jobs to fetch | Integer | 10 | +| url | (CAMUNDA_7) Url to connect to Camunda 7 | String | "" | +| zeebeGatewayAddress | (CAMUNDA_8) Address to connect Camunda 8 | String | "" | +| operateUrl | (CAMUNDA_8, CAMUNDA_8_SAAS) Url to connect Operate | String | "" | +| taskListUrl | (CAMUNDA_8, CAMUNDA_8_SAAS) Url to connect Tasklist | String | "" | +| operateUserName | (CAMUNDA_8, CAMUNDA_8_SAAS) User name to connect to Operate | String | "demo" | +| operateUserPassword | (CAMUNDA_8, CAMUNDA_8_SAAS) Password to connect to Operate | String | "demo" | +| region | (CAMUNDA_8_SAAS) Saas region | String | "" | +| clusterId | (CAMUNDA_8_SAAS) Cluster ID | String | "" | +| clientId | (CAMUNDA_8_SAAS) Client ID | String | "" | +| oAuthUrl | (CAMUNDA_8_SAAS) Authorization URL | String | "" | +| audience | (CAMUNDA_8_SAAS) Audience | String | "" | +| secret | (CAMUNDA_8_SAAS) Secret | String | "" | + +***Example*** + +```yaml +automator.serversList: - name: "Gold" type: "CAMUNDA_7" url: "http://localhost:8080/engine-rest" @@ -121,10 +155,120 @@ automator.servers: - name: "Diamond" type: "CAMUNDA_8_SAAS" - zeebeCloudRegister: - zeebeCloudRegion: - clientSecret: - zeebeCloudClusterId: - zeebeCloudClientId: + region: + clusterId: + clientId: + secret: + oAuthUrl: + audience: + workerExecutionThreads: 10 + workerMaxJobsActive: 10 + ``` +### Explicit values + +This method is simplest to use to configure a Docker/Kubernetes connection + + +This definition is very simple to use in the K8 definition, because one variable can be override + +For example, to set up a Camunda 8 server, use in the environment: +````yaml +env: +- name: JAVA_TOOL_OPTIONS + value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud + -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 + -Dautomator.servers.camunda8.operateUserName=demo + -Dautomator.servers.camunda8.operateUserPassword=demo + -Dautomator.servers.camunda8.operateUrl=http://camunda-operate:80 + -Dautomator.servers.camunda8.taskListUrl=http://camunda-tasklist:80 + -Dautomator.servers.camunda8.workerExecutionThreads=1 +```` + +Variables are: + +Prefix **automator.servers.camunda7** + +| Parameter | Explanation | Type | Default | +|----------------------------|-------------------------------------------------------------|----------|---------| +| name | Name of server (to be use to define the server to connect) | String | "" | +| url | Url to connect to Camunda 7 | String | "" | +| workerMaxJobsActive | Number of jobs to fetch | Integer | 20 | + + +Prefix **automator.servers.camunda8** + +| Parameter | Explanation | Type | Default | +|------------------------|------------------------------------------------------------|---------|---------| +| name | Name of server (to be use to define the server to connect) | String | "" | +| zeebeGatewayAddress | Address to connect Camunda 8 | String | "" | +| operateUrl | Url to connect Operate | String | "" | +| taskListUrl | Url to connect Tasklist | String | "" | +| operateUserName | User name to connect to Operate | String | "demo" | +| operateUserPassword | Password to connect to Operate | String | "demo" | +| workerExecutionThreads | Number of threads to use | Integer | 20 | +| workerMaxJobsActive | Number of jobs to fetch | Integer | 10 | + + +Prefix **automator.servers.camunda8Saas** + +| Parameter | Explanation | Type | Default | +|------------------------|------------------------------------------------------------|---------|---------| +| name | Name of server (to be use to define the server to connect) | String | "" | +| operateUrl | Url to connect Operate | String | "" | +| taskListUrl | Url to connect Tasklist | String | "" | +| operateUserName | User name to connect to Operate | String | "demo" | +| operateUserPassword | Password to connect to Operate | String | "demo" | +| region | Saas regions | String | "" | +| clusterId | Cluster ID | String | "" | +| clientId | Client ID | String | "" | +| oAuthUrl | Authorization URL | String | "" | +| audience | Audience | String | "" | +| secret | Secret | String | "" | +| workerExecutionThreads | Number of threads to use | Integer | 20 | +| workerMaxJobsActive | Number of jobs to fetch | Integer | 10 | + + +***Example*** + + +````yaml +automator.servers: + + camunda7: + name: "Camunda7Granit" + url: "http://localhost:8080/engine-rest" + workerMaxJobsActive: 20 + + + camunda8: + name: "Camunda8Calcair" + zeebeGatewayAddress: "127.0.0.1:26500" + operateUserName: "demo" + operateUserPassword: "demo" + operateUrl: "http://localhost:8081" + taskListUrl: "http://localhost:8082" + workerExecutionThreads: 10 + workerMaxJobsActive: 10 + + camunda8Saas: + name: "Camunda8Marbble" + clusterId: "25fdd1e6-e4a1-4362-b49c-5eced08cb893" + clientId: "eknOoiO5GYDdFf4ZjDSh8yaLG-BVCw9L" + oAuthUrl: "https://login.cloud.camunda.io/oauth/token" + audience: "" + secret: "4BPUva1U4lDtoG2-torvAtx6w5RbHULUFhGZ-bBXOMWwZJG3d3VDlfPHjVO3Kz-N" + operateUrl: "https://ont-1.operate.camunda.io/25fdd1e6-e4a1-4362-b49c-5eced08cb893" + taskListUrl: "https://ont-1.tasklist.camunda.io/25fdd1e6-e4a1-4362-b49c-5eced08cb893" + + operateUserName: "demo" + operateUserPassword: "demo" + + region: "ont-1" + workerExecutionThreads: 10 + workerMaxJobsActive: 10 +```` + diff --git a/doc/loadtestscenario/Tutorial.md b/doc/loadtestscenario/Tutorial.md index 47de94d..a7839be 100644 --- a/doc/loadtestscenario/Tutorial.md +++ b/doc/loadtestscenario/Tutorial.md @@ -24,8 +24,6 @@ zeebe: env: - name: ZEEBE_BROKER_EXECUTION_METRICS_EXPORTER_ENABLED value: "true" - - name: ZEEBE_BROKER_PROCESSING_MAXCOMMANDSINBATCH - value: "5000" resources: requests: cpu: "1" @@ -221,13 +219,13 @@ Specify in the application parameter what you want to run. `````yaml Automator.startup: -scenarioPath: ./doc/loadtestsscenario/resources + scenarioPath: ./doc/loadtestsscenario/resources # List of scenarios separated by ; -scenarioAtStartup: C8CrawlUrlScn.json; + scenarioAtStartup: C8CrawlUrlScn.json; # DEBUG, INFO, MONITORING, MAIN, NOTHING -logLevel: MAIN + logLevel: MAIN # string composed with DEPLOYPROCESS, WARMINGUP, CREATION, SERVICETASK (ex: "CREATION", "DEPLOYPROCESS|CREATION|SERVICETASK") -policyExecution: DEPLOYPROCESS|WARMINGUP|CREATION|SERVICETASK|USERTASK + policyExecution: DEPLOYPROCESS|WARMINGUP|CREATION|SERVICETASK|USERTASK ````` @@ -249,14 +247,15 @@ To be close to the final platform, let's run the process-automator not locally b The main point is to provide the scenario to the pod. -1. Create a config map for the scenario +Create a config map for the scenario ```` cd doc/loadtestscenario/ kubectl create configmap crawurlscnmap --from-file=resources/C8CrawlUrlScn.json ```` +How this scenario is accessible in the pod? Check the `ku-c8CrawUrl.yaml` file -2. Create a volume and mount the configMap in that volume +1. Create a volume and mount the configMap in that volume ````yaml volumes: - name: scenario @@ -264,7 +263,7 @@ kubectl create configmap crawurlscnmap --from-file=resources/C8CrawlUrlScn.json name: crawurlscnmap ```` -3. Mount the volume in the container +2. Mount the volume in the container `````yaml volumeMounts: @@ -274,17 +273,30 @@ volumeMounts: readOnly: true ````` -4. Reference the file in parameters +3. Reference the file in parameters ````` -Dautomator.startup.scenarioResourceAtStartup=file:/C8CrawlUrlScn.json ````` -Then, deploy and start the docker image with + +Then, deploy and start the docker image. + +All this configuration is available in the file `ku-c8CrawlUrl.yaml`, so run it with ```` kubectl create -f ku-c8CrawlUrl.yaml ```` +Follow the advance +```` +kubectl get pods +```` +Identify the correct pods, and access the log +```` +kubectl logs -f ku-processautomator-xxxxxx +```` + + ### Generate the Docker image again An alternative consists of placing the scenario under `src/resources/` and building a new image. diff --git a/doc/loadtestscenario/ku-c8CrawlUrl.yaml b/doc/loadtestscenario/ku-c8CrawlUrl.yaml index f926a9f..cedc27f 100644 --- a/doc/loadtestscenario/ku-c8CrawlUrl.yaml +++ b/doc/loadtestscenario/ku-c8CrawlUrl.yaml @@ -20,16 +20,18 @@ spec: spec: containers: - name: ku-processautomator - image: ghcr.io/camunda-community-hub/process-execution-automator:latest + image: ghcr.io/camunda-community-hub/process-execution-automator:1.3.0 imagePullPolicy: Always env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo -Dautomator.servers.camunda8.operateUrl=http://camunda-operate:80 - -Dautomator.servers.camunda8.taskListUrl= + -Dautomator.servers.camunda8.taskListUrl=http://camunda-tasklist:80 -Dautomator.servers.camunda8.workerExecutionThreads=1 -Dautomator.startup.scenarioResourceAtStartup=file:/C8CrawlUrlScn.json -Dautomator.startup.policyExecution=WARMINGUP|CREATION|SERVICETASK|USERTASK diff --git a/doc/loadtestscenario/resources/C8CrawlUrlScn.json b/doc/loadtestscenario/resources/C8CrawlUrlScn.json index aa03d8b..98018de 100644 --- a/doc/loadtestscenario/resources/C8CrawlUrlScn.json +++ b/doc/loadtestscenario/resources/C8CrawlUrlScn.json @@ -1,8 +1,8 @@ { "name": "C8CrawlUrl", "processId": "CrawlUrl", - "type": "FLOW", "serverType": "Camunda_8", + "typeScenario" : "FLOW", "deployments": [ { "serverType": "CAMUNDA_8", diff --git a/doc/loadtestscenario/resources/C8CrawlUrlScn250.json b/doc/loadtestscenario/resources/C8CrawlUrlScn250.json index 33283d4..4c56670 100644 --- a/doc/loadtestscenario/resources/C8CrawlUrlScn250.json +++ b/doc/loadtestscenario/resources/C8CrawlUrlScn250.json @@ -1,8 +1,8 @@ { "name": "C8CrawlUrl", "processId": "CrawlUrl", - "type": "FLOW", "serverType": "Camunda_8", + "typeScenario" : "FLOW", "deployments": [ { "serverType": "CAMUNDA_8", diff --git a/doc/loadtestscenario/test_1/test-1-c8CrawlUrlMultiple.yaml b/doc/loadtestscenario/test_1/test-1-c8CrawlUrlMultiple.yaml index 9d33b51..887b5a7 100644 --- a/doc/loadtestscenario/test_1/test-1-c8CrawlUrlMultiple.yaml +++ b/doc/loadtestscenario/test_1/test-1-c8CrawlUrlMultiple.yaml @@ -25,6 +25,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -78,6 +80,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -132,6 +136,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -186,6 +192,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -241,6 +249,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -294,6 +304,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -348,6 +360,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -402,6 +416,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo diff --git a/doc/loadtestscenario/test_2/test-2-c8CrawlUrlMultiple.yaml b/doc/loadtestscenario/test_2/test-2-c8CrawlUrlMultiple.yaml index 29397bf..e55d767 100644 --- a/doc/loadtestscenario/test_2/test-2-c8CrawlUrlMultiple.yaml +++ b/doc/loadtestscenario/test_2/test-2-c8CrawlUrlMultiple.yaml @@ -20,16 +20,18 @@ spec: spec: containers: - name: ku-processautomator-creation - image: ghcr.io/camunda-community-hub/process-execution-automator:latest + image: ghcr.io/camunda-community-hub/process-execution-automator:1.3.0 imagePullPolicy: Always env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo -Dautomator.servers.camunda8.operateUrl=http://camunda-operate:80 - -Dautomator.servers.camunda8.taskListUrl= + -Dautomator.servers.camunda8.taskListUrl=http://camunda-tasklist:80 -Dautomator.servers.camunda8.workerExecutionThreads=1 -Dautomator.startup.scenarioResourceAtStartup=file:/C8CrawlUrlScn.json -Dautomator.startup.policyExecution=DEPLOYPROCESS|WARMINGUP|CREATION @@ -74,16 +76,18 @@ spec: spec: containers: - name: ku-processautomator-retrievework - image: ghcr.io/camunda-community-hub/process-execution-automator:latest + image: ghcr.io/camunda-community-hub/process-execution-automator:1.3.0 imagePullPolicy: Always env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo -Dautomator.servers.camunda8.operateUrl=http://camunda-operate:80 - -Dautomator.servers.camunda8.taskListUrl= + -Dautomator.servers.camunda8.taskListUrl=http://camunda-tasklist:80 -Dautomator.servers.camunda8.workerExecutionThreads=15 -Dautomator.startup.scenarioResourceAtStartup=file:/C8CrawlUrlScn.json -Dautomator.startup.policyExecution=SERVICETASK @@ -129,16 +133,18 @@ spec: spec: containers: - name: ku-processautomator-search - image: ghcr.io/camunda-community-hub/process-execution-automator:latest + image: ghcr.io/camunda-community-hub/process-execution-automator:1.3.0 imagePullPolicy: Always env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo -Dautomator.servers.camunda8.operateUrl=http://camunda-operate:80 - -Dautomator.servers.camunda8.taskListUrl= + -Dautomator.servers.camunda8.taskListUrl=http://camunda-tasklist:80 -Dautomator.servers.camunda8.workerExecutionThreads=250 -Dautomator.startup.scenarioResourceAtStartup=file:/C8CrawlUrlScn.json -Dautomator.startup.policyExecution=SERVICETASK @@ -184,16 +190,18 @@ spec: spec: containers: - name: ku-processautomator-message - image: ghcr.io/camunda-community-hub/process-execution-automator:latest + image: ghcr.io/camunda-community-hub/process-execution-automator:1.3.0 imagePullPolicy: Always env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo -Dautomator.servers.camunda8.operateUrl=http://camunda-operate:80 - -Dautomator.servers.camunda8.taskListUrl= + -Dautomator.servers.camunda8.taskListUrl=http://camunda-tasklist:80 -Dautomator.servers.camunda8.workerExecutionThreads=70 -Dautomator.startup.scenarioResourceAtStartup=file:/C8CrawlUrlScn.json -Dautomator.startup.policyExecution=SERVICETASK @@ -240,11 +248,13 @@ spec: spec: containers: - name: ku-processautomator-verify - image: ghcr.io/camunda-community-hub/process-execution-automator:latest + image: ghcr.io/camunda-community-hub/process-execution-automator:1.3.0 imagePullPolicy: Always env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -294,16 +304,18 @@ spec: spec: containers: - name: ku-processautomator-message - image: ghcr.io/camunda-community-hub/process-execution-automator:latest + image: ghcr.io/camunda-community-hub/process-execution-automator:1.3.0 imagePullPolicy: Always env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo -Dautomator.servers.camunda8.operateUrl=http://camunda-operate:80 - -Dautomator.servers.camunda8.taskListUrl= + -Dautomator.servers.camunda8.taskListUrl=http://camunda-tasklist:80 -Dautomator.servers.camunda8.workerExecutionThreads=150 -Dautomator.startup.scenarioResourceAtStartup=file:/C8CrawlUrlScn.json -Dautomator.startup.policyExecution=SERVICETASK @@ -350,16 +362,18 @@ spec: spec: containers: - name: ku-processautomator-filter - image: ghcr.io/camunda-community-hub/process-execution-automator:latest + image: ghcr.io/camunda-community-hub/process-execution-automator:1.3.0 imagePullPolicy: Always env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo -Dautomator.servers.camunda8.operateUrl=http://camunda-operate:80 - -Dautomator.servers.camunda8.taskListUrl= + -Dautomator.servers.camunda8.taskListUrl=http://camunda-tasklist:80 -Dautomator.servers.camunda8.workerExecutionThreads=70 -Dautomator.startup.scenarioResourceAtStartup=file:/C8CrawlUrlScn.json -Dautomator.startup.policyExecution=SERVICETASK @@ -405,16 +419,18 @@ spec: spec: containers: - name: ku-processautomator-store - image: ghcr.io/camunda-community-hub/process-execution-automator:latest + image: ghcr.io/camunda-community-hub/process-execution-automator:1.3.0 imagePullPolicy: Always env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo -Dautomator.servers.camunda8.operateUrl=http://camunda-operate:80 - -Dautomator.servers.camunda8.taskListUrl= + -Dautomator.servers.camunda8.taskListUrl=http://camunda-tasklist:80 -Dautomator.servers.camunda8.workerExecutionThreads=70 -Dautomator.startup.scenarioResourceAtStartup=file:/C8CrawlUrlScn.json -Dautomator.startup.policyExecution=SERVICETASK diff --git a/doc/loadtestscenario/test_3/test-3-c8CrawlUrlMultiple.yaml b/doc/loadtestscenario/test_3/test-3-c8CrawlUrlMultiple.yaml index 13c69f3..37375ee 100644 --- a/doc/loadtestscenario/test_3/test-3-c8CrawlUrlMultiple.yaml +++ b/doc/loadtestscenario/test_3/test-3-c8CrawlUrlMultiple.yaml @@ -25,6 +25,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -79,6 +81,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -134,6 +138,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -189,6 +195,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -244,6 +252,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -298,6 +308,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -353,6 +365,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -408,6 +422,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo diff --git a/doc/loadtestscenario/test_4/test-4-c8CrawlUrlMultiple.yaml b/doc/loadtestscenario/test_4/test-4-c8CrawlUrlMultiple.yaml index 65391d7..059e670 100644 --- a/doc/loadtestscenario/test_4/test-4-c8CrawlUrlMultiple.yaml +++ b/doc/loadtestscenario/test_4/test-4-c8CrawlUrlMultiple.yaml @@ -25,6 +25,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -79,6 +81,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -134,6 +138,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -189,6 +195,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -244,6 +252,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -298,6 +308,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -353,6 +365,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo @@ -408,6 +422,8 @@ spec: env: - name: JAVA_TOOL_OPTIONS value: >- + -Dautomator.startup.serverName=zeebeCloud + -Dautomator.servers.camunda8.name=zeebeCloud -Dautomator.servers.camunda8.zeebeGatewayAddress=camunda-zeebe-gateway:26500 -Dautomator.servers.camunda8.operateUserName=demo -Dautomator.servers.camunda8.operateUserPassword=demo diff --git a/doc/scenarioreference/README.md b/doc/scenarioreference/README.md index d693510..77be35d 100644 --- a/doc/scenarioreference/README.md +++ b/doc/scenarioreference/README.md @@ -1,7 +1,7 @@ # Scenario reference - -A scenario is a JSON file. A scenario explains one execution, from the process creation until a point. It may not be the end of the process: Automator can be used to advance process instances +A scenario is a JSON file. A scenario explains one execution, from the process creation until a +point. It may not be the end of the process: Automator can be used to advance process instances until a specific task. It contains: * Information on the process: Which process has to start? Some information on a delay between two @@ -12,7 +12,6 @@ until a specific task. It contains: can execute other tasks: Automator does not verify that, except if the "mode verification" is set to "Strict." - # Different BPM The Automator executes a process instance. It does not care about the definition of the process: @@ -34,7 +33,7 @@ A scenario may consist of executing some tasks and then sending a Cancellation m process instance in a different process to get a Cancellation message. It is possible to describe this operation in a step. -## Example +# Example `````json @@ -43,6 +42,7 @@ this operation in a step. "name": "execution Round 14", "version": "1.2", "processId": "MergingInclusive", + "typeScenario": "UNIT", "executions": [ { "name": "multinstance", @@ -51,12 +51,12 @@ this operation in a step. "numberOfThreads": 5, "steps": [ { - "name" : "classical Start Event", + "name": "classical Start Event", "type": "STARTEVENT", "taskId": "StartEvent_1" }, { - "name" : "Get context", + "name": "Get context", "type": "SERVICETASK", "taskId": "Get context", "executiontargetms": 10000 @@ -107,15 +107,36 @@ this operation in a step. } ````` +# Header + +The header gives some main information + +| Parameter | Explanation | Example | +|--------------|----------------------------------------------------------------------------------------|---------------------------------| +| Name | Name of the scenario | "name" : "Test Load accepted" | +| version | version of the scenario | "version": "1.0" | +| processId | process ID: the scenario run on this scenario, last version deployed | "processId": "C8LoadManagement" | +| typeScenario | "UNIT" or "FLOW". The type determine the execution, and the other part of the scenario | "typeScenario": "UNIT" | +| serverName | optional. Each server has a name, and the scenario can provide this information. | "serverName": "ZeebeGrena" | + +For some usage of scenario (automator function), the scenario can provide the name of the server. This name must exist in the list of scenario. +Only the Automator function use this function. + +# UNIT scenario + +This is valid for a typeScenario UNIT. + ## Execution parameters -| Parameter | Explanation | Example | -|------------------------|--------------------------------------------------------------------------------------------------------|---------------------------------| -| Name | Name of execution | "name": "This is the first run" | +The parent attribute is "executions" + +| Parameter | Explanation | Example | +|------------------------|-----------------------------------------------------------------------------------------------------------|---------------------------------| +| Name | Name of execution | "name": "This is the first run" | | policy | "STOPATFIRSTERROR" or "CONTINUE": In case of an error, what is the next move. Default is STOPATFIRSTERROR | "policy": "STOPATFIRSTERROR" | -| numberProcessInstances | Number of process instances to create. Each process instance follows steps. | "numberProcessInstances": 45 | -| Number of threads | Number of threads to execute in parallel. Default is 1. | "numberOfThreads": 5 | -| execution | If false, the execution does not start. If not present, the default value is TRUE. | "execution" : false | +| numberProcessInstances | Number of process instances to create. Each process instance follows steps. | "numberProcessInstances": 45 | +| Number of threads | Number of threads to execute in parallel. Default is 1. | "numberOfThreads": 5 | +| execution | If false, the execution does not start. If not present, the default value is TRUE. | "execution" : false | Then, the execution contains a list of steps. @@ -129,28 +150,49 @@ Start a new process instance. | type | Specify the type (STARTEVENT) | "type": "STARTEVENT" | | taskId | Activity ID of start event | "activityId": "StartEvent_1" | +Example + +````yaml + + +{ + "name": "execution Round 14", + "executions": [ + { + "steps": [ + { + "name": "classical Start Event", + "type": "STARTEVENT", + "taskId": "StartEvent_1" + } + } +} +```` + ## USERTASK step The step waits for a user task and executes it. -| Parameter | Explanation | Example | -|--------------------|------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------| -| name | name of the step, optional | "name": "review" | -| type | Specify the type (USERTASK) | "type": "USERTASK" | -| delay | Deplay to wait before looking for the task, in ISO 8601 | "delay": "PT0.1S" waits 100 ms | +| Parameter | Explanation | Example | +|--------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------| +| name | name of the step, optional | "name": "review" | +| type | Specify the type (USERTASK) | "type": "USERTASK" | +| delay | Deplay to wait before looking for the task, in ISO 8601 | "delay": "PT0.1S" waits 100 ms | | waitingTime | Wait for maximum this time before returning an error. Process-Automator queries the engine every 500 ms until this delay. Default value is 5 minutes | "waitingTime" : "PT10S" | -| taskId | Activity ID to query | "activityId" : "review" | -| variables | List of variables (JSON file) to update | "variables": {"amount": 450, "account": "myBankAccount", "colors": ["blue","red"]} | -| numberOfExecutions | Number of execution, the task may be multi-instance. Default is 1 | "numberOfExecutions" : 3 | +| taskId | Activity ID to query | "activityId" : "review" | +| variables | List of variables (JSON file) to update | "variables": {"amount": 450, "account": "myBankAccount", "colors": ["blue","red"]} | +| variablesOperation | List of variables, but the value is an operation | | +| numberOfExecutions | Number of execution, the task may be multi-instance. Default is 1 | "numberOfExecutions" : 3 | ## SERVICETASK step The step waits for a service task and executes it. -It depends on the usage of the scenario: if a CD/CI, the service task should be executed by the real workers, not by the Process-Automator. But in some environments, or to advance quickly the task to a -certain position, you may want to simulate the worker. Then, the Process-Aautomator can execute a service -task. The real worker shouldbe deactivated then. If the service task is not found, then the scenario -will have an error. +It depends on the usage of the scenario: if a CD/CI, the service task should be executed by the real +workers, not by the Process-Automator. But in some environments, or to advance quickly the task to a +certain position, you may want to simulate the worker. Then, the Process-Aautomator can execute a +service task. The real worker shouldbe deactivated then. If the service task is not found, then the +scenario will have an error. | Parameter | Explanation | Example | |--------------------|------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------| @@ -161,6 +203,7 @@ will have an error. | taskId | Activity ID to query | "activityId": "review" | | topic | Topic to search the task (mandatory in C8) | "topic" : "get-score" | | variables | List of variables (JSON file) to update | "variables": {"amount": 450, "account": "myBankAccount", "colors": ["blue","red"]} | +| variablesOperation | List of variables, but the value is an operation | | | modeExecution | Implementation: options are CLASSICAL, THREAD, THREADTOKEN. Default is CLASSICAL | "modeExecution" : "CLASSICAL" | | numberOfExecutions | Number of execution, the task may be multi-instance. Default is 1 | "numberOfExecutions" : 3 | @@ -168,22 +211,46 @@ There is different implementation for the worker. Choose the one you will use fo **"modeExecution" : "CLASSICAL"** -A classical worker executes the job in the handle method. Zeebe Client waits for all threads -are complete before asking for a new batch of jobs. +A classical worker executes the job in the handle method. Zeebe Client waits for all threads are +complete before asking for a new batch of jobs. **"modeExecution" : "THREAD"** -A thread worker creates a new thread to execute the job and then finishes the method. -So, ZeebeClient gets back quickly to all handle() methods and can ask for a new batch. -If you run 20 jobs active, 20 jobs are locked, and threads are forked, but immediately, a new batch of 20 jobs is requested. So, if the task contains 300 items, this method will catch these 300 items very fast, and 300 threads are running. +A thread worker creates a new thread to execute the job and then finishes the method. So, +ZeebeClient gets back quickly to all handle() methods and can ask for a new batch. If you run 20 +jobs active, 20 jobs are locked, and threads are forked, but immediately, a new batch of 20 jobs is +requested. So, if the task contains 300 items, this method will catch these 300 items very fast, and +300 threads are running. -If the implementation of the workers consists of sending a message to an external service and waiting for the result, this implementation is perfectly fine: the worker will not have 300 threads; just send 300 requests and wait for the return. +If the implementation of the workers consists of sending a message to an external service and +waiting for the result, this implementation is perfectly fine: the worker will not have 300 threads; +just send 300 requests and wait for the return. **"modeExecution" : "THREADTOKEN"** -To control the number of threads working on the worker and to get maximum efficiency, this implementation can be used. -This is the same implementation as before, but a token acquisition is added. To start the -thread, the +To control the number of threads working on the worker and to get maximum efficiency, this +implementation can be used. This is the same implementation as before, but a token acquisition is +added. To start the thread, the + +## ENDEVENT step + +The EndEvent does not have any execution purpose, but a verification goal during a unit test. +Process automator check that the process instance finished by this end event. The EndEvent ID is +store in the `taskId` parameter. + +## Variablesoperation + +The content of the variable is not a direct value, but an operation. + +**generaterandomlist()** +Generate a list with a number of value +Example: +```` +"loopcrawl": "generaterandomlist(500)" +```` +the variable `loopcrawl` will be a list of 500 random string. + + ## Verification @@ -191,8 +258,8 @@ Each execution can declare verifications. Verification is executed after the exe It's possible to check: -* Active activity: Is the process instance correctly waiting on the task "Final Review" after - the execution? +* Active activity: Is the process instance correctly waiting on the task "Final Review" after the + execution? * any completed activity: does the process instance execute the task "GetScore"? Does the process instance end on the end event "Application Done"? * any variable value: does the process variable "ApplicantScore" 150? @@ -201,11 +268,12 @@ It's possible to check: ## Warmup -The Warmup is used to load the process before starting the measurement. -For example, a process may have a service task that takes 2 mn, then another which needs 5 mn. -To load the process before starting the measurement, it is preferable to start to create process instances and execute service tas for 5 mn. - +This section is valid for a scenario FLOW. The parent attribute is "warmup" +The Warmup is used to load the process before starting the measurement. For example, a process may +have a service task that takes 2 mn, then another which needs 5 mn. To load the process before +starting the measurement, it is preferable to start to create process instances and execute service +tas for 5 mn. | Parameter | Explanation | Example | |-----------------|-------------------------------------------------------------------------------|-------------------------| @@ -214,7 +282,6 @@ To load the process before starting the measurement, it is preferable to start t | useUserTasks | When true, all user's tasks in the scenario are started (default is false) | "useUserTasks": true | | operations | List of operations | | - An operation is a record with multiple parameters. | Parameter | Explanation | Example | @@ -222,12 +289,14 @@ An operation is a record with multiple parameters. | type | Type of operation (STARTEVENT, USERTASK,SERVICETASK | | | taskId | | | | processId | | | -| variablesOperation | | | +| variables | | | +| variablesOperation | List of variables, but the value is an operation | | | frequency | | | | numberOfExecutions | | | | endWarmingUp | | | Example: + ```json { "warmingUp": { @@ -249,28 +318,32 @@ Example: } } ``` + ### endWarmingUp -Decide when the warmup can finish. If a duration is set and the properties are true, then the warmup is ended. +Decide when the warmup can finish. If a duration is set and the properties are true, then the warmup +is ended. The parameter is an expression. Possible functions are: **UserTaskThreshold** - A task appears in a user task. The expression gives the Number of tasks expected to be true. +A task appears in a user task. The expression gives the Number of tasks expected to be true. Syntax: UserTaskThreshold( < ActivityId >,< Value >) Example: + ```` UserTaskThreshold(Activity_DiscoverySeedExtraction_TheEnd,7) ```` **EndEventThreshold** - If an end event is detected after the instant the scenario starts, then the warmup is ended. +If an end event is detected after the instant the scenario starts, then the warmup is ended. Syntax: EndEventThreshold(< ActivityId >,< Value >) Example: + ```` UserTaskThreshold(Activity_DiscoverySeedExtraction_TheEnd,7) ```` diff --git a/doc/unittestscenario/README.md b/doc/unittestscenario/README.md index 9adc0a7..4f486ef 100644 --- a/doc/unittestscenario/README.md +++ b/doc/unittestscenario/README.md @@ -4,7 +4,7 @@ Verify a process reacts as expected. There is multiple use case: -* When a process instance is created with the variable "amount=120", it follows the activity "getScore", and then "Review" +* When a process instance is created with the variable "amount>120", it follows the activity "getScore", and then "CheckUser" * Verify that the performance is still the same and a service task stays under 300 ms to be executed @@ -44,9 +44,21 @@ advance the process instance where you want it. # Build a Scenario -In progress +A Unit scenario reference the different activity you need to simulate. If your environment has a worker behind the topic "getScore", you don't need to simulate it, so it must not be in the scenario? + +In the unit scenario, you should place some Event (for example, the end event): the unit will verify that this event is registered in the history. + +This verification implies to give an Operate access. + +The scenario will contains: + +The name, the process ID + +A list of flow to execute under the attribut `executions` +* a STARTEVENT, to start one process instance +* the list of all SERVICETASK ## Scenario definition diff --git a/doc/unittestscenario/resources/C8LoanManagementScn.json b/doc/unittestscenario/resources/C8LoanManagementScn.json new file mode 100644 index 0000000..5bee6ca --- /dev/null +++ b/doc/unittestscenario/resources/C8LoanManagementScn.json @@ -0,0 +1,53 @@ +{ + "name": "C8LoanManagement", + "processId": "LoanManagement", + "serverType": "Camunda_8", + "typeScenario": "UNIT", + "executions": [ + { + "name": "multinstance", + "policy": "STOPATFIRSTERROR", + "numberProcessInstances": 1, + "numberOfThreads": 1, + "steps": [ + { + "name": "Start event normal", + "type": "STARTEVENT", + "taskId": "StartEvent", + "processId": "LoanManagement", + "variables": {"amount": 500} + }, + { + "type": "SERVICETASK", + "topic": "getScore", + "taskId" : "Activity_getScore", + "variables": { + "score": 565 + } + }, + { + "type": "SERVICETASK", + "taskId": "Activity_getUserInformation", + "topic": "getUserInformation" + }, + { + "type": "SERVICETASK", + "topic": "calculateRisk", + "taskId": "Activity_calculateRisk", + "variables": { + "acceptLoan": true + } + }, + { + "type": "SERVICETASK", + "taskId": "Activity_acceptLoan", + "topic": "acceptLoan" + }, + { + "type": "ENDEVENT", + "taskId": "ClaimAccepted" + } + ] + } + ] +} \ No newline at end of file diff --git a/doc/unittestscenario/resources/LoanManagement.bpmn b/doc/unittestscenario/resources/LoanManagement.bpmn new file mode 100644 index 0000000..6a9ebb5 --- /dev/null +++ b/doc/unittestscenario/resources/LoanManagement.bpmn @@ -0,0 +1,225 @@ + + + + + + + + + + + =acceptLoan + + + + + + + =amount > 120 + + + + + + + Flow_0kqc4jy + Flow_0fx9cei + Flow_0no46hw + + + + Flow_1kcan3u + + + + + + Flow_085d046 + Flow_1kcan3u + + + Flow_1503jua + + + Flow_1503jua + Flow_1yyyunu + Flow_0fx9cei + + + + + + + + + Flow_1yyyunu + Flow_0kqc4jy + + + + + + Flow_0no46hw + Flow_0qgd4ue + + + Flow_0qgd4ue + Flow_1svgypr + Flow_085d046 + + + + + + Flow_1svgypr + Flow_0u0ewv2 + + + Flow_0u0ewv2 + + + + + Flow_1pt8gsy + + + + + Flow_0ln9pb3 + + + + + + Flow_1pt8gsy + Flow_0ln9pb3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index fcb6b90..0835411 100644 --- a/pom.xml +++ b/pom.xml @@ -1,18 +1,20 @@ - + 4.0.0 org.camunda.community.automator process-execution-automator - 1.2.2 + 1.3.0 17 ${java.version} ${java.version} - 8.2.0 - 8.2.4 + 8.3.0 + 8.3.0 + 7.19.0 5.9.1 diff --git a/src/main/java/org/camunda/automator/AutomatorAPI.java b/src/main/java/org/camunda/automator/AutomatorAPI.java index 8f7fbe9..cdbb5ef 100644 --- a/src/main/java/org/camunda/automator/AutomatorAPI.java +++ b/src/main/java/org/camunda/automator/AutomatorAPI.java @@ -49,8 +49,7 @@ public Scenario createScenario() { * @throws AutomatorException if scenario can't be read */ public Scenario loadFromFile(File scenarioFile) throws AutomatorException { - Scenario scenario = Scenario.createFromFile(scenarioFile); - return scenario; + return Scenario.createFromFile(scenarioFile); } /** @@ -69,23 +68,21 @@ public Scenario loadFromInputStream(InputStream scenarioInputStream, String orig * Search the engine from the scenario * * @param scenario scenario - * @param engineConfiguration different engine configuration + * @param bpmnEngineList different engine configuration * @return the engine, null if no engine exist, an exception if the connection is not possible */ - public BpmnEngine getBpmnEngineFromScenario(Scenario scenario, BpmnEngineList engineConfiguration) + public BpmnEngine getBpmnEngineFromScenario(Scenario scenario, BpmnEngineList bpmnEngineList) throws AutomatorException { try { if (scenario.getServerName() != null) { - return getBpmnEngine(engineConfiguration, engineConfiguration.getByServerName(scenario.getServerName())); - } - if (scenario.getServerType() != null) { - return getBpmnEngine(engineConfiguration, engineConfiguration.getByServerType(scenario.getServerType())); + return getBpmnEngine( bpmnEngineList.getByServerName(scenario.getServerName()), true); } + return null; } catch (AutomatorException e) { - logger.error("Can't connect the engine for the scenario [{}] serverName[{}] serverType[{}] : {}", - scenario.getName(), scenario.getServerName(), scenario.getServerType(), e.getMessage()); + logger.error("Can't connect the engine for the scenario [{}] serverName[{}]: {}", + scenario.getName(), scenario.getServerName(), e.getMessage()); throw e; } @@ -124,10 +121,8 @@ public RunResult executeScenario(BpmnEngine bpmnEngine, RunParameters runParamet /* Deploy a process in the server */ /* ******************************************************************** */ - public BpmnEngine getBpmnEngine(BpmnEngineList engineConfiguration, - BpmnEngineList.BpmnServerDefinition serverDefinition) throws AutomatorException { - - return BpmnEngineFactory.getInstance().getEngineFromConfiguration(engineConfiguration, serverDefinition); + public BpmnEngine getBpmnEngine(BpmnEngineList.BpmnServerDefinition serverDefinition,boolean logDebug) throws AutomatorException { + return BpmnEngineFactory.getInstance().getEngineFromConfiguration( serverDefinition, logDebug); } /** diff --git a/src/main/java/org/camunda/automator/AutomatorApplication.java b/src/main/java/org/camunda/automator/AutomatorApplication.java index 1f9a77d..af39f83 100644 --- a/src/main/java/org/camunda/automator/AutomatorApplication.java +++ b/src/main/java/org/camunda/automator/AutomatorApplication.java @@ -12,7 +12,7 @@ public class AutomatorApplication { public static void main(String[] args) { SpringApplication.run(AutomatorApplication.class, args); - // thanks to Spring, the class CherryJobRunnerFactory is active. All runners (worker, connectors) start then + // thanks to Spring, the class AutomatorStartup.init() is active. } // https://docs.camunda.io/docs/components/best-practices/development/writing-good-workers/ diff --git a/src/main/java/org/camunda/automator/AutomatorCLI.java b/src/main/java/org/camunda/automator/AutomatorCLI.java index 33fccb6..b2d041b 100644 --- a/src/main/java/org/camunda/automator/AutomatorCLI.java +++ b/src/main/java/org/camunda/automator/AutomatorCLI.java @@ -181,30 +181,22 @@ public void run(String[] args) { // get the correct server configuration BpmnEngineList.BpmnServerDefinition serverDefinition = null; - if (serverName != null) { - serverDefinition = engineConfiguration.getByServerName(serverName); - if (serverDefinition == null) { - throw new AutomatorException("Check configuration: name[" + serverName - + "] does not exist in the list of servers in application.yaml file"); - } - } else { - List listServers = engineConfiguration.getListServers(); - - serverDefinition = listServers.isEmpty() ? null : listServers.get(0); - } + serverDefinition = engineConfiguration.getByServerName(serverName); if (serverDefinition == null) { - throw new AutomatorException( - "Check configuration: configuration to access a Camunda server is missing in application.yaml"); + throw new AutomatorException("Check configuration: name[" + serverName + + "] does not exist in the list of servers in application.yaml file"); } long beginTime = System.currentTimeMillis(); - BpmnEngine bpmnEngine = automatorAPI.getBpmnEngine(engineConfiguration, serverDefinition); + BpmnEngine bpmnEngine = automatorAPI.getBpmnEngine(serverDefinition, true); switch (action) { case RUN -> { Scenario scenario = automatorAPI.loadFromFile(scenarioFile); - BpmnEngine bpmnEngineScenario = automatorAPI.getBpmnEngineFromScenario(scenario, engineConfiguration); + BpmnEngine bpmnEngineScenario = automatorAPI.getBpmnEngine(serverDefinition, true); + + // execution RunResult scenarioExecutionResult = automatorAPI.executeScenario( bpmnEngineScenario == null ? bpmnEngine : bpmnEngineScenario, runParameters, scenario); @@ -214,7 +206,7 @@ public void run(String[] args) { List listScenario = detectRecursiveScenario(folderRecursive); for (File scenarioFileIndex : listScenario) { Scenario scenario = automatorAPI.loadFromFile(scenarioFileIndex); - BpmnEngine bpmnEngineScenario = automatorAPI.getBpmnEngineFromScenario(scenario, engineConfiguration); + BpmnEngine bpmnEngineScenario = automatorAPI.getBpmnEngine(serverDefinition, true); RunResult scenarioExecutionResult = automatorAPI.executeScenario( bpmnEngineScenario == null ? bpmnEngine : bpmnEngineScenario, runParameters, scenario); @@ -234,6 +226,7 @@ public enum ACTION {RUN, RECURSIVE, VERIFY, RUNVERIFY, RECURSIVVERIFY} /** * To reduce the number of warning + * * @param message message to log out */ private static void logOutLn(String message) { diff --git a/src/main/java/org/camunda/automator/bpmnengine/BpmnEngineConfigurationInstance.java b/src/main/java/org/camunda/automator/bpmnengine/BpmnEngineConfigurationInstance.java index 7718a2d..44051a2 100644 --- a/src/main/java/org/camunda/automator/bpmnengine/BpmnEngineConfigurationInstance.java +++ b/src/main/java/org/camunda/automator/bpmnengine/BpmnEngineConfigurationInstance.java @@ -51,10 +51,9 @@ public static BpmnEngineList getCamundaSaas8(String zeebeCloudRegister, BpmnEngineList.BpmnServerDefinition serverDefinition = new BpmnEngineList.BpmnServerDefinition(); serverDefinition.serverType = BpmnEngineList.CamundaEngine.CAMUNDA_8; - serverDefinition.zeebeCloudRegister = zeebeCloudRegister; - serverDefinition.zeebeCloudRegion = zeebeCloudRegion; - serverDefinition.zeebeCloudClusterId = zeebeCloudClusterId; - serverDefinition.zeebeCloudClientId = zeebeCloudClientId; + serverDefinition.zeebeSaasRegion = zeebeCloudRegion; + serverDefinition.zeebeSaasClusterId = zeebeCloudClusterId; + serverDefinition.zeebeSaasClientId = zeebeCloudClientId; bpmEngineConfiguration.addExplicitServer(serverDefinition); diff --git a/src/main/java/org/camunda/automator/bpmnengine/BpmnEngineFactory.java b/src/main/java/org/camunda/automator/bpmnengine/BpmnEngineFactory.java index a1a9253..7882b07 100644 --- a/src/main/java/org/camunda/automator/bpmnengine/BpmnEngineFactory.java +++ b/src/main/java/org/camunda/automator/bpmnengine/BpmnEngineFactory.java @@ -27,8 +27,8 @@ public static BpmnEngineFactory getInstance() { return bpmnEngineFactory; } - public BpmnEngine getEngineFromConfiguration(BpmnEngineList engineConfiguration, - BpmnEngineList.BpmnServerDefinition serverDefinition) + public BpmnEngine getEngineFromConfiguration(BpmnEngineList.BpmnServerDefinition serverDefinition, + boolean logDebug) throws AutomatorException { BpmnEngine engine = cacheEngine.get(serverDefinition.serverType); if (engine != null) @@ -41,13 +41,13 @@ public BpmnEngine getEngineFromConfiguration(BpmnEngineList engineConfiguration, return engine; engine = switch (serverDefinition.serverType) { - case CAMUNDA_7 -> new BpmnEngineCamunda7(engineConfiguration, serverDefinition); + case CAMUNDA_7 -> new BpmnEngineCamunda7(serverDefinition, logDebug); - case CAMUNDA_8 -> new BpmnEngineCamunda8(engineConfiguration, serverDefinition); + case CAMUNDA_8 -> BpmnEngineCamunda8.getFromServerDefinition(serverDefinition, logDebug); - case CAMUNDA_8_SAAS -> new BpmnEngineCamunda8(engineConfiguration, serverDefinition); + case CAMUNDA_8_SAAS -> BpmnEngineCamunda8.getFromServerDefinition( serverDefinition, logDebug); - case DUMMY -> new BpmnEngineDummy(engineConfiguration); + case DUMMY -> new BpmnEngineDummy(serverDefinition); }; diff --git a/src/main/java/org/camunda/automator/bpmnengine/camunda7/BpmnEngineCamunda7.java b/src/main/java/org/camunda/automator/bpmnengine/camunda7/BpmnEngineCamunda7.java index cae1d0c..3bf1f31 100644 --- a/src/main/java/org/camunda/automator/bpmnengine/camunda7/BpmnEngineCamunda7.java +++ b/src/main/java/org/camunda/automator/bpmnengine/camunda7/BpmnEngineCamunda7.java @@ -72,12 +72,16 @@ public class BpmnEngineCamunda7 implements BpmnEngine { EngineApi engineApi; private int count = 0; - public BpmnEngineCamunda7(BpmnEngineList engineConfiguration, BpmnEngineList.BpmnServerDefinition serverDefinition) { + /** + * @param serverDefinition definition to connect to the server + * @param logDebug if true, operation will be log as debug level + */ + public BpmnEngineCamunda7(BpmnEngineList.BpmnServerDefinition serverDefinition, boolean logDebug) { this.serverUrl = serverDefinition.camunda7ServerUrl; this.userName = serverDefinition.camunda7UserName; this.password = serverDefinition.camunda7Password; this.workerMaxJobsActive = serverDefinition.workerMaxJobsActive; - this.logDebug = engineConfiguration.getLogDebug(); + this.logDebug = logDebug; init(); } @@ -226,7 +230,7 @@ public List searchUserTasksByProcessInstance(String processInstanceId, S @Override public List searchUserTasks(String userTaskId, int maxResult) throws AutomatorException { if (logDebug) { - logger.info("BpmnEngine7.searchForActivity: taskName[" + userTaskId + "]"); + logger.info("BpmnEngine7.searchForActivity: taskName[{}]", userTaskId); } TaskQueryDto taskQueryDto = new TaskQueryDto(); @@ -245,7 +249,7 @@ public void executeUserTask(String userTaskId, String userId, Map searchServiceTasks(String processInstanceId, String serviceTaskId, String topic, int maxResult) throws AutomatorException { if (logDebug) { - logger.info("BpmnEngine7.searchForActivity: Process[" + processInstanceId + "] taskName[" + serviceTaskId + "]"); + logger.info("BpmnEngine7.searchForActivity: Process[{}] taskName[{}]", processInstanceId, serviceTaskId); } // get the list of all sub process instance @@ -340,7 +344,7 @@ public void executeServiceTask(String serviceTaskId, String userId, Map serverDefinition.workerMaxJobsActive) { logger.error( - "Camunda8 [{}] Incorrect definition: the number of threads {} must be <= number Jobs Active {} , else ZeebeClient will not fetch enough jobs to feed threads", + "Camunda8 [{}] Incorrect definition: the workerExecutionThreads {} must be <= workerMaxJobsActive {} , else ZeebeClient will not fetch enough jobs to feed threads", serverDefinition.name, serverDefinition.workerExecutionThreads, serverDefinition.workerMaxJobsActive); } + if (!isOk) + throw new AutomatorException("Invalid configuration " + analysis.toString()); + clientBuilder.numJobWorkerExecutionThreads(serverDefinition.workerExecutionThreads); clientBuilder.defaultJobWorkerMaxJobsActive(serverDefinition.workerMaxJobsActive); + + analysis.append("Zeebe connection..."); zeebeClient = clientBuilder.build(); - analysis.append("Zeebe connection with success,"); + // simple test + Topology join = zeebeClient.newTopologyRequest().send().join(); + + // Actually, if an error arrived, an exception is thrown + analysis.append(join != null ? "successfully," : "error"); + + isOk = stillOk(serverDefinition.operateUrl, "operateUrl", analysis, false, isOk); + + analysis.append("Operate connection..."); operateClient = new CamundaOperateClient.Builder().operateUrl(serverDefinition.operateUrl) .authentication(saOperate) .build(); - analysis.append("OperateConnection with success,"); + analysis.append("successfully,"); // TaskList is not mandatory if (serverDefinition.taskListUrl != null && !serverDefinition.taskListUrl.isEmpty()) { + isOk = stillOk(serverDefinition.taskListUrl, "taskListUrl", analysis, false, isOk); + analysis.append("Tasklist ..."); + taskClient = new CamundaTaskListClient.Builder().taskListUrl(serverDefinition.taskListUrl) .authentication(saTaskList) .build(); - analysis.append("TasklistConnection with success,"); + analysis.append("successfully,"); } //get tasks assigned to demo logger.info(analysis.toString()); @@ -228,7 +319,7 @@ public void connection() throws AutomatorException { } catch (Exception e) { zeebeClient = null; throw new AutomatorException( - "Can't connect to Zeebe/operate/tasklist " + e.getMessage() + " - Analysis:" + analysis); + "Can't connect to Server[" + serverDefinition.name + "] Analysis:" + analysis + " fail : " + e.getMessage()); } } @@ -254,10 +345,10 @@ public boolean isReady() { /** * HighFlowMode: when true, the class does not save anything, to reduce the footprint * - * @param hightFlowMode true or false + * @param highFlowMode true or false */ - public void turnHighFlowMode(boolean hightFlowMode) { - this.hightFlowMode = hightFlowMode; + public void turnHighFlowMode(boolean highFlowMode) { + this.hightFlowMode = highFlowMode; } @Override @@ -286,11 +377,11 @@ public String createProcessInstance(String processId, String starterEventId, Map } return String.valueOf(processInstanceId); } catch (Exception e) { - throw new AutomatorException("Can't create in process [" + processId + "] :" + e.getMessage()); + throw new AutomatorException("CreateProcessInstance Error[" + processId + "] :" + e.getMessage()); } } - public String createProcessInstanceSimple(String processId, String starterEventId, Map variables) + public String createProcessInstanceDirect(String processId, String starterEventId, Map variables) throws AutomatorException { try { String marker = null; @@ -454,6 +545,18 @@ public List searchServiceTasks(String processInstanceId, String serviceT throws AutomatorException { try { long processInstanceIdLong = Long.parseLong(processInstanceId); + + ProcessInstanceFilter processInstanceFilter = new ProcessInstanceFilter.Builder().parentKey(processInstanceIdLong) + .build(); + + SearchQuery processInstanceQuery = new SearchQuery.Builder().filter(processInstanceFilter).size(100).build(); + + List listProcessInstances = operateClient.searchProcessInstances(processInstanceQuery); + Set setProcessInstances = listProcessInstances.stream() + .map(ProcessInstance::getKey) + .collect(Collectors.toSet()); + setProcessInstances.add(processInstanceIdLong); + ActivateJobsResponse jobsResponse = zeebeClient.newActivateJobsCommand() .jobType(topic) .maxJobsToActivate(10000) @@ -463,7 +566,7 @@ public List searchServiceTasks(String processInstanceId, String serviceT List listJobsId = new ArrayList<>(); for (ActivatedJob job : jobsResponse.getJobs()) { - if (job.getProcessInstanceKey() == processInstanceIdLong) + if (setProcessInstances.contains(job.getProcessInstanceKey())) listJobsId.add(String.valueOf(job.getKey())); else { zeebeClient.newFailCommand(job.getKey()).retries(2).send().join(); @@ -472,7 +575,7 @@ public List searchServiceTasks(String processInstanceId, String serviceT return listJobsId; } catch (Exception e) { - throw new AutomatorException("Can't search users task " + e.getMessage()); + throw new AutomatorException("Can't search service task topic[" + topic + "] : " + e.getMessage()); } } @@ -489,7 +592,24 @@ public List searchServiceTasks(String processInstanceId, String serviceT public void executeServiceTask(String serviceTaskId, String workerId, Map variables) throws AutomatorException { try { - zeebeClient.newCompleteCommand(Long.valueOf(serviceTaskId)).send().join(); + zeebeClient.newCompleteCommand(Long.valueOf(serviceTaskId)).variables(variables).send().join(); + } catch (Exception e) { + throw new AutomatorException("Can't execute service task " + e.getMessage()); + } + } + + public void throwBpmnServiceTask(String serviceTaskId, + String workerId, + String errorCode, + String errorMessage, + Map variables) throws AutomatorException { + try { + zeebeClient.newThrowErrorCommand(Long.valueOf(serviceTaskId)) + .errorCode(errorCode) + .errorMessage(errorMessage) + .variables(variables) + .send() + .join(); } catch (Exception e) { throw new AutomatorException("Can't execute service task " + e.getMessage()); } @@ -718,8 +838,9 @@ public BpmnEngineList.CamundaEngine getTypeCamundaEngine() { public String getSignature() { String signature = typeCamundaEngine.toString() + " "; if (typeCamundaEngine.equals(BpmnEngineList.CamundaEngine.CAMUNDA_8_SAAS)) - signature += "Cloud[" + serverDefinition.zeebeCloudRegister + "] ClientId[" + serverDefinition.zeebeCloudClientId - + "] ClusterId[" + serverDefinition.zeebeCloudClusterId + "]"; + signature += + "Cloud ClientId[" + serverDefinition.zeebeSaasClientId + "] ClusterId[" + serverDefinition.zeebeSaasClusterId + + "]"; else signature += "Address[" + serverDefinition.zeebeGatewayAddress + "]"; signature += " numJobWorkerExecutionThreads[" + serverDefinition.workerExecutionThreads + "] workerMaxJobsActive[" @@ -739,4 +860,31 @@ private String getUniqueMarker(String processId, String starterEventId) { public ZeebeClient getZeebeClient() { return zeebeClient; } + + /** + * add in analysis and check the consistence + * + * @param value value to check + * @param message name of parameter + * @param analysis analysis builder + * @param check true if the value must not be null or empty + * @param wasOkBefore previous value, is returned if this check is Ok + * @return previous value is ok false else + */ + private boolean stillOk(Object value, String message, StringBuilder analysis, boolean check, boolean wasOkBefore) { + analysis.append(message); + analysis.append(" ["); + analysis.append(value); + analysis.append(" ]"); + + if (check) { + if (value == null || (value instanceof String && ((String) value).isEmpty())) { + analysis.append("No "); + analysis.append(message); + return false; + } + } + return wasOkBefore; + } + } diff --git a/src/main/java/org/camunda/automator/bpmnengine/dummy/BpmnEngineDummy.java b/src/main/java/org/camunda/automator/bpmnengine/dummy/BpmnEngineDummy.java index 78f3c60..26c76d7 100644 --- a/src/main/java/org/camunda/automator/bpmnengine/dummy/BpmnEngineDummy.java +++ b/src/main/java/org/camunda/automator/bpmnengine/dummy/BpmnEngineDummy.java @@ -17,11 +17,11 @@ public class BpmnEngineDummy implements BpmnEngine { - private final BpmnEngineList engineConfiguration; + private final BpmnEngineList.BpmnServerDefinition serverDefinition; private final Logger logger = LoggerFactory.getLogger(BpmnEngineDummy.class); - public BpmnEngineDummy(BpmnEngineList engineConfiguration) { - this.engineConfiguration = engineConfiguration; + public BpmnEngineDummy(BpmnEngineList.BpmnServerDefinition serverDefinition) { + this.serverDefinition = serverDefinition; } @Override diff --git a/src/main/java/org/camunda/automator/configuration/BpmnEngineList.java b/src/main/java/org/camunda/automator/configuration/BpmnEngineList.java index 496e827..14f6fc4 100644 --- a/src/main/java/org/camunda/automator/configuration/BpmnEngineList.java +++ b/src/main/java/org/camunda/automator/configuration/BpmnEngineList.java @@ -24,6 +24,26 @@ public class BpmnEngineList { public static final int DEFAULT_VALUE_EXECUTION_THREADS = 100; public static final int DEFAULT_VALUE_MAX_JOBS_ACTIVE = -1; + public static final String CONF_WORKER_MAX_JOBS_ACTIVE = "workerMaxJobsActive"; + public static final String CONF_WORKER_EXECUTION_THREADS = "workerExecutionThreads"; + public static final String CONF_TASK_LIST_URL = "taskListUrl"; + public static final String CONF_OPERATE_URL = "operateUrl"; + public static final String CONF_OPERATE_USER_PASSWORD = "operateUserPassword"; + public static final String CONF_OPERATE_USER_NAME = "operateUserName"; + public static final String CONF_ZEEBE_GATEWAY_ADDRESS = "zeebeGatewayAddress"; + public static final String CONF_URL = "url"; + public static final String CONF_TYPE = "type"; + public static final String CONF_TYPE_V_CAMUNDA_8 = "camunda8"; + public static final String CONF_TYPE_V_CAMUNDA_8_SAAS = "camunda8Saas"; + public static final String CONF_TYPE_V_CAMUNDA_7 = "camunda7"; + + public static final String CONF_ZEEBE_SAAS_REGION = "region"; + public static final String CONF_ZEEBE_SAAS_SECRET = "secret"; + public static final String CONF_ZEEBE_SAAS_CLUSTER_ID = "clusterId"; + public static final String CONF_ZEEBE_SAAS_CLIENT_ID = "clientId"; + public static final String CONF_ZEEBE_SAAS_OAUTHURL= "oAuthUrl"; + public static final String CONF_ZEEBE_SAAS_AUDIENCE= "audience"; + static Logger logger = LoggerFactory.getLogger(BpmnEngineList.class); @Autowired @@ -48,17 +68,23 @@ public void init() { // log all servers detected logger.info("ConfigurationBpmEngine: servers detected : {} ", allServers.size()); for (BpmnServerDefinition server : allServers) { - String serverDetails = "Server Type[" + server.serverType + "] " + switch (server.serverType) { + String serverDetails = "Server Type[" + server.serverType + "] "; + if (server.serverType == null) { + logger.error("ServerType not declared for server [" + server.name + "]"); + return; + } + + serverDetails += switch (server.serverType) { case CAMUNDA_8 -> "ZeebeadressGateway [" + server.zeebeGatewayAddress + "]"; - case CAMUNDA_8_SAAS -> "ZeebeClientId [" + server.zeebeCloudClientId + "] ClusterId[" - + server.zeebeCloudClusterId + "] RegionId[" + server.zeebeCloudRegion + "]"; + case CAMUNDA_8_SAAS -> "ZeebeClientId [" + server.zeebeSaasClientId + "] ClusterId[" + + server.zeebeSaasClusterId + "] RegionId[" + server.zeebeSaasRegion + "]"; case CAMUNDA_7 -> "Camunda7URL [" + server.camunda7ServerUrl + "]"; case DUMMY -> "Dummy"; }; logger.info(serverDetails); } } catch (Exception e) { - logger.error("Error during initialization"); + logger.error("Error during initialization : " + e.getMessage()); } } @@ -120,10 +146,12 @@ public boolean getLogDebug() { private List getFromServersConnectionList() throws AutomatorException { // not possible to use a Stream: decode throw an exception List list = new ArrayList<>(); + int count=0; for (String s : configurationServersEngine.serversConnection) { + count++; if (s.isEmpty()) continue; - BpmnServerDefinition bpmnServerDefinition = decodeServerConnection(s); + BpmnServerDefinition bpmnServerDefinition = decodeServerConnection(s, "Range in ConnectionString: #"+count); if (bpmnServerDefinition.serverType == null) { logger.error("Server Type can't be detected in string [{}]", s); continue; @@ -134,39 +162,57 @@ private List getFromServersConnectionList() throws Automat return list; } + /** + * getFromServerList + * in configuration, give a list of server. + * @return + * @throws AutomatorException + */ private List getFromServersList() throws AutomatorException { List serverList = new ArrayList<>(); + int count=0; for (Map serverMap : configurationServersEngine.getServersList()) { + count++; BpmnServerDefinition bpmnServerDefinition = new BpmnServerDefinition(); - bpmnServerDefinition.name = getString("name", serverMap, null); - bpmnServerDefinition.workerMaxJobsActive = getInteger("workerMaxJobsActive", serverMap, null); - if ("camunda7".equalsIgnoreCase(getString("type", serverMap, null))) { - bpmnServerDefinition.camunda7ServerUrl = getString("url", serverMap, null); + bpmnServerDefinition.name = getString("name", serverMap, null,"ServerList #"+count); + String contextLog = "ServerList #"+count+" Name ["+bpmnServerDefinition.name+"]"; + bpmnServerDefinition.workerMaxJobsActive = getInteger(CONF_WORKER_MAX_JOBS_ACTIVE, serverMap, DEFAULT_VALUE_MAX_JOBS_ACTIVE,contextLog); + + if (CONF_TYPE_V_CAMUNDA_7.equalsIgnoreCase(getString(CONF_TYPE, serverMap, null,contextLog))) { + bpmnServerDefinition.serverType = CamundaEngine.CAMUNDA_7; + bpmnServerDefinition.camunda7ServerUrl = getString(CONF_URL, serverMap, null,contextLog); if (bpmnServerDefinition.camunda7ServerUrl == null) - throw new AutomatorException("Incorrect Definition - [url] expected for [Camunda7] type"); + throw new AutomatorException("Incorrect Definition - [url] expected for ["+CONF_TYPE_V_CAMUNDA_7+"] type "+contextLog); } - if ("camunda8".equalsIgnoreCase(getString("type", serverMap, null))) { + if (CONF_TYPE_V_CAMUNDA_8.equalsIgnoreCase(getString(CONF_TYPE, serverMap, null,contextLog))) { bpmnServerDefinition.serverType = CamundaEngine.CAMUNDA_8; - bpmnServerDefinition.zeebeGatewayAddress = getString("zeebeGatewayAddress", serverMap, null); - bpmnServerDefinition.operateUserName = getString("operateUserName", serverMap, null); - bpmnServerDefinition.operateUserPassword = getString("operateUserPassword", serverMap, null); - bpmnServerDefinition.operateUrl = getString("operateUrl", serverMap, null); - bpmnServerDefinition.taskListUrl = getString("taskListUrl", serverMap, null); - bpmnServerDefinition.workerExecutionThreads = getInteger("workerExecutionThreads", serverMap, null); + bpmnServerDefinition.zeebeGatewayAddress = getString(CONF_ZEEBE_GATEWAY_ADDRESS, serverMap, null,contextLog); + bpmnServerDefinition.operateUserName = getString(CONF_OPERATE_USER_NAME, serverMap, null,contextLog); + bpmnServerDefinition.operateUserPassword = getString(CONF_OPERATE_USER_PASSWORD, serverMap, null,contextLog); + bpmnServerDefinition.operateUrl = getString(CONF_OPERATE_URL, serverMap, null,contextLog); + bpmnServerDefinition.taskListUrl = getString(CONF_TASK_LIST_URL, serverMap, null,contextLog); + bpmnServerDefinition.workerExecutionThreads = getInteger(CONF_WORKER_EXECUTION_THREADS, serverMap, DEFAULT_VALUE_EXECUTION_THREADS,contextLog); if (bpmnServerDefinition.zeebeGatewayAddress == null) - throw new AutomatorException("Incorrect Definition - [zeebeGatewayAddress] expected for [Camunda8] type"); + throw new AutomatorException("Incorrect Definition - [zeebeGatewayAddress] expected for ["+CONF_TYPE_V_CAMUNDA_8+"] type"); } - if ("camunda8Saas".equalsIgnoreCase(getString("type", serverMap, null))) { + if (CONF_TYPE_V_CAMUNDA_8_SAAS.equalsIgnoreCase(getString(CONF_TYPE, serverMap, null,contextLog))) { bpmnServerDefinition.serverType = CamundaEngine.CAMUNDA_8_SAAS; - bpmnServerDefinition.zeebeCloudRegister = getString("zeebeCloudRegister", serverMap, null); - bpmnServerDefinition.zeebeCloudRegion = getString("zeebeCloudRegion", serverMap, null); - bpmnServerDefinition.zeebeClientSecret = getString("zeebeClientSecret", serverMap, null); - bpmnServerDefinition.zeebeCloudClusterId = getString("zeebeCloudClusterId", serverMap, null); - bpmnServerDefinition.zeebeCloudClientId = getString("zeebeCloudClientId", serverMap, null); - if (bpmnServerDefinition.zeebeCloudRegister == null || bpmnServerDefinition.zeebeCloudRegion == null - || bpmnServerDefinition.zeebeClientSecret == null || bpmnServerDefinition.zeebeCloudClusterId == null - || bpmnServerDefinition.zeebeCloudClientId == null) + bpmnServerDefinition.zeebeSaasRegion = getString(CONF_ZEEBE_SAAS_REGION, serverMap, null,contextLog); + bpmnServerDefinition.zeebeSaasClientSecret = getString(CONF_ZEEBE_SAAS_SECRET, serverMap, null,contextLog); + bpmnServerDefinition.zeebeSaasClusterId = getString(CONF_ZEEBE_SAAS_CLUSTER_ID, serverMap, null,contextLog); + bpmnServerDefinition.zeebeSaasClientId = getString(CONF_ZEEBE_SAAS_CLIENT_ID, serverMap, null,contextLog); + bpmnServerDefinition.zeebeSaasOAuthUrl = getString(CONF_ZEEBE_SAAS_OAUTHURL, serverMap, null,contextLog); + bpmnServerDefinition.zeebeSaasAudience = getString(CONF_ZEEBE_SAAS_AUDIENCE, serverMap, null,contextLog); + + bpmnServerDefinition.workerExecutionThreads = getInteger(CONF_WORKER_EXECUTION_THREADS, serverMap, DEFAULT_VALUE_EXECUTION_THREADS,contextLog); + bpmnServerDefinition.operateUserName = getString(CONF_OPERATE_USER_NAME, serverMap, null,contextLog); + bpmnServerDefinition.operateUserPassword = getString(CONF_OPERATE_USER_PASSWORD, serverMap, null,contextLog); + bpmnServerDefinition.operateUrl = getString(CONF_OPERATE_URL, serverMap, null,contextLog); + bpmnServerDefinition.taskListUrl = getString(CONF_TASK_LIST_URL, serverMap, null,contextLog); + if (bpmnServerDefinition.zeebeSaasRegion == null + || bpmnServerDefinition.zeebeSaasClientSecret == null || bpmnServerDefinition.zeebeSaasClusterId == null + || bpmnServerDefinition.zeebeSaasClientId == null) throw new AutomatorException( "Incorrect Definition - [zeebeCloudRegister],[zeebeCloudRegion], [zeebeClientSecret},[zeebeCloudClusterId],[zeebeCloudClientId] expected for [Camunda8SaaS] type"); } @@ -182,7 +228,7 @@ private List getFromServersList() throws AutomatorExceptio * @return a ServerDefinition * @throws AutomatorException on any error */ - private BpmnServerDefinition decodeServerConnection(String connectionString) throws AutomatorException { + private BpmnServerDefinition decodeServerConnection(String connectionString, String contextLog) throws AutomatorException { StringTokenizer st = new StringTokenizer(connectionString, ","); BpmnServerDefinition bpmnServerDefinition = new BpmnServerDefinition(); bpmnServerDefinition.name = (st.hasMoreTokens() ? st.nextToken() : null); @@ -198,27 +244,28 @@ private BpmnServerDefinition decodeServerConnection(String connectionString) thr bpmnServerDefinition.operateUserPassword = (st.hasMoreTokens() ? st.nextToken() : null); bpmnServerDefinition.taskListUrl = (st.hasMoreTokens() ? st.nextToken() : null); bpmnServerDefinition.workerExecutionThreads = (st.hasMoreTokens() ? - parseInt("executionThread", st.nextToken(), DEFAULT_VALUE_EXECUTION_THREADS) : + parseInt(CONF_WORKER_EXECUTION_THREADS, st.nextToken(), DEFAULT_VALUE_EXECUTION_THREADS, contextLog) : null); bpmnServerDefinition.workerMaxJobsActive = (st.hasMoreTokens() ? - parseInt("jobActive", st.nextToken(), DEFAULT_VALUE_MAX_JOBS_ACTIVE) : + parseInt(CONF_WORKER_MAX_JOBS_ACTIVE, st.nextToken(), DEFAULT_VALUE_MAX_JOBS_ACTIVE, contextLog) : null); } else if (CamundaEngine.CAMUNDA_8_SAAS.equals(bpmnServerDefinition.serverType)) { - bpmnServerDefinition.zeebeCloudRegister = (st.hasMoreTokens() ? st.nextToken() : null); - bpmnServerDefinition.zeebeCloudRegion = (st.hasMoreTokens() ? st.nextToken() : null); - bpmnServerDefinition.zeebeCloudClusterId = (st.hasMoreTokens() ? st.nextToken() : null); - bpmnServerDefinition.zeebeCloudClientId = (st.hasMoreTokens() ? st.nextToken() : null); - bpmnServerDefinition.zeebeClientSecret = (st.hasMoreTokens() ? st.nextToken() : null); + bpmnServerDefinition.zeebeSaasRegion = (st.hasMoreTokens() ? st.nextToken() : null); + bpmnServerDefinition.zeebeSaasClusterId = (st.hasMoreTokens() ? st.nextToken() : null); + bpmnServerDefinition.zeebeSaasClientId = (st.hasMoreTokens() ? st.nextToken() : null); + bpmnServerDefinition.zeebeSaasClientSecret = (st.hasMoreTokens() ? st.nextToken() : null); + bpmnServerDefinition.zeebeSaasOAuthUrl = (st.hasMoreTokens() ? st.nextToken() : null); + bpmnServerDefinition.zeebeSaasAudience = (st.hasMoreTokens() ? st.nextToken() : null); bpmnServerDefinition.operateUrl = (st.hasMoreTokens() ? st.nextToken() : null); bpmnServerDefinition.operateUserName = (st.hasMoreTokens() ? st.nextToken() : null); bpmnServerDefinition.operateUserPassword = (st.hasMoreTokens() ? st.nextToken() : null); bpmnServerDefinition.taskListUrl = (st.hasMoreTokens() ? st.nextToken() : null); bpmnServerDefinition.workerExecutionThreads = (st.hasMoreTokens() ? - parseInt("executionThread", st.nextToken(), DEFAULT_VALUE_EXECUTION_THREADS) : + parseInt(CONF_WORKER_EXECUTION_THREADS, st.nextToken(), DEFAULT_VALUE_EXECUTION_THREADS, contextLog) : null); bpmnServerDefinition.workerMaxJobsActive = (st.hasMoreTokens() ? - parseInt("jobActive", st.nextToken(), DEFAULT_VALUE_MAX_JOBS_ACTIVE) : + parseInt(CONF_WORKER_MAX_JOBS_ACTIVE, st.nextToken(), DEFAULT_VALUE_MAX_JOBS_ACTIVE, contextLog) : null); } return bpmnServerDefinition; @@ -228,7 +275,7 @@ private BpmnServerDefinition decodeServerConnection(String connectionString) thr } /** - * Get the list from the serverConfiguration Explode the variable + * Get the list from the serverConfiguration. If the variable exist, then use the value. Easy to configure for K8 * * @return list of BpmnServer */ @@ -243,13 +290,15 @@ private List getFromServerConfiguration() { camunda7.camunda7ServerUrl = configurationServersEngine.camunda7Url; camunda7.camunda7UserName = configurationServersEngine.camunda7UserName; camunda7.camunda7Password = configurationServersEngine.camunda7Password; - camunda7.workerMaxJobsActive = parseInt("Camunda7.workerMaxJobsActive", - configurationServersEngine.C7WorkerMaxJobsActive, DEFAULT_VALUE_MAX_JOBS_ACTIVE); - camunda7.workerExecutionThreads = parseInt("Camunda7.workerExecutionThreads", - configurationServersEngine.C7WorkerMaxJobsActive, DEFAULT_VALUE_EXECUTION_THREADS); - camunda7.workerMaxJobsActive = parseInt("Camunda7.workerMaxJobsActive", - configurationServersEngine.C7WorkerMaxJobsActive, DEFAULT_VALUE_MAX_JOBS_ACTIVE); + camunda7.workerMaxJobsActive = parseInt("Camunda7."+CONF_WORKER_MAX_JOBS_ACTIVE, + configurationServersEngine.C7WorkerMaxJobsActive, DEFAULT_VALUE_MAX_JOBS_ACTIVE, ""); + camunda7.workerExecutionThreads = parseInt("Camunda7."+CONF_WORKER_EXECUTION_THREADS, + configurationServersEngine.C7WorkerMaxJobsActive, DEFAULT_VALUE_EXECUTION_THREADS, ""); + ; + + camunda7.workerMaxJobsActive = parseInt("Camunda7."+CONF_WORKER_MAX_JOBS_ACTIVE, + configurationServersEngine.C7WorkerMaxJobsActive, DEFAULT_VALUE_MAX_JOBS_ACTIVE, ""); list.add(camunda7); logger.info("Configuration: Camunda7 Name[{}] url[{}] MaxJobsActive[{}]", camunda7.name, camunda7.camunda7ServerUrl, camunda7.workerMaxJobsActive); @@ -259,14 +308,14 @@ private List getFromServerConfiguration() { camunda8.serverType = CamundaEngine.CAMUNDA_8; camunda8.name = configurationServersEngine.zeebeName; camunda8.zeebeGatewayAddress = configurationServersEngine.zeebeGatewayAddress; - camunda8.workerExecutionThreads = parseInt("Camunda8.workerExecutionThreads", - configurationServersEngine.workerExecutionThreads, DEFAULT_VALUE_EXECUTION_THREADS); - camunda8.workerMaxJobsActive = parseInt("Camunda8.workerMaxJobsActive", - configurationServersEngine.C8WorkerMaxJobsActive, DEFAULT_VALUE_MAX_JOBS_ACTIVE); - camunda8.operateUrl = configurationServersEngine.operateUrl; - camunda8.operateUserName = configurationServersEngine.operateUserName; - camunda8.operateUserPassword = configurationServersEngine.operateUserPassword; - camunda8.taskListUrl = configurationServersEngine.taskListUrl; + camunda8.workerExecutionThreads = parseInt("Camunda8."+CONF_WORKER_EXECUTION_THREADS, + configurationServersEngine.zeebeWorkerExecutionThreads, DEFAULT_VALUE_EXECUTION_THREADS, ""); + camunda8.workerMaxJobsActive = parseInt("Camunda8."+CONF_WORKER_MAX_JOBS_ACTIVE, + configurationServersEngine.zeebeWorkerMaxJobsActive, DEFAULT_VALUE_MAX_JOBS_ACTIVE, ""); + camunda8.operateUrl = configurationServersEngine.zeebeOperateUrl; + camunda8.operateUserName = configurationServersEngine.zeebeOperateUserName; + camunda8.operateUserPassword = configurationServersEngine.zeebeOperateUserPassword; + camunda8.taskListUrl = configurationServersEngine.zeebeTaskListUrl; list.add(camunda8); logger.info( "Configuration: Camunda8 Name[{}] zeebeGateway[{}] MaxJobsActive[{}] WorkerThreads[{}] " + "OperateURL[{}]", @@ -274,18 +323,20 @@ private List getFromServerConfiguration() { camunda8.operateUrl); } - if (hasValue(configurationServersEngine.zeebeCloudRegister)) { + if (hasValue(configurationServersEngine.zeebeSaasClusterId)) { BpmnServerDefinition camunda8 = new BpmnServerDefinition(); - - camunda8.zeebeCloudRegister = configurationServersEngine.zeebeCloudRegister; - camunda8.zeebeCloudRegion = configurationServersEngine.zeebeCloudRegion; - camunda8.zeebeCloudClusterId = configurationServersEngine.zeebeCloudClusterId; - camunda8.zeebeCloudClientId = configurationServersEngine.zeebeCloudClientId; - camunda8.zeebeClientSecret = configurationServersEngine.zeebeClientSecret; - camunda8.operateUrl = configurationServersEngine.operateUrl; - camunda8.operateUserName = configurationServersEngine.operateUserName; - camunda8.operateUserPassword = configurationServersEngine.operateUserPassword; - camunda8.taskListUrl = configurationServersEngine.taskListUrl; + camunda8.serverType= CamundaEngine.CAMUNDA_8_SAAS; + camunda8.name = configurationServersEngine.zeebeName; + camunda8.zeebeSaasRegion = configurationServersEngine.zeebeSaasRegion; + camunda8.zeebeSaasClusterId = configurationServersEngine.zeebeSaasClusterId; + camunda8.zeebeSaasClientId = configurationServersEngine.zeebeSaasClientId; + camunda8.zeebeSaasClientSecret = configurationServersEngine.zeebeSaasClientSecret; + camunda8.zeebeSaasOAuthUrl = configurationServersEngine.zeebeSaasOAuthUrl; + camunda8.zeebeSaasAudience = configurationServersEngine.zeebeSaasAudience; + camunda8.operateUrl = configurationServersEngine.zeebeOperateUrl; + camunda8.operateUserName = configurationServersEngine.zeebeOperateUserName; + camunda8.operateUserPassword = configurationServersEngine.zeebeOperateUserPassword; + camunda8.taskListUrl = configurationServersEngine.zeebeTaskListUrl; list.add(camunda8); } @@ -301,39 +352,45 @@ private List getFromServerConfiguration() { /* */ /* ******************************************************************** */ - private String getString(String name, Map record, String defaultValue) { + private String getString(String name, Map record, String defaultValue, String contextLog) { try { if (!record.containsKey(name)) { - logger.error("Variable [{}] not defined", name); + if (defaultValue==null) + logger.error(contextLog+"Variable [{}] not defined in {}", name, contextLog); + else + logger.info(contextLog+"Variable [{}] not defined in {}", name, contextLog); return defaultValue; } return (String) record.get(name); } catch (Exception e) { - logger.error("Variable [{}] bad definition {}", name, e.getMessage()); + logger.error(contextLog+"Variable [{}] {} bad definition {}", name, contextLog, e.getMessage()); return defaultValue; } } - private Integer getInteger(String name, Map record, Integer defaultValue) { + private Integer getInteger(String name, Map record, Integer defaultValue, String contextLog) { try { if (!record.containsKey(name)) { - logger.error("Variable [{}] not defined", name); + if (defaultValue==null) + logger.error("Variable [{}] not defined in {}", name, contextLog); + else + logger.info("Variable [{}] not defined in {}", name, contextLog); return defaultValue; } return (Integer) record.get(name); } catch (Exception e) { - logger.error("Variable [{}] bad definition {}", name, e.getMessage()); + logger.error("Variable [{}] {} bad definition {}", name, contextLog, e.getMessage()); return defaultValue; } } - private int parseInt(String label, String value, int defaultValue) { + private int parseInt(String label, String value, int defaultValue, String contextLog) { try { if (value.equals("''")) return defaultValue; return Integer.parseInt(value); } catch (Exception e) { - logger.error("Can't parse value [{}] at [{}]", value, label); + logger.error("Can't parse value [{}] at [{}] {}", value, label, contextLog); return defaultValue; } } @@ -377,14 +434,12 @@ public static class BpmnServerDefinition { /** * SaaS Zeebe */ - public String zeebeCloudRegister; - public String zeebeCloudRegion; - public String zeebeCloudClusterId; - public String zeebeCloudClientId; - public String zeebeClientSecret; - - public Integer workerExecutionThreads = Integer.valueOf(DEFAULT_VALUE_EXECUTION_THREADS); - public Integer workerMaxJobsActive = Integer.valueOf(DEFAULT_VALUE_MAX_JOBS_ACTIVE); + public String zeebeSaasRegion; + public String zeebeSaasClusterId; + public String zeebeSaasClientId; + public String zeebeSaasClientSecret; + public String zeebeSaasOAuthUrl; + public String zeebeSaasAudience; /** * Connection to Operate @@ -394,12 +449,20 @@ public static class BpmnServerDefinition { public String operateUrl; public String taskListUrl; - /** + + /** * Camunda 7 */ public String camunda7ServerUrl; public String camunda7UserName; public String camunda7Password; + + /** + * Common Camunda 7 and Camunda8 + */ + public Integer workerExecutionThreads = Integer.valueOf(DEFAULT_VALUE_EXECUTION_THREADS); + public Integer workerMaxJobsActive = Integer.valueOf(DEFAULT_VALUE_MAX_JOBS_ACTIVE); + } } diff --git a/src/main/java/org/camunda/automator/configuration/ConfigurationServersEngine.java b/src/main/java/org/camunda/automator/configuration/ConfigurationServersEngine.java index 732c72a..1c39f4b 100644 --- a/src/main/java/org/camunda/automator/configuration/ConfigurationServersEngine.java +++ b/src/main/java/org/camunda/automator/configuration/ConfigurationServersEngine.java @@ -18,6 +18,8 @@ public class ConfigurationServersEngine { public List serversConnection; public List> serversList; + + @Value("${automator.servers.camunda7.url:''}") public String camunda7Url; @Value("${automator.servers.camunda7.username:}") @@ -28,32 +30,50 @@ public class ConfigurationServersEngine { public String camunda7Name; @Value("${automator.servers.camunda7.workerMaxJobsActive:''}") public String C7WorkerMaxJobsActive; + @Value("${automator.servers.camunda8.name:''}") public String zeebeName; @Value("${automator.servers.camunda8.zeebeGatewayAddress:''}") public String zeebeGatewayAddress; - @Value("${automator.servers.camunda8.zeebeCloudRegister:''}") - public String zeebeCloudRegister; - @Value("${automator.servers.camunda8.zeebeCloudRegion:''}") - public String zeebeCloudRegion; - @Value("${automator.servers.camunda8.zeebeCloudClusterId:''}") - public String zeebeCloudClusterId; - @Value("${automator.servers.camunda8.zeebeCloudClientId:''}") - public String zeebeCloudClientId; - @Value("${automator.servers.camunda8.clientSecret:''}") - public String zeebeClientSecret; @Value("${automator.servers.camunda8.operateUrl:''}") - public String operateUrl; + public String zeebeOperateUrl; @Value("${automator.servers.camunda8.operateUserName:''}") - public String operateUserName; + public String zeebeOperateUserName; @Value("${automator.servers.camunda8.operateUserPassword:''}") - public String operateUserPassword; + public String zeebeOperateUserPassword; @Value("${automator.servers.camunda8.taskListUrl:''}") - public String taskListUrl; + public String zeebeTaskListUrl; @Value("${automator.servers.camunda8.workerExecutionThreads:''}") - public String workerExecutionThreads; + public String zeebeWorkerExecutionThreads; @Value("${automator.servers.camunda8.workerMaxJobsActive:''}") - public String C8WorkerMaxJobsActive; + public String zeebeWorkerMaxJobsActive; + + + @Value("${automator.servers.camunda8Saas.region:''}") + public String zeebeSaasRegion; + @Value("${automator.servers.camunda8Saas.clusterId:''}") + public String zeebeSaasClusterId; + @Value("${automator.servers.camunda8Saas.clientId:''}") + public String zeebeSaasClientId; + @Value("${automator.servers.camunda8Saas.oAuthUrl:''}") + public String zeebeSaasOAuthUrl; + @Value("${automator.servers.camunda8Saas.audience:''}") + public String zeebeSaasAudience; + + @Value("${automator.servers.camunda8Saas.secret:''}") + public String zeebeSaasClientSecret; + @Value("${automator.servers.camunda8Saas.operateUrl:''}") + public String zeebeSaasOperateUrl; + @Value("${automator.servers.camunda8Saas.operateUserName:''}") + public String zeebeSaasOperateUserName; + @Value("${automator.servers.camunda8Saas.operateUserPassword:''}") + public String zeebeSaasOperateUserPassword; + @Value("${automator.servers.camunda8Saas.taskListUrl:''}") + public String zeebeSaasTaskListUrl; + @Value("${automator.servers.camunda8Saas.workerExecutionThreads:''}") + public String zeebeSaasWorkerExecutionThreads; + @Value("${automator.servers.camunda8Saas.workerMaxJobsActive:''}") + public String zeebeSaasWorkerMaxJobsActive; public List> getServersList() { return serversList; diff --git a/src/main/java/org/camunda/automator/configuration/ConfigurationStartup.java b/src/main/java/org/camunda/automator/configuration/ConfigurationStartup.java index 9eb2aa9..4f69d3f 100644 --- a/src/main/java/org/camunda/automator/configuration/ConfigurationStartup.java +++ b/src/main/java/org/camunda/automator/configuration/ConfigurationStartup.java @@ -32,6 +32,9 @@ public class ConfigurationStartup { @Value("${automator.startup.waitWarmUpServer:PT0S}") public String waitWarmupServer; + @Value("${automator.startup.serverName}") + private String serverName; + @Value("#{'${automator.startup.scenarioFileAtStartup:}'.split(';')}") private List scenarioFileAtStartup; @@ -41,6 +44,10 @@ public class ConfigurationStartup { @Value("#{'${automator.startup.filterService:}'.split(';')}") private List filterService; + public String getServerName() { + return serverName; + } + public void setLogLevel(String logLevel) { this.logLevel = logLevel; } diff --git a/src/main/java/org/camunda/automator/definition/Scenario.java b/src/main/java/org/camunda/automator/definition/Scenario.java index 75662d0..c273979 100644 --- a/src/main/java/org/camunda/automator/definition/Scenario.java +++ b/src/main/java/org/camunda/automator/definition/Scenario.java @@ -29,19 +29,31 @@ public class Scenario { static Logger logger = LoggerFactory.getLogger(Scenario.class); - private final List executions = new ArrayList<>(); private final List deployments = new ArrayList<>(); private final List flows = new ArrayList<>(); + + public enum TYPESCENARIO { FLOW, UNIT}; + + public TYPESCENARIO typeScenario; + + /** + * Type FLOW + */ private ScenarioWarmingUp warmingUp; private ScenarioFlowControl flowControl; + /** + * Type UNIT + */ + private final List executions = new ArrayList<>(); + private String name; private String version; private String processName; private String processId; /** - * Server to run the scenario + * Server to run the scenario (optional, will be overide by the configuration) */ private String serverName; @@ -173,20 +185,13 @@ public File getScenarioFile() { } } + public String getServerName() { if (serverName == null || serverName.isEmpty()) return null; return serverName; } - public BpmnEngineList.CamundaEngine getServerType() { - try { - return BpmnEngineList.CamundaEngine.valueOf(serverType.toUpperCase()); - } catch (Exception e) { - return null; - } - - } private void afterUnSerialize() { // Attention, now we have to manually set the tree relation diff --git a/src/main/java/org/camunda/automator/engine/RunParameters.java b/src/main/java/org/camunda/automator/engine/RunParameters.java index 917c7dc..3b6a29b 100644 --- a/src/main/java/org/camunda/automator/engine/RunParameters.java +++ b/src/main/java/org/camunda/automator/engine/RunParameters.java @@ -6,6 +6,8 @@ public class RunParameters { private LOGLEVEL logLevel = LOGLEVEL.MONITORING; + private String serverName; + private int numberOfThreadsPerScenario = 10; /** @@ -49,6 +51,14 @@ public LOGLEVEL getLogLevel() { return logLevel; } + public RunParameters setServerName(String serverName) { + this.serverName = serverName; + return this; + } + public String getServerName() { + return this.serverName; + } + public RunParameters setLogLevel(LOGLEVEL logLevel) { this.logLevel = logLevel; return this; diff --git a/src/main/java/org/camunda/automator/engine/RunResult.java b/src/main/java/org/camunda/automator/engine/RunResult.java index fd81044..0185ca3 100644 --- a/src/main/java/org/camunda/automator/engine/RunResult.java +++ b/src/main/java/org/camunda/automator/engine/RunResult.java @@ -157,7 +157,9 @@ public void addVerification(ScenarioVerificationBasic verification, boolean isSu this.listVerifications.add(verificationStatus); } - +public boolean hasErrors() { + return ! listErrors.isEmpty(); +} /* ******************************************************************** */ /* */ @@ -260,17 +262,18 @@ public int getNumberOfErrorSteps() { */ public String getSynthesis(boolean fullDetail) { StringBuilder synthesis = new StringBuilder(); - synthesis.append(isSuccess() ? "SUCCESS " : "FAIL "); + synthesis.append((isSuccess() && ! hasErrors()) ? "SUCCESS " : "FAIL "); synthesis.append(runScenario.getScenario().getName()); synthesis.append("("); synthesis.append(runScenario.getScenario().getProcessId()); synthesis.append("): "); - synthesis.append(timeExecution); + StringBuilder append = synthesis.append(timeExecution); synthesis.append(" timeExecution(ms), "); - synthesis.append(recordCreationPIMap.get(runScenario.getScenario().getProcessId()).nbCreated); + RecordCreationPI recordCreationPI = recordCreationPIMap.get(runScenario.getScenario().getProcessId()); + synthesis.append(recordCreationPI==null? 0 : recordCreationPI.nbCreated); synthesis.append(" PICreated, "); - synthesis.append(recordCreationPIMap.get(runScenario.getScenario().getProcessId()).nbFailed); + synthesis.append(recordCreationPI==null? 0 : recordCreationPI.nbFailed); synthesis.append(" PIFailed, "); synthesis.append(numberOfSteps); synthesis.append(" stepsExecuted, "); diff --git a/src/main/java/org/camunda/automator/engine/RunScenario.java b/src/main/java/org/camunda/automator/engine/RunScenario.java index d76878a..7994973 100644 --- a/src/main/java/org/camunda/automator/engine/RunScenario.java +++ b/src/main/java/org/camunda/automator/engine/RunScenario.java @@ -64,6 +64,23 @@ public RunScenario(Scenario scenario, */ public RunResult runScenario() { RunResult result = new RunResult(this); + + // control + if (scenario.typeScenario == null) { + result.addError(null, "TypeScenario undefined"); + } + if (scenario.typeScenario.equals(Scenario.TYPESCENARIO.UNIT)) { + if (scenario.getExecutions() == null || scenario.getExecutions().isEmpty()) + result.addError(null, "TypeScenario[" + Scenario.TYPESCENARIO.UNIT + "] must have a list of [executions]"); + } else if (scenario.typeScenario.equals(Scenario.TYPESCENARIO.FLOW)) { + if (scenario.getFlowControl() == null) + result.addError(null, "TypeScenario[" + Scenario.TYPESCENARIO.FLOW + "] must have a list of [flowControl]"); + if (scenario.getFlows() == null || scenario.getFlows().isEmpty()) + result.addError(null, "TypeScenario[" + Scenario.TYPESCENARIO.FLOW + "] must have a list of [flows]"); + } + if (result.hasErrors()) + return result; + logger.info("RunScenario: ------ Deployment ({})", runParameters.isDeploymentProcess()); if (runParameters.isDeploymentProcess()) result.add(runDeployment()); @@ -126,8 +143,11 @@ public RunResult runExecutions() { ExecutorService executor = Executors.newFixedThreadPool(runParameters.getNumberOfThreadsPerScenario()); // the scenario can be an Execution or a Flow - if (!scenario.getExecutions().isEmpty()) { + if (scenario.typeScenario.equals(Scenario.TYPESCENARIO.UNIT)) { List> listFutures = new ArrayList<>(); + logger.info("RunScenario: ------ execution UNIT scenario [{}] {} execution on {} Threads", scenario.getName(), + scenario.getExecutions().size(), + runParameters.getNumberOfThreadsPerScenario()); for (int i = 0; i < scenario.getExecutions().size(); i++) { ScenarioExecution scnExecution = scenario.getExecutions().get(i); @@ -150,10 +170,13 @@ public RunResult runExecutions() { } catch (Exception e) { result.addError(null, "Error during executing in parallel " + e.getMessage()); } + logger.info("RunScenario: ------ End execution"); } - if (!scenario.getFlows().isEmpty()) { + if (scenario.typeScenario.equals(Scenario.TYPESCENARIO.FLOW)) { + logger.info("RunScenario: ------ execution FLOW scenario [{}]", scenario.getName()); RunScenarioFlows scenarioFlows = new RunScenarioFlows(serviceAccess, this); scenarioFlows.execute(result); + logger.info("RunScenario: ------ End execution"); } return result; diff --git a/src/main/java/org/camunda/automator/engine/flow/RunScenarioFlows.java b/src/main/java/org/camunda/automator/engine/flow/RunScenarioFlows.java index 9389c6b..533803c 100644 --- a/src/main/java/org/camunda/automator/engine/flow/RunScenarioFlows.java +++ b/src/main/java/org/camunda/automator/engine/flow/RunScenarioFlows.java @@ -7,6 +7,7 @@ package org.camunda.automator.engine.flow; import org.camunda.automator.bpmnengine.BpmnEngine; +import org.camunda.automator.definition.ScenarioFlowControl; import org.camunda.automator.definition.ScenarioStep; import org.camunda.automator.engine.RunResult; import org.camunda.automator.engine.RunScenario; @@ -16,6 +17,7 @@ import java.time.Duration; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -41,8 +43,16 @@ public void execute(RunResult runResult) { // Create one executor per flow RunScenarioWarmingUp runScenarioWarmingUp = new RunScenarioWarmingUp(serviceAccess, runScenario); Map recordCreationPIMap = new HashMap<>(); - RunObjectives runObjectives = new RunObjectives(runScenario.getScenario().getFlowControl().getObjectives(), - runScenario.getBpmnEngine(), recordCreationPIMap); + if (runScenario.getScenario().getFlowControl() == null) { + runResult.addError(null, "Scenario does not declare a [FlowControl] section. This section is mandatory for a Flow Scenario"); + return; + } + + List listObjectives = runScenario.getScenario().getFlowControl().getObjectives(); + if (listObjectives == null) + listObjectives = Collections.emptyList(); + + RunObjectives runObjectives = new RunObjectives(listObjectives, runScenario.getBpmnEngine(), recordCreationPIMap); logger.info("ScenarioFlow: ------ WarmingUp"); runScenarioWarmingUp.warmingUp(runResult); @@ -66,10 +76,8 @@ public void execute(RunResult runResult) { // Check with Objective now logger.info("ScenarioFlow: ------ CheckObjectives"); - if (runScenario.getScenario().getFlowControl() != null - && runScenario.getScenario().getFlowControl().getObjectives() != null) { - checkObjectives(runObjectives, startTestDate, endTestDate, runResult); - } + checkObjectives(runObjectives, startTestDate, endTestDate, runResult); + logger.info("ScenarioFlow: ------ TheEnd"); } diff --git a/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitServiceTask.java b/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitServiceTask.java index 45d4741..7f0f00d 100644 --- a/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitServiceTask.java +++ b/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitServiceTask.java @@ -5,12 +5,16 @@ import org.camunda.automator.engine.RunResult; import org.camunda.automator.engine.RunScenario; import org.camunda.automator.engine.RunZeebeOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.time.Duration; import java.util.List; public class RunScenarioUnitServiceTask { + private final Logger logger = LoggerFactory.getLogger(RunScenarioUnitServiceTask.class); + private final RunScenario runScenario; protected RunScenarioUnitServiceTask(RunScenario runScenario) { @@ -25,6 +29,10 @@ protected RunScenarioUnitServiceTask(RunScenario runScenario) { * @return result completed */ public RunResult executeServiceTask(RunResult result, ScenarioStep step) { + if (runScenario.getRunParameters().showLevelMonitoring()) { + logger.info("Service TaskId[{}]", step.getTaskId()); + } + if (step.getDelay() != null) { Duration duration = Duration.parse(step.getDelay()); try { diff --git a/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitStartEvent.java b/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitStartEvent.java index 71a4bb8..bd47d96 100644 --- a/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitStartEvent.java +++ b/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitStartEvent.java @@ -5,9 +5,15 @@ import org.camunda.automator.engine.RunResult; import org.camunda.automator.engine.RunScenario; import org.camunda.automator.engine.RunZeebeOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; public class RunScenarioUnitStartEvent { + private final Logger logger = LoggerFactory.getLogger(RunScenarioUnitStartEvent.class); + private final RunScenario runScenario; protected RunScenarioUnitStartEvent(RunScenario runScenario) { @@ -23,9 +29,16 @@ protected RunScenarioUnitStartEvent(RunScenario runScenario) { */ public RunResult startEvent(RunResult result, ScenarioStep step) { try { - result.addProcessInstanceId(step.getScnExecution().getScnHead().getProcessId(), runScenario.getBpmnEngine() - .createProcessInstance(step.getScnExecution().getScnHead().getProcessId(), step.getTaskId(), // activityId - RunZeebeOperation.getVariablesStep(runScenario, step))); // resolve variables + if (runScenario.getRunParameters().showLevelMonitoring()) { + logger.info("StartEvent EventId[{}]", step.getTaskId()); + } + String processId = step.getScnExecution().getScnHead().getProcessId(); + Map processVariables = RunZeebeOperation.getVariablesStep(runScenario, step); + + String processInstanceId = runScenario.getBpmnEngine() + .createProcessInstance(processId, step.getTaskId(), processVariables); + + result.addProcessInstanceId(processId, processInstanceId); } catch (AutomatorException e) { result.addError(step, "Error at creation " + e.getMessage()); } diff --git a/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitUserTask.java b/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitUserTask.java index 32cd61d..94d8ee3 100644 --- a/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitUserTask.java +++ b/src/main/java/org/camunda/automator/engine/unit/RunScenarioUnitUserTask.java @@ -5,12 +5,16 @@ import org.camunda.automator.engine.RunResult; import org.camunda.automator.engine.RunScenario; import org.camunda.automator.engine.RunZeebeOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.time.Duration; import java.util.List; public class RunScenarioUnitUserTask { + private final Logger logger = LoggerFactory.getLogger(RunScenarioUnitUserTask.class); + private final RunScenario runScenario; protected RunScenarioUnitUserTask(RunScenario runScenario) { @@ -26,6 +30,10 @@ protected RunScenarioUnitUserTask(RunScenario runScenario) { */ public RunResult executeUserTask(RunResult result, ScenarioStep step) { + if (runScenario.getRunParameters().showLevelMonitoring()) { + logger.info("UserTask TaskId[{}]", step.getTaskId()); + } + if (step.getDelay() != null) { Duration duration = Duration.parse(step.getDelay()); try { diff --git a/src/main/java/org/camunda/automator/services/AutomatorStartup.java b/src/main/java/org/camunda/automator/services/AutomatorStartup.java index f187925..620a9a1 100644 --- a/src/main/java/org/camunda/automator/services/AutomatorStartup.java +++ b/src/main/java/org/camunda/automator/services/AutomatorStartup.java @@ -45,8 +45,11 @@ public void init() { if (AutomatorCLI.isRunningCLI) return; + logger.info("AutomatorStartup-start"); AutomatorSetupRunnable automatorSetupRunnable = new AutomatorSetupRunnable(configurationStartup, automatorAPI, automatorCLI, engineConfiguration); + + // start the automator startup immediately, and Spring can continue to start the application serviceAccess.getTaskScheduler("AutomatorSetup").schedule(automatorSetupRunnable, Instant.now()); } @@ -100,8 +103,10 @@ private List registerScenario() { configurationStartup.getScenarioResourceAtStartupName()); for (Resource resource : configurationStartup.getScenarioResourceAtStartup()) { - logger.info("Load scenario [Resource] from [{}]", resource.getDescription()); - scenarioList.add(resource); + if (resource!=null) { + logger.info("Load scenario [Resource] from [{}]", resource.getDescription()); + scenarioList.add(resource); + } } } @@ -136,6 +141,7 @@ public void run() { RunParameters runParameters = new RunParameters(); runParameters.setExecution(true) + .setServerName(configurationStartup.getServerName()) .setLogLevel(configurationStartup.getLogLevelEnum()) .setCreation(configurationStartup.isPolicyExecutionCreation()) .setServiceTask(configurationStartup.isPolicyExecutionServiceTask()) @@ -149,7 +155,8 @@ public void run() { } logger.info( - "AutomatorStartup parameters warmingUp[{}] creation:[{}] serviceTask:[{}] userTask:[{}] ScenarioPath[{}] logLevel[{}] waitWarmingUpServer[{} s]", + "AutomatorStartup parameters serverName[{}] warmingUp[{}] creation:[{}] serviceTask:[{}] userTask:[{}] ScenarioPath[{}] logLevel[{}] waitWarmingUpServer[{} s]", + runParameters.getServerName(), runParameters.isWarmingUp(), runParameters.isCreation(), runParameters.isServiceTask(), runParameters.isUserTask(), configurationStartup.scenarioPath, configurationStartup.logLevel, configurationStartup.getWarmingUpServer().toMillis() / 1000); @@ -199,10 +206,22 @@ else if (scenarioObject instanceof Resource scenarioResource) { String message = ""; try { if (runParameters.showLevelDashboard()) { - logger.info("Connect to Bpmn Engine Type [{}] for scenario [{}]", scenario.getServerType(), - scenario.getName()); + logger.info("Connect to Bpmn Engine for scenario [{}]", scenario.getName()); + } + if (scenario.getServerName() != null && !scenario.getServerName().isEmpty()) { + bpmnEngine = automatorAPI.getBpmnEngineFromScenario(scenario, engineConfiguration); + + } else { + if (runParameters.getServerName() == null) + throw new AutomatorException("No Server define in configuration"); + BpmnEngineList.BpmnServerDefinition serverDefinition = engineConfiguration.getByServerName( + runParameters.getServerName()); + if (serverDefinition == null) + throw new AutomatorException( + "Server [" + runParameters.getServerName() + "] does not exist in the list"); + + bpmnEngine = automatorAPI.getBpmnEngine(serverDefinition, true); } - bpmnEngine = automatorAPI.getBpmnEngineFromScenario(scenario, engineConfiguration); if (!bpmnEngine.isReady()) { bpmnEngine.connection(); } @@ -212,9 +231,8 @@ else if (scenarioObject instanceof Resource scenarioResource) { } if (pleaseTryAgain && countEngineIsNotReady < 10) { logger.info( - "Scenario [{}] file[{}] No BPM ENGINE running [{}] tentative:{}/10. Sleep 30s. Scenario reference serverName[{}] serverType[{}]", - message, countEngineIsNotReady, scenario.getName(), scenario.getName(), scenario.getServerName(), - scenario.getServerType()); + "Scenario [{}] file[{}] No BPM ENGINE running [{}] tentative:{}/10. Sleep 30s. Scenario reference serverName[{}]", + message, countEngineIsNotReady, scenario.getName(), scenario.getName(), scenario.getServerName()); try { Thread.sleep(((long) 1000) * 30); } catch (InterruptedException e) { @@ -224,8 +242,7 @@ else if (scenarioObject instanceof Resource scenarioResource) { } while (pleaseTryAgain && countEngineIsNotReady < 10); if (bpmnEngine == null) { - logger.error("Scenario [{}] file[{}] No BPM ENGINE running. Scenario reference serverName[{}] serverType[{}]", - scenario.getName(), scenario.getName(), scenario.getServerName(), scenario.getServerType()); + logger.error("Scenario [{}] file[{}] No BPM ENGINE running.", scenario.getName(), scenario.getName()); continue; } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index e191c09..339df6b 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,15 +1,20 @@ automator: - - scheduler: startup: + # give the server to run all tests at startup. The name must be registered in the list of server after + serverName: + scenarioPath: ./src/main/resources/loadtest # list of scenario separate by ; scenarioAtStartup: file:/C8CrawlUrlScn.json; + + # one scenario resource - to be accessible in a Docker container via a configMap + scenarioResourceAtStartup: + # DEBUG, INFO, MONITORING, MAIN, NOTHING - logLevel: DASHBOARD + logLevel: MONITORING # string composed with DEPLOYPROCESS, WARMINGUP, CREATION, SERVICETASK, USERTASK # (ex: "CREATION|DEPLOYPROCESS|CREATION|SERVICETASK") policyExecution: DEPLOYPROCESS|WARMINGUP|CREATION|SERVICETASK|USERTASK @@ -22,21 +27,22 @@ automator: # servers connection is a list of connection separate by ; # each connection contains a name and a type. then, other parameters depends on the type # ,CAMUNDA_7, - # ,CAMUNDA_8,ZeebeGatewayAddress,OperateUserName,OperateUserPassword,OperateUrl - # ,CAMUNDA_8_SAAS,zeebeCloudRegister,zeebeCloudRegion,zeebeCloudClusterId,zeebeCloudClientId,clientSecret,OperateUserName,OperateUserPassword,OperateUrl + # ,CAMUNDA_8,ZeebeGatewayAddress,OperateUserName,OperateUserPassword,OperateUrl,ExecutionThreads,MaxJobActive + # ,CAMUNDA_8_SAAS,zeebeCloudRegion,zeebeCloudClusterId,zeebeCloudClientId, + # zeebeCloudOAuthUrl,zeebeCloudAudience,clientSecret,OperateUserName,OperateUserPassword,OperateUrl,ExecutionThreads,MaxJobActive - serversConnection: Camunda7URL,CAMUNDA_7,http://localhost:8080/engine-rest; \ - Camunda8URL,CAMUNDA_8,127.0.0.1:26500,demo,demo,http://localhost:8081 + serversConnection: Camunda7Diamond,CAMUNDA_7,http://localhost:8080/engine-rest; \ + Camunda8Safir,CAMUNDA_8,127.0.0.1:26500,demo,demo,http://localhost:8081 # other way to provide the list of server connection serversList: - type: "camunda7" - name: "camunda7Local" + name: "camunda7Emeraud" url: "http://localhost:8080/engine-rest" workerMaxJobsActive: 20 - type: "camunda8" - name: "Camunda8Local" + name: "Camunda8Ruby" zeebeGatewayAddress: "127.0.0.1:26500" operateUserName: "demo" operateUserPassword: "demo" @@ -46,23 +52,31 @@ automator: workerMaxJobsActive: 10 - type: "camunda8saas" - name: "Camunda8SaaS" - zeebeCloudRegister: "aaa" - zeebeCloudRegion: "usa" - zeebeClientSecret: "bbb" - zeebeCloudClusterId: "ddd" - zeebeCloudClientId: "eee" + name: "Camunda8Grena" + workerExecutionThreads: 10 + workerMaxJobsActive: 10 + + # Cluster 8.3.0 + region: "bru-2" + clusterId: "4b...e2" + clientId: "bs...6a" + secret: "-Ez...ZG" + oAuthUrl: "https://login.cloud.camunda.io/oauth/token" + audience: "zeebe.camunda.io" + operateUrl: "https://bru-2.operate.camunda.io/4b..e2" + taskListUrl: "https://bru-2.tasklist.camunda.io/4b..e2" + # This definition is very simple to use in the K8 definition, because one variable can be override servers: camunda7: - name: "Camunda7Local" + name: "Camunda7Granit" url: "http://localhost:8080/engine-rest" workerMaxJobsActive: 20 camunda8: - name: "Camunda8Local" + name: "Camunda8Calcair" zeebeGatewayAddress: "127.0.0.1:26500" operateUserName: "demo" operateUserPassword: "demo" @@ -71,18 +85,27 @@ automator: workerExecutionThreads: 10 workerMaxJobsActive: 10 + camunda8Saas: + name: "Camunda8Marbble" + workerExecutionThreads: 10 + workerMaxJobsActive: 10 + operateUrl: "https://ont-1.operate.camunda.io/25fdd1e6-e4a1-4362-b49c-5eced08cb893" + taskListUrl: "https://ont-1.tasklist.camunda.io/25fdd1e6-e4a1-4362-b49c-5eced08cb893" + operateUserName: "demo" + operateUserPassword: "demo" + region: "ont-1" + clusterId: "25fdd1e6-e4a1-4362-b49c-5eced08cb893" + clientId: "eknOoiO5GYDdFf4ZjDSh8yaLG-BVCw9L" + oAuthUrl: "https://login.cloud.camunda.io/oauth/token" + audience: "" + secret: "4BPUva1U4lDtoG2-torvAtx6w5RbHULUFhGZ-bBXOMWwZJG3d3VDlfPHjVO3Kz-N" - #zeebeCloudRegister: - #zeebeCloudRegion: - #clientSecret: - #zeebeCloudClusterId: - #zeebeCloudClientId: -server.port: 8380 +server.port: 8381 scheduler.poolSize: 10 \ No newline at end of file diff --git a/src/test/java/automatorapi/TestSimpleUserTask.java b/src/test/java/automatorapi/TestSimpleUserTask.java index cdc45d7..1ae5a72 100644 --- a/src/test/java/automatorapi/TestSimpleUserTask.java +++ b/src/test/java/automatorapi/TestSimpleUserTask.java @@ -40,9 +40,7 @@ public void SimpleUserTaskAPI() { try { BpmnEngineList engineConfiguration = BpmnEngineConfigurationInstance.getDummy(); - BpmnEngine bpmnEngine = automatorApi.getBpmnEngineFromScenario(scenario, engineConfiguration); - if (bpmnEngine == null) - bpmnEngine = automatorApi.getBpmnEngine(engineConfiguration, engineConfiguration.getListServers().get(0)); + BpmnEngine bpmnEngine = automatorApi.getBpmnEngine(engineConfiguration.getListServers().get(0),true); RunResult scenarioExecutionResult = automatorApi.executeScenario(bpmnEngine, runParameters, scenario); assert (scenarioExecutionResult.isSuccess());