Modules in this directory contain the standard implementation of a Connector runtime for Camunda Connectors.
Camunda Connector runtime is shipped as 3 artifacts:
connector-runtime-core
: The core runtime classes and utilities, independent of any framework. This module only provides a basic library that can be used to build a custom Connector runtime.connector-runtime-spring
: The Spring-based runtime implementation. Built on top ofconnector-runtime-core
, this module provides a Spring configuration for an embedded Connector Runtime.spring-boot-starter-camunda-connectors
: A Spring Boot starter for the Connector Runtime. This module provides a Spring Boot autoconfiguration for an embedded Connector Runtime. It is built on top ofconnector-runtime-spring
. The Spring Boot starter is the recommended way of using the Connector Runtime in a Spring Boot application.
To add the embeddable Connector runtime to your Spring Boot project, add the following dependency to your Spring project:
<dependency>
<groupId>io.camunda.connector</groupId>
<artifactId>spring-boot-starter-camunda-connectors</artifactId>
<version>${version.connectors}</version>
</dependency>
Refer to the Releases page for the latest version.
Refer to the Connector Runtime Application Docker example for further details.
To use the Camunda-provided Connectors with the runtime out of the box, refer to the Connectors Bundle.
Often, you want to build one application/deployment, that not only contains the pure runtime, but also some connectors themselves.
There are two ways of achieving this:
- Create a Maven build that depends on this runtime, but also add connectors as dependencies.
- Add connectors to the classpath of the runtime.
The first approach (Maven) has the clear advantage, that Maven resolves possible dependency conflicts, for example because two connectors use different versions of Jackson.
For example:
<dependencies>
<dependency>
<groupId>io.camunda</groupId>
<artifactId>spring-boot-starter-camunda-connectors</artifactId>
<version>${version.spring-zeebe}</version>
</dependency>
<dependency>
<groupId>io.camunda.connector</groupId>
<artifactId>connector-http-json</artifactId>
<version>${version.connector-http-json}</version>
</dependency>
<dependency>
<groupId>io.camunda.connector</groupId>
<artifactId>connector-sqs</artifactId>
<version>${version.connector-sqs}</version>
</dependency>
</dependencies>
We generally recommend preferring this approach.
The second approach (Classpath) has the advantage, that you can build a runtime by pure command line or Docker instructions, without any Java knowledge.
To minimize the risk of connectors bringing different versions of the same library, we recommend to use Maven Shade Relocate to relocate common libraries. A example can be found in the SQS connector:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<relocations>
<relocation>
<pattern>com.fasterxml.jackson</pattern>
<shadedPattern>connectorsqs.com.fasterxml.jackson</shadedPattern>
</relocation>
</relocations>
</configuration>
</plugin>
</plugins>
</build>
Now SQS bundles its own copy of Jackson.
See also Docker: Custom set of connectors.
The following configuration properties can be set via src/main/application.properties
if you run Java directly.
You can also set those configuration options via environment variables (then named ZEEBE_CLIENT_CLOUD_CLUSTERID
instead of zeebe.client.cloud.cluster-id
), especially useful if you run via DOCKER.
In general, the Connector Runtime will respect all properties known to Spring Zeebe, which allows to specify some more options.
To use Camunda SaaS specify the connection properties:
zeebe.client.cloud.cluster-id=xxx
zeebe.client.cloud.client-id=xxx
zeebe.client.cloud.client-secret=xxx
zeebe.client.cloud.region=bru-2
You can further configure separate connection properties for Camunda Operate (othewise it will use the properties configured for Zeebe above). For this you need to create client credentials in Console to access Operate:
camunda.operate.client.client-id=xxx
camunda.operate.client.client-secret=xxx
Zeebe:
zeebe.client.broker.gateway-address=127.0.0.1:26500
zeebe.client.security.plaintext=true
Connect to Operate locally using username and password:
camunda.operate.client.url=http://localhost:8081
camunda.operate.client.username=demo
camunda.operate.client.password=demo
When running against a self-managed environment you might also need to configure the keycloak endpoint to not use Operate username/password authentication. For this you either need to use the existing connectors client-id and client-secret (see in Identity) or create a new client in Identity that has permission to access the operate-api (read:*). When you have the client-id and client-secret you can configure the following Identity properties:
camunda.identity.type=keycloak
camunda.identity.base-url=http://localhost:8084
camunda.identity.issuer=http://localhost:18080/auth/realms/camunda-platform
camunda.identity.client-id=connectors
camunda.identity.client-secret=xxx
camunda.identity.issuer-backend-url=http://localhost:18080/auth/realms/camunda-platform
camunda.identity.audience=connectors
The runtime picks up outbound connectors available on the classpath automatically unless overriden through manual configuration.
The automatic discovery is based on the Java ServiceLoader mechanism.
It looks for all classes implementing the io.camunda.connector.api.outbound.OutboundConnectorFunction
or io.camunda.connector.api.inbound.InboundConnectorExecutable
interfaces. For automatic discovery to work,
you need to create a file META-INF/services/io.camunda.connector.api.outbound.OutboundConnectorFunction
or META-INF/services/io.camunda.connector.api.inbound.InboundConnectorExecutable
in your connector jar file.
This file must contain the fully qualified class name of your connector class.
It uses the default configuration specified through the @OutboundConnector
annotation in these cases.
java -cp 'connector-runtime-VERSION-with-dependencies.jar:connector-http-json-VERSION-with-dependencies.jar' \
io.camunda.connector.bundle.ConnectorRuntimeApplication
Note that you need to use ;
instead of :
on Windows machines:
java -cp 'connector-runtime-VERSION-with-dependencies.jar;connector-http-json-VERSION-with-dependencies.jar' \
io.camunda.connector.bundle.ConnectorRuntimeApplication
Use environment variables to configure connectors and their configuration explicitly, without auto-discovery:
Environment variable | Purpose |
---|---|
CONNECTOR_{NAME}_FUNCTION (required) |
Function to be registered as job worker with the given NAME |
CONNECTOR_{NAME}_TYPE (optional) |
Job type to register for worker with NAME |
CONNECTOR_{NAME}_INPUT_VARIABLES (optional) |
Variables to fetch for worker with NAME |
Through that configuration you define all job workers to run.
Specifying optional values allow you to override @OutboundConnector
provided connector configuration.
CONNECTOR_HTTPJSON_FUNCTION=io.camunda.connector.http.rest.HttpJsonFunction
CONNECTOR_HTTPJSON_TYPE=non-default-httpjson-task-type
java -cp 'connector-runtime-VERSION-with-dependencies.jar:connector-http-json-VERSION-with-dependencies.jar' \
io.camunda.connector.bundle.ConnectorRuntimeApplication
You can define a custom secret provider by implementing the SecretProvider
interface.
This secret provider is used by the Runtime to resolve secrets. You can also define multiple secret providers.
You can make your custom secret provider discoverable in 2 ways:
- Using the Java
SeviceLoader
pattern- Add a file
META-INF/services/io.camunda.connector.api.secret.SecretProvider
to the classpath - The file should contain the fully qualified name of your secret provider class
- This method is implemented in the Connector SDK and is also supported in custom Connector Runtimes out of the box
- Add a file
- By defining your
SecretProvider
as a Spring bean- All Spring beans implementing the
SecretProvider
interface are automatically discovered by the Runtime - Note that if you define a custom secret provider as a Spring bean, other providers defined using the
ServiceLoader
pattern will not be discovered
- All Spring beans implementing the
When using spring-boot-starter-camunda-connectors
, the secret providers are discovered in the following order:
- Secret providers defined as Spring beans have the highest priority. If they are discovered, the
ServiceLoader
pattern is not used. - Secret providers defined using the
ServiceLoader
pattern have the second priority. - If no secret provider is discovered, the default secret provider is used. It uses the environment variables to resolve secrets.
Therefore, a combination of 2 ways of defining secret providers is not possible. If you want to define multiple secret providers, make sure that all of them are defined using the same method (e.g. all of them are Spring beans).
If multiple secret providers are discovered, all of them can be used to resolve secrets. The default strategy is to use the first secret provider that returns a non-null value for a given secret name. The order of lookup is non-deterministic.
You can change this behavior by implementing the SecretProviderAggregator
interface. Define your custom aggregator as a Spring bean, and it will be used instead of the default one.
To inject secrets during connector function execution, export them as environment variables
export MY_SECRET='foo'
Reference the secret in the request payload prefixed with secrets.MY_SECRET
.
Refer to the Connector Runtime Docker image documentation for further details.
Use under terms of the Apache License, Version 2.0