Skip to content

Commit

Permalink
new example: process state query
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanlukas committed Feb 6, 2024
1 parent e3ca150 commit 6ccfda7
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 0 deletions.
7 changes: 7 additions & 0 deletions process-state-query/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Query Process instance state

This code example shows how to query a process instance state.

Therefore, it uses the Operate REST API.

The `application.yaml` is configured to run with a local docker-compose core dev setup (without identity).
41 changes: 41 additions & 0 deletions process-state-query/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>
<artifactId>process-state-query</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.java>17</version.java>
<maven.compiler.source>${version.java}</maven.compiler.source>
<maven.compiler.target>${version.java}</maven.compiler.target>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.1.5</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>io.camunda.spring</groupId>
<artifactId>spring-boot-starter-camunda</artifactId>
<version>8.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.camunda.processStateQuery;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package io.camunda.processStateQuery;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.camunda.operate.CamundaOperateClient;
import io.camunda.operate.dto.FlownodeInstance;
import io.camunda.operate.dto.Incident;
import io.camunda.operate.dto.ProcessDefinition;
import io.camunda.operate.dto.ProcessInstance;
import io.camunda.operate.dto.Variable;
import io.camunda.operate.exception.OperateException;
import io.camunda.operate.search.FlownodeInstanceFilter;
import io.camunda.operate.search.IncidentFilter;
import io.camunda.operate.search.SearchQuery;
import io.camunda.operate.search.VariableFilter;
import io.camunda.processStateQuery.ProcessStateDto.ElementInstanceDto;
import io.camunda.processStateQuery.ProcessStateDto.IncidentDto;
import io.camunda.processStateQuery.ProcessStateDto.VariableDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

@RestController
public class ProcessStateController {
private static final Logger LOG = LoggerFactory.getLogger(ProcessStateController.class);
private final CamundaOperateClient camundaOperateClient;
private final ObjectMapper objectMapper;

@Autowired
public ProcessStateController(CamundaOperateClient camundaOperateClient, ObjectMapper objectMapper) {
this.camundaOperateClient = camundaOperateClient;
this.objectMapper = objectMapper;
}

@GetMapping("/process-states/{key}")
public ProcessStateDto getProcessState(@PathVariable("key") long key) throws OperateException {
LOG.info("Fetching process instance with key {}", key);
ProcessInstance processInstance = camundaOperateClient.getProcessInstance(key);
ProcessDefinition processDefinition = camundaOperateClient.getProcessDefinition(processInstance.getProcessDefinitionKey());
List<FlownodeInstance> flownodeInstances = camundaOperateClient.searchFlownodeInstances(new SearchQuery.Builder()
.filter(new FlownodeInstanceFilter.Builder()
.processInstanceKey(processInstance.getKey())
.build())
.build());
List<Incident> incidents = camundaOperateClient.searchIncidents(new SearchQuery.Builder()
.filter(new IncidentFilter.Builder()
.processInstanceKey(processInstance.getKey())
.build())
.build());
List<Variable> variables = camundaOperateClient
.searchVariables(new SearchQuery.Builder()
.filter(new VariableFilter.Builder()
.processInstanceKey(processInstance.getKey())
.build())
.build())
.stream()
.map(this::getVariable)
.toList();
return new ProcessStateDto(
processInstance.getKey(),
processInstance.getProcessDefinitionKey(),
processInstance.getBpmnProcessId(),
processDefinition.getName(),
buildElementInstances(flownodeInstances, variables),
buildIncidents(incidents),
buildVariables(variables, processInstance.getKey()),
processInstance
.getState()
.toString(),
fromDate(processInstance.getStartDate()),
fromDate(processInstance.getEndDate())
);
}

private List<IncidentDto> buildIncidents(List<Incident> incidents) {
return incidents
.stream()
.map(i -> new IncidentDto(i.getKey(), i.getMessage(), i.getState(), fromDate(i.getCreationTime())))
.toList();
}

private Variable getVariable(Variable variable) {
try {
return variable.getTruncated() ? camundaOperateClient.getVariable(variable.getKey()) : variable;
} catch (OperateException e) {
throw new RuntimeException(e);
}
}

private List<ElementInstanceDto> buildElementInstances(
List<FlownodeInstance> flownodeInstances, List<Variable> variables
) {
return flownodeInstances
.stream()
.map(fni -> buildElementInstance(fni, variables))
.toList();
}

private ElementInstanceDto buildElementInstance(FlownodeInstance flownodeInstance, List<Variable> variables) {
return new ElementInstanceDto(
flownodeInstance.getKey(),
flownodeInstance.getFlowNodeId(),
flownodeInstance.getFlowNodeName(),
buildVariables(variables, flownodeInstance.getKey()),
flownodeInstance
.getState()
.toString(),
fromDate(flownodeInstance.getStartDate()),
fromDate(flownodeInstance.getEndDate())
);
}

private List<VariableDto> buildVariables(List<Variable> variables, Long scopeKey) {
return variables
.stream()
.filter(v -> v
.getScopeKey()
.equals(scopeKey))
.map(v -> new VariableDto(v.getKey(), v.getName(), getVariableValue(v)))
.toList();
}

private JsonNode getVariableValue(Variable variable) {
try {
return objectMapper.readTree(variable.getValue());
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}

private LocalDateTime fromDate(Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.camunda.processStateQuery;

import com.fasterxml.jackson.databind.JsonNode;

import java.time.LocalDateTime;
import java.util.List;

public record ProcessStateDto(long processInstanceKey, long processDefinitionKey, String bpmnProcessId,
String processName, List<ElementInstanceDto> elementInstances,
List<IncidentDto> incidents, List<VariableDto> variables, String state,
LocalDateTime startDate, LocalDateTime endDate) {
public record ElementInstanceDto(long elementInstanceKey, String elementId, String elementName,
List<VariableDto> variables, String state, LocalDateTime startDate,
LocalDateTime endDate) {}

public record IncidentDto(long incidentKey, String message, String state, LocalDateTime creationTime) {}

public record VariableDto(long variableKey, String name, JsonNode value) {

}
}
10 changes: 10 additions & 0 deletions process-state-query/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
operate:
client:
enabled: true

camunda:
operate:
client:
url: http://localhost:8081
username: demo
password: demo

0 comments on commit 6ccfda7

Please sign in to comment.