generated from camunda-community-hub/maven-template
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #91 from camunda-community-hub/np-agent
Add a standalone, containerized agent
- Loading branch information
Showing
7 changed files
with
354 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
<?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> | ||
|
||
<artifactId>agent</artifactId> | ||
<packaging>jar</packaging> | ||
|
||
<name>EZE - Embedded Zeebe Engine Agent</name> | ||
|
||
<parent> | ||
<groupId>org.camunda.community</groupId> | ||
<artifactId>eze-root</artifactId> | ||
<relativePath>../pom.xml</relativePath> | ||
<version>0.7.1-SNAPSHOT</version> | ||
</parent> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.camunda.community</groupId> | ||
<artifactId>eze</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
|
||
<!-- required as otherwise the engine cannot be instantiated due to a missing class --> | ||
<dependency> | ||
<groupId>io.camunda</groupId> | ||
<artifactId>zeebe-exporter-api</artifactId> | ||
</dependency> | ||
|
||
<!-- cli --> | ||
<dependency> | ||
<groupId>info.picocli</groupId> | ||
<artifactId>picocli</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.agrona</groupId> | ||
<artifactId>agrona</artifactId> | ||
</dependency> | ||
|
||
<!-- logging; adopt the implementation included in eze --> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
</dependency> | ||
|
||
<!-- Test dependencies --> | ||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-api</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.assertj</groupId> | ||
<artifactId>assertj-core</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.camunda</groupId> | ||
<artifactId>zeebe-client-java</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<properties> | ||
<agent.finalName>eze</agent.finalName> | ||
<agent.mainClass>org.camunda.community.eze.agent.Agent</agent.mainClass> | ||
</properties> | ||
|
||
<build> | ||
<finalName>${agent.finalName}</finalName> | ||
<plugins> | ||
<!-- process picocli annotations --> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<annotationProcessorPaths> | ||
<path> | ||
<groupId>info.picocli</groupId> | ||
<artifactId>picocli-codegen</artifactId> | ||
<version>${picocli.version}</version> | ||
</path> | ||
</annotationProcessorPaths> | ||
<compilerArgs> | ||
<arg>-Aproject=${project.groupId}/${project.artifactId}</arg> | ||
</compilerArgs> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<profiles> | ||
<!-- generates a Docker image as part of the build process; this configuration expects | ||
authentication to have been set up beforehand --> | ||
<profile> | ||
<id>docker</id> | ||
|
||
<properties> | ||
<dockerImageTag>${project.version}</dockerImageTag> | ||
|
||
<!-- set to build to build AND push; leave to dockerBuild to only build locally --> | ||
<dockerGoal>dockerBuild</dockerGoal> | ||
</properties> | ||
|
||
<build> | ||
<plugins> | ||
<!-- Build a docker image --> | ||
<plugin> | ||
<groupId>com.google.cloud.tools</groupId> | ||
<artifactId>jib-maven-plugin</artifactId> | ||
|
||
<configuration> | ||
<from> | ||
<!-- smallest Java 17 base image; Temurin does not produce Java 17 JRE only builds --> | ||
<image> | ||
azul/zulu-openjdk-alpine:17-jre-headless@sha256:ca58039e2aa75651ab6e6558816202e85187675d8ee64f6dc7fc8d44cb6ffef3 | ||
</image> | ||
</from> | ||
<to> | ||
<image>ghcr.io/camunda-community-hub/${project.build.finalName}</image> | ||
<tags>${dockerImageTag}</tags> | ||
</to> | ||
<container> | ||
<mainClass>${agent.mainClass}</mainClass> | ||
<ports> | ||
<port>26500</port> | ||
</ports> | ||
</container> | ||
</configuration> | ||
|
||
<executions> | ||
<execution> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>${dockerGoal}</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</profile> | ||
</profiles> | ||
|
||
</project> |
73 changes: 73 additions & 0 deletions
73
agent/src/main/java/org/camunda/community/eze/agent/Agent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
/* | ||
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under | ||
* one or more contributor license agreements. See the NOTICE file distributed | ||
* with this work for additional information regarding copyright ownership. | ||
* Licensed under the Zeebe Community License 1.1. You may not use this file | ||
* except in compliance with the Zeebe Community License 1.1. | ||
*/ | ||
package org.camunda.community.eze.agent; | ||
|
||
import java.util.Collections; | ||
import java.util.concurrent.Callable; | ||
import org.agrona.concurrent.ShutdownSignalBarrier; | ||
import org.camunda.community.eze.EngineFactory; | ||
import org.camunda.community.eze.ZeebeEngine; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import picocli.CommandLine; | ||
import picocli.CommandLine.Command; | ||
|
||
/** | ||
* A thin wrapper around a {@link ZeebeEngine} instance. For potential exit codes, see {@link | ||
* ExitCode}. | ||
*/ | ||
@Command(name = "agent", mixinStandardHelpOptions = true, description = "Standalone EZE agent") | ||
public final class Agent implements Callable<Integer> { | ||
|
||
private final Logger logger; | ||
|
||
public Agent() { | ||
logger = LoggerFactory.getLogger(getClass()); | ||
} | ||
|
||
@Override | ||
public Integer call() { | ||
final var shutdownBarrier = new ShutdownSignalBarrier(); | ||
final ZeebeEngine engine; | ||
|
||
logger.info("Starting EZE agent..."); | ||
try { | ||
engine = EngineFactory.INSTANCE.create(Collections.emptyList()); | ||
} catch (final Exception e) { | ||
logger.error("Failed to create an instance of the embedded engine", e); | ||
return ExitCode.CREATE_ERROR.getCode(); | ||
} | ||
|
||
try { | ||
engine.start(); | ||
} catch (final Exception e) { | ||
logger.error("Failed to start EZE agent", e); | ||
return ExitCode.START_ERROR.getCode(); | ||
} | ||
|
||
logger.info("EZE agent started at {}", engine.getGatewayAddress()); | ||
ExitCode exitCode = ExitCode.OK; | ||
shutdownBarrier.await(); | ||
|
||
logger.info("Shutting down EZE agent..."); | ||
try { | ||
engine.stop(); | ||
} catch (final Exception e) { | ||
logger.warn("Failed to gracefully shutdown the embedded engine", e); | ||
exitCode = ExitCode.SHUTDOWN_ERROR; | ||
} | ||
|
||
logger.info("Shutdown EZE agent with status: {}", exitCode); | ||
return exitCode.getCode(); | ||
} | ||
|
||
public static void main(final String[] args) { | ||
final int exitCode = new CommandLine(new Agent()).execute(args); | ||
System.exit(exitCode); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
agent/src/main/java/org/camunda/community/eze/agent/ExitCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH under | ||
* one or more contributor license agreements. See the NOTICE file distributed | ||
* with this work for additional information regarding copyright ownership. | ||
* Licensed under the Zeebe Community License 1.1. You may not use this file | ||
* except in compliance with the Zeebe Community License 1.1. | ||
*/ | ||
package org.camunda.community.eze.agent; | ||
|
||
/** | ||
* A list of possible exit status codes returned by the Agent. These can be consumed by scripts or | ||
* container orchestrators to react appropriately based on the error. | ||
*/ | ||
enum ExitCode { | ||
/** Indicates the application started and shutdown gracefully without errors */ | ||
OK(0), | ||
/** Indicates the agent failed to create an instance of EZE */ | ||
CREATE_ERROR(128), | ||
/** Indicates the agent failed to start the EZE instance */ | ||
START_ERROR(129), | ||
/** Indicates the agent started the engine, but failed to gracefully shut it down */ | ||
SHUTDOWN_ERROR(131); | ||
|
||
private final int code; | ||
|
||
ExitCode(final int code) { | ||
this.code = code; | ||
} | ||
|
||
int getCode() { | ||
return code; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Configuration status="WARN"> | ||
|
||
<Appenders> | ||
<Console name="Console" target="SYSTEM_OUT"> | ||
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> | ||
</Console> | ||
</Appenders> | ||
|
||
<Loggers> | ||
<Root level="info"> | ||
<AppenderRef ref="Console"/> | ||
</Root> | ||
</Loggers> | ||
|
||
</Configuration> |
49 changes: 49 additions & 0 deletions
49
agent/src/test/java/org/camunda/community/eze/agent/AgentTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package org.camunda.community.eze.agent; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import io.camunda.zeebe.client.ZeebeClient; | ||
import io.camunda.zeebe.client.api.response.Topology; | ||
import java.time.Duration; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
import org.camunda.community.eze.ZeebeEngineImpl; | ||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.Test; | ||
import sun.misc.Signal; | ||
|
||
final class AgentTest { | ||
private ExecutorService agentThreadContext; | ||
|
||
@AfterEach | ||
void afterEach() { | ||
if (agentThreadContext != null) { | ||
agentThreadContext.shutdownNow(); | ||
} | ||
} | ||
|
||
@Test | ||
void shouldStartEngine() { | ||
// given | ||
final var agent = new Agent(); | ||
agentThreadContext = Executors.newSingleThreadExecutor(); | ||
|
||
// when | ||
final var exitCodeFuture = agentThreadContext.submit(agent); | ||
final Topology topology; | ||
try (final var client = | ||
ZeebeClient.newClientBuilder() | ||
.usePlaintext() | ||
.gatewayAddress("localhost:" + ZeebeEngineImpl.PORT) | ||
.build()) { | ||
topology = client.newTopologyRequest().send().join(); | ||
} | ||
Signal.raise(new Signal("INT")); | ||
|
||
// then | ||
assertThat(topology.getClusterSize()).isEqualTo(1); | ||
assertThat(exitCodeFuture) | ||
.succeedsWithin(Duration.ofSeconds(10)) | ||
.isEqualTo(ExitCode.OK.getCode()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters