Skip to content

Commit

Permalink
Introducing new structure of Spring Boot properties
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanpelikan committed Feb 26, 2024
1 parent ea7565b commit b7fe56b
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 13 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<artifactId>camunda8-adapter</artifactId>

<name>VanillaBP SPI adapter for Camunda 8.x</name>
<version>1.2.1-SNAPSHOT</version>
<version>1.3.0-SNAPSHOT</version>
<packaging>pom</packaging>

<properties>
Expand Down
29 changes: 29 additions & 0 deletions spring-boot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,35 @@ On using receive tasks Camunda 8 requires us to define correlation IDs. If your

In case your model has more than one receive task active you have to define unique correlation IDs for each receive task of that message name to enable the BPMS to find the right receive task to correlate to. This might happen for multi-instance receive tasks or receive tasks within a multi-instance embedded sub-process. In that case use the workflow id in combination with the multi-instance element as a correlation id: `=id+"+"+RequestRideOffer` (where "RequestRideOffer" is the name of the multi-instance element).

## Using Camunda multi-tenancy

Typically, on operating multiple workflow modules, one wants to avoid name clashes in Camunda (e.g. of event names, etc.).
Therefore, each workflow module is deployed to Camunda as a separate tenant using the workflow module's id as the tenant-id.

This behavior can be adapted.

**If you wish to define a custom tenant-id instead:**

```yaml
vanillabp:
workflow-modules:
ride:
adapters:
camunda8:
tenant-id: taxiride
```

**If you want to disable multi-tenancy:**

```yaml
vanillabp:
workflow-modules:
ride:
adapters:
camunda8:
use-tenants: false
```

## Transaction behavior

Since Camunda 8 is an external system to your services one has to deal with eventual consistency in conjunction with transactions. This adapter uses the recommended pattern to report a task as completed and roll back the local transaction in case of errors. Possible errors are:
Expand Down
4 changes: 2 additions & 2 deletions spring-boot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.camunda.community.vanillabp</groupId>
<artifactId>camunda8-adapter</artifactId>
<version>1.2.1-SNAPSHOT</version>
<version>1.3.0-SNAPSHOT</version>
</parent>

<artifactId>camunda8-spring-boot-adapter</artifactId>
Expand Down Expand Up @@ -35,7 +35,7 @@
<dependency>
<groupId>io.vanillabp</groupId>
<artifactId>spring-boot-support</artifactId>
<version>1.0.8-SNAPSHOT</version>
<version>1.1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.camunda</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
Expand All @@ -37,6 +38,7 @@

@AutoConfigurationPackage(basePackageClasses = Camunda8AdapterConfiguration.class)
@AutoConfigureBefore(CamundaAutoConfiguration.class)
@EnableConfigurationProperties(Camunda8VanillaBpProperties.class)
public class Camunda8AdapterConfiguration extends AdapterConfigurationBase<Camunda8ProcessService<?>> {

private static final Logger logger = LoggerFactory.getLogger(Camunda8AdapterConfiguration.class);
Expand Down Expand Up @@ -64,6 +66,9 @@ public class Camunda8AdapterConfiguration extends AdapterConfigurationBase<Camun
@Autowired
private DeploymentResourceRepository deploymentResourceRepository;

@Autowired
private Camunda8VanillaBpProperties camunda8Properties;

@PostConstruct
public void init() {

Expand All @@ -88,6 +93,7 @@ public Camunda8DeploymentAdapter camunda8Adapter(
return new Camunda8DeploymentAdapter(
applicationName,
properties,
camunda8Properties,
deploymentService,
camunda8TaskWiring);

Expand Down Expand Up @@ -159,7 +165,7 @@ public <DE> Camunda8ProcessService<?> newProcessServiceImplementation(
final CrudRepository<DE, Object> workflowAggregateRepository) {

final var result = new Camunda8ProcessService<DE>(
applicationName,
camunda8Properties,
workflowAggregateRepository,
workflowAggregate -> springDataUtil.getId(workflowAggregate),
workflowAggregateClass);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package io.vanillabp.camunda8;

import io.vanillabp.springboot.adapter.VanillaBpProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils;

import java.util.Map;

@ConfigurationProperties(prefix = VanillaBpProperties.PREFIX, ignoreUnknownFields = true)
public class Camunda8VanillaBpProperties {

private Map<String, WorkflowModuleAdapterProperties> workflowModules = Map.of();

public Map<String, WorkflowModuleAdapterProperties> getWorkflowModules() {
return workflowModules;
}

public void setWorkflowModules(Map<String, WorkflowModuleAdapterProperties> workflowModules) {

this.workflowModules = workflowModules;
workflowModules.forEach((workflowModuleId, properties) -> {
properties.workflowModuleId = workflowModuleId;
});

}

private static final WorkflowModuleAdapterProperties defaultProperties = new WorkflowModuleAdapterProperties();
private static final AdapterConfiguration defaultAdapterProperties = new AdapterConfiguration();

public String getTenantId(
final String workflowModuleId) {

final var configuration = workflowModules
.getOrDefault(workflowModuleId, defaultProperties)
.getAdapters()
.getOrDefault(Camunda8AdapterConfiguration.ADAPTER_ID, defaultAdapterProperties);
if (!configuration.isUseTenants()) {
return null;
}
if (StringUtils.hasText(configuration.getTenant())) {
return configuration.getTenant();
}
return workflowModuleId;

}

public static class AdapterConfiguration {

private boolean useTenants = true;

private String tenant;

public boolean isUseTenants() {
return useTenants;
}

public void setUseTenants(boolean useTenants) {
this.useTenants = useTenants;
}

public String getTenant() {
return tenant;
}

public void setTenant(String tenant) {
this.tenant = tenant;
}

}

public static class WorkflowModuleAdapterProperties {

String workflowModuleId;

private Map<String, AdapterConfiguration> adapters = Map.of();

public Map<String, AdapterConfiguration> getAdapters() {
return adapters;
}

public void setAdapters(Map<String, AdapterConfiguration> adapters) {
this.adapters = adapters;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.camunda.zeebe.model.bpmn.instance.UserTask;
import io.camunda.zeebe.spring.client.event.ZeebeClientCreatedEvent;
import io.vanillabp.camunda8.Camunda8AdapterConfiguration;
import io.vanillabp.camunda8.Camunda8VanillaBpProperties;
import io.vanillabp.camunda8.service.Camunda8ProcessService;
import io.vanillabp.camunda8.utils.HashCodeInputStream;
import io.vanillabp.camunda8.wiring.Camunda8TaskWiring;
Expand Down Expand Up @@ -47,20 +48,21 @@ public class Camunda8DeploymentAdapter extends ModuleAwareBpmnDeployment {

private final DeploymentService deploymentService;

private final String applicationName;
private final Camunda8VanillaBpProperties camunda8Properties;

private ZeebeClient client;

public Camunda8DeploymentAdapter(
final String applicationName,
final VanillaBpProperties properties,
final Camunda8VanillaBpProperties camunda8Properties,
final DeploymentService deploymentService,
final Camunda8TaskWiring taskWiring) {

super(properties);
super(properties, applicationName);
this.camunda8Properties = camunda8Properties;
this.taskWiring = taskWiring;
this.deploymentService = deploymentService;
this.applicationName = applicationName;

}

Expand Down Expand Up @@ -160,7 +162,7 @@ protected void doDeployment(

if (hasDeployables[0]) {

final var tenantId = workflowModuleId == null ? applicationName : workflowModuleId;
final var tenantId = camunda8Properties.getTenantId(workflowModuleId);
final var deployedResources = deploymentCommand
.map(command -> tenantId == null ? command : command.tenantId(tenantId))
.map(command -> command
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.camunda.zeebe.client.ZeebeClient;
import io.vanillabp.camunda8.Camunda8AdapterConfiguration;
import io.vanillabp.camunda8.Camunda8VanillaBpProperties;
import io.vanillabp.springboot.adapter.AdapterAwareProcessService;
import io.vanillabp.springboot.adapter.ProcessServiceImplementation;
import org.slf4j.Logger;
Expand All @@ -26,20 +27,20 @@ public class Camunda8ProcessService<DE>

private final Function<DE, Object> getWorkflowAggregateId;

private final String applicationName;
private final Camunda8VanillaBpProperties camunda8Properties;

private AdapterAwareProcessService<DE> parent;

private ZeebeClient client;

public Camunda8ProcessService(
final String applicationName,
final Camunda8VanillaBpProperties camunda8Properties,
final CrudRepository<DE, Object> workflowAggregateRepository,
final Function<DE, Object> getWorkflowAggregateId,
final Class<DE> workflowAggregateClass) {

super();
this.applicationName = applicationName;
this.camunda8Properties = camunda8Properties;
this.workflowAggregateRepository = workflowAggregateRepository;
this.workflowAggregateClass = workflowAggregateClass;
this.getWorkflowAggregateId = getWorkflowAggregateId;
Expand Down Expand Up @@ -104,7 +105,7 @@ public DE startWorkflow(
final var attachedAggregate = workflowAggregateRepository
.save(workflowAggregate);

final var tenantId = parent.getWorkflowModuleId() == null ? applicationName : parent.getWorkflowModuleId();
final var tenantId = camunda8Properties.getTenantId(parent.getWorkflowModuleId());
final var command = client
.newCreateInstanceCommand()
.bpmnProcessId(parent.getPrimaryBpmnProcessId())
Expand Down Expand Up @@ -167,7 +168,7 @@ public DE correlateMessage(
final var attachedAggregate = workflowAggregateRepository
.save(workflowAggregate);

final var tenantId = parent.getWorkflowModuleId() == null ? applicationName : parent.getWorkflowModuleId();
final var tenantId = camunda8Properties.getTenantId(parent.getWorkflowModuleId());
final var command = client
.newPublishMessageCommand()
.messageName(messageName)
Expand Down

0 comments on commit b7fe56b

Please sign in to comment.