Skip to content

Commit

Permalink
Close #188: Add documentation on how to prevent missing version infor…
Browse files Browse the repository at this point in the history
…mation. Also remove term "BPM".
  • Loading branch information
tobiasschaefer authored and martisaw committed Feb 22, 2021
1 parent 5266f85 commit da8be6d
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 19 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,23 @@ See also a test in our example application: [HelloWorldProcessTest](/micronaut-c

## Pitfalls

### No version information in Fat/Uber/Shadow JAR

If you create a Fat/Uber/Shadow JAR and run that you will see a warning:

`WARN i.n.m.c.b.f.MnProcessEngineConfiguration - The Camunda version cannot be determined. If you created a Fat/Uber/Shadow JAR then please consider using the Micronaut Application Plugin's 'dockerBuild' task to create a Docker image.`

This is because the repackaging of the jars implicitly removes the META-INF information.

Instead, of creating a Fat/Uber/Shadow JAR, please use the [Micronaut Application Plugin](https://github.com/micronaut-projects/micronaut-gradle-plugin/blob/master/README.md#micronaut-application-plugin)'s `dockerBuild` task to create a layered Docker image:

`./gradlew dockerBuild`

and use the resulting image to run a Docker container.

Missing version information leads to
* Detailed telemetry cannot be sent to Camunda because the version is mandatory.

### Executing Blocking Operations on Netty's I/O Thread Pool
When using the default server implementation Netty, blocking operations must be performed on I/O instead of Netty threads to avoid possible deadlocks. Therefore, as soon as Camunda ["borrows a client thread"](https://docs.camunda.org/manual/current/user-guide/process-engine/transactions-in-processes/) you have to make sure that the [event loop is not blocked](https://objectcomputing.com/resources/publications/sett/june-2020-micronaut-2-dont-let-event-loops-own-you).
A frequently occurring example is the implementation of a REST endpoint which interacts with the process engine. By default, Micronaut would use a Netty thread for this blocking operation. To prevent the use of a Netty thread it is recommended to use the annotation [`@ExecuteOn(TaskExecutors.IO)`](https://docs.micronaut.io/latest/guide/index.html#reactiveServer). This will make sure that an I/O thread is used.
Expand Down
2 changes: 1 addition & 1 deletion micronaut-camunda-bpm-feature/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ publishing {
from components.java
pom {
name = 'micronaut-camunda-bpm-feature'
description = 'Integration between Micronaut and Camunda BPM Process Engine'
description = 'Integration between Micronaut and Camunda Process Engine'
url = 'https://github.com/NovatecConsulting/micronaut-camunda-bpm'
licenses {
license {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ protected void createUser() {

protected void createAdminGroup() {
Group camundaAdminGroup = identityService.newGroup(CAMUNDA_ADMIN);
camundaAdminGroup.setName("Camunda BPM Administrators");
camundaAdminGroup.setName("Camunda Administrators");
camundaAdminGroup.setType(GROUP_TYPE_SYSTEM);
identityService.saveGroup(camundaAdminGroup);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@

//Implementation based on https://github.com/camunda/camunda-bpm-platform/blob/master/spring-boot-starter/starter/src/main/java/org/camunda/bpm/spring/boot/starter/util/CamundaBpmVersion.java
@Singleton
public class CamundaBpmVersion {
public class CamundaVersion {

private final Optional<String> version;

public CamundaBpmVersion() {
public CamundaVersion() {
this(ProcessEngine.class.getPackage());
}

protected CamundaBpmVersion(Package pkg) {
protected CamundaVersion(Package pkg) {
version = Optional.ofNullable(pkg.getImplementationVersion())
.map(String::trim);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class MnProcessEngineConfiguration extends ProcessEngineConfigurationImpl

protected final Environment environment;

protected final CamundaBpmVersion camundaBpmVersion;
protected final CamundaVersion camundaVersion;

protected final BasicJdbcConfiguration basicJdbcConfiguration;

Expand All @@ -63,7 +63,7 @@ public MnProcessEngineConfiguration(SynchronousTransactionManager<Connection> tr
Configuration configuration,
MnTelemetryRegistry telemetryRegistry,
Environment environment,
CamundaBpmVersion camundaBpmVersion,
CamundaVersion camundaVersion,
ApplicationContext applicationContext,
BasicJdbcConfiguration basicJdbcConfiguration,
DataSource dataSource,
Expand All @@ -75,7 +75,7 @@ public MnProcessEngineConfiguration(SynchronousTransactionManager<Connection> tr
this.telemetryRegistry = telemetryRegistry;
this.beansResolverFactory = beansResolverFactory;
this.environment = environment;
this.camundaBpmVersion = camundaBpmVersion;
this.camundaVersion = camundaVersion;
this.basicJdbcConfiguration = basicJdbcConfiguration;
checkForDeprecatedConfiguration();
setDataSource(dataSource);
Expand Down Expand Up @@ -161,7 +161,7 @@ protected void configureTelemetry() {
if (environment.getActiveNames().contains(Environment.TEST)) {
setInitializeTelemetry(false);
setTelemetryReporterActivate(false);
} else if ( Boolean.TRUE.equals(isInitializeTelemetry()) && isTelemetryReporterActivate() && !camundaBpmVersion.getVersion().isPresent() ) {
} else if ( Boolean.TRUE.equals(isInitializeTelemetry()) && isTelemetryReporterActivate() && !camundaVersion.getVersion().isPresent() ) {
log.warn("Disabling TelemetryReporter because required information 'Camunda Version' is not available.");
setTelemetryReporterActivate(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,29 @@ public class ProcessEngineFactory {

private static final Logger log = LoggerFactory.getLogger(ProcessEngineFactory.class);

protected final ProcessEngineConfiguration processEngineConfiguration;
protected final CamundaVersion camundaVersion;

public ProcessEngineFactory(ProcessEngineConfiguration processEngineConfiguration, CamundaVersion camundaVersion) {
this.processEngineConfiguration = processEngineConfiguration;
this.camundaVersion = camundaVersion;
}

/**
* The {@link ProcessEngine} is started with the application start so that the task scheduler is started immediately.
*
* @param processEngineConfiguration the {@link ProcessEngineConfiguration} to build the {@link ProcessEngine}.
* @param camundaBpmVersion the @{@link CamundaBpmVersion} to log on application start.
* @return the initialized {@link ProcessEngine} in the application context.
* @throws IOException if a resource, i.e. a model, cannot be loaded.
*/
@Context
@Bean(preDestroy = "close")
public ProcessEngine processEngine(ProcessEngineConfiguration processEngineConfiguration, CamundaBpmVersion camundaBpmVersion) throws IOException {
public ProcessEngine processEngine() throws IOException {

log.info("Camunda BPM version: {}", camundaBpmVersion.getVersion().orElse(""));
if (camundaVersion.getVersion().isPresent()) {
log.info("Camunda version: {}", camundaVersion.getVersion().get());
} else {
log.warn("The Camunda version cannot be determined. If you created a Fat/Uber/Shadow JAR then please consider using the Micronaut Application Plugin's 'dockerBuild' task to create a Docker image.");
}

ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package info.novatec.micronaut.camunda.bpm.feature.test

import info.novatec.micronaut.camunda.bpm.feature.CamundaBpmVersion
import info.novatec.micronaut.camunda.bpm.feature.CamundaVersion
import io.micronaut.context.ApplicationContext
import org.camunda.bpm.engine.ProcessEngine
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl
Expand All @@ -9,7 +9,6 @@ import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource
import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import java.util.*
import java.util.Optional.empty
import java.util.Optional.of

Expand All @@ -33,14 +32,14 @@ class MnProcessEngineConfigurationTelemetryTest {
@ParameterizedTest
@ValueSource(strings = ["true", "false"])
fun `telemetry reporter can only be enabled if version info is available`(versionInfoAvailable: Boolean) {
val camundaBpmVersion = mock(CamundaBpmVersion::class.java)
val camundaBpmVersion = mock(CamundaVersion::class.java)
`when`(camundaBpmVersion.version).thenReturn(if (versionInfoAvailable) of("7.14.0") else empty())

ApplicationContext.builder()
.deduceEnvironment(false)
.properties(mapOf("camunda.generic-properties.properties.initialize-telemetry" to true))
.build()
.registerSingleton(CamundaBpmVersion::class.java, camundaBpmVersion)
.registerSingleton(CamundaVersion::class.java, camundaBpmVersion)
.start()
.use { applicationContext ->
val pec = applicationContext.getBean(ProcessEngine::class.java).processEngineConfiguration as ProcessEngineConfigurationImpl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import org.slf4j.LoggerFactory
class ProcessEngineFactoryLoggerTest {

@Test
fun `Camunda BPM version is logged on application start`() {
fun `Camunda version is logged on application start`() {

val logger = LoggerFactory.getLogger(ProcessEngineFactory::class.java) as Logger

Expand All @@ -29,6 +29,6 @@ class ProcessEngineFactoryLoggerTest {
ApplicationContext.run()

assertTrue(listAppender.list.stream()
.anyMatch { e -> e.formattedMessage.contains(Regex("""Camunda BPM version: \d+\.\d+\.\d+""")) })
.anyMatch { e -> e.formattedMessage.contains(Regex("""Camunda version: \d+\.\d+\.\d+""")) })
}
}

0 comments on commit da8be6d

Please sign in to comment.