Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(deps): migrate to the official Zeebe Spring SDK #3193

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

import io.camunda.connector.api.secret.SecretProvider;
import io.camunda.connector.runtime.cloud.GcpSecretManagerSecretProvider;
import io.camunda.zeebe.spring.client.properties.ZeebeClientConfigurationProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -39,21 +37,16 @@ public class SaaSConfiguration {
@Value("${camunda.saas.secrets.internalPrefix:internal-connector-secrets}")
private String secretsInternalNamePrefix;

private final ZeebeClientConfigurationProperties conf;

@Autowired
public SaaSConfiguration(ZeebeClientConfigurationProperties conf) {
this.conf = conf;
}
@Value("${zeebe.client.cloud.cluster-id}")
private String clusterId;

@Bean
public SecretProvider getSecretProvider() {
return new GcpSecretManagerSecretProvider(
conf.getCloud().getClusterId(), secretsProjectId, secretsNamePrefix);
return new GcpSecretManagerSecretProvider(clusterId, secretsProjectId, secretsNamePrefix);
}

public SecretProvider getInternalSecretProvider() {
return new GcpSecretManagerSecretProvider(
conf.getCloud().getClusterId(), secretsProjectId, secretsInternalNamePrefix);
clusterId, secretsProjectId, secretsInternalNamePrefix);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,18 @@
*/
package io.camunda.connector.runtime.saas;

import io.camunda.common.auth.JwtConfig;
import io.camunda.common.auth.JwtCredential;
import io.camunda.common.auth.Product;
import io.camunda.common.auth.SaaSAuthenticationBuilder;
import io.camunda.common.json.JsonMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.camunda.connector.api.secret.SecretProvider;
import io.camunda.operate.CamundaOperateClient;
import io.camunda.zeebe.spring.client.properties.OperateClientConfigurationProperties;
import io.camunda.operate.CamundaOperateClientConfiguration;
import io.camunda.operate.auth.JwtAuthentication;
import io.camunda.operate.auth.JwtCredential;
import io.camunda.operate.auth.TokenResponseMapper.JacksonTokenResponseMapper;
import io.camunda.operate.spring.OperateClientConfiguration;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
Expand All @@ -37,40 +41,50 @@
public static String SECRET_NAME_SECRET = "M2MSecret";

private final SecretProvider internalSecretProvider;
private final OperateClientConfigurationProperties operateProperties;

@Value("${camunda.operate.client.url}")
private String operateUrl;

public SaaSOperateClientFactory(
@Autowired SaaSConfiguration saaSConfiguration,
@Autowired OperateClientConfigurationProperties operateProperties) {
@Value("${camunda.operate.client.baseUrl}")
private String operateBaseUrl;

@Value("${camunda.operate.client.authUrl}")
private String operateAuthUrl;

public SaaSOperateClientFactory(@Autowired SaaSConfiguration saaSConfiguration) {
this.internalSecretProvider = saaSConfiguration.getInternalSecretProvider();
this.operateProperties = operateProperties;
}

@Bean
@Primary
public CamundaOperateClient camundaOperateClientBundle(JsonMapper jsonMapper) {

var jwtConfig = new JwtConfig();
jwtConfig.addProduct(Product.OPERATE, configureJwtCredential());
public CamundaOperateClient camundaOperateClientBundle(
ObjectMapper objectMapper, OperateClientConfiguration configuration) {
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed

var jwtCredential = configureJwtCredential();
Fixed Show fixed Hide fixed
var authentication =
new SaaSAuthenticationBuilder().withJwtConfig(jwtConfig).withJsonMapper(jsonMapper).build();

return CamundaOperateClient.builder()
.operateUrl(operateUrl)
.authentication(authentication)
.setup()
.build();
new JwtAuthentication(jwtCredential, new JacksonTokenResponseMapper(objectMapper));
URL convertedOperateUrl;
try {
convertedOperateUrl = new URI(operateUrl).toURL();
} catch (Exception e) {
throw new RuntimeException(e);
}
var adjustedConfiguration =
new CamundaOperateClientConfiguration(
authentication, convertedOperateUrl, objectMapper, configuration.operateHttpClient());
return new CamundaOperateClient(adjustedConfiguration);
}

JwtCredential configureJwtCredential() {
return new JwtCredential(
internalSecretProvider.getSecret(SECRET_NAME_CLIENT_ID),
internalSecretProvider.getSecret(SECRET_NAME_SECRET),
operateProperties.getBaseUrl(),
operateProperties.getAuthUrl());
try {
var authUrl = new URI(operateAuthUrl).toURL();
return new JwtCredential(
internalSecretProvider.getSecret(SECRET_NAME_CLIENT_ID),
internalSecretProvider.getSecret(SECRET_NAME_SECRET),
operateBaseUrl,
authUrl);
} catch (MalformedURLException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,18 @@ camunda.connector.secret-provider.console.enabled=false

zeebe.client.worker.threads=10
zeebe.client.worker.max-jobs-active=32
camunda.client.zeebe.defaults.stream-enabled=true

# Enforce local connection, even if cluster-id set
zeebe.client.connection-mode=ADDRESS
camunda.client.mode=simple
camunda.client.zeebe.defaults.stream-enabled=true
camunda.client.zeebe.grpc-address=http://${zeebe.client.broker.gateway-address}
camunda.client.zeebe.base-url=http://${zeebe.client.broker.gateway-address}
camunda.client.mode=saas
camunda.client.region=${zeebe.client.cloud.region}
camunda.client.cluster-id=${zeebe.client.cloud.cluster-id}
operate.client.profile=saas
operate.client.region=${zeebe.client.cloud.region}
operate.client.cluster-id=${zeebe.client.cloud.cluster-id}

connectors.log.appender=stackdriver

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package io.camunda.connector.runtime.saas;

import io.camunda.connector.api.secret.SecretProvider;
import io.camunda.zeebe.spring.client.properties.ZeebeClientConfigurationProperties;
import java.util.Map;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
Expand All @@ -39,8 +38,8 @@ public class MockSaaSConfiguration {
SaaSOperateClientFactory.SECRET_NAME_SECRET, OPERATE_CLIENT_SECRET);

@Bean
public SaaSConfiguration saaSConfiguration(ZeebeClientConfigurationProperties conf) {
return new SaaSConfiguration(conf) {
public SaaSConfiguration saaSConfiguration() {
return new SaaSConfiguration() {
@Override
public SecretProvider getInternalSecretProvider() {
return secrets::get;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
"camunda.saas.secrets.projectId=42",
"zeebe.client.cloud.cluster-id=42",
"zeebe.client.security.plaintext=true",
"zeebe.client.broker.gateway-address=zeebe-service:26500",
"zeebe.client.cloud.region=bru-1",
"camunda.connector.auth.audience=connectors.dev.ultrawombat.com",
"camunda.connector.auth.issuer=https://weblogin.cloud.dev.ultrawombat.com/",
"camunda.operate.client.url=" + MockSaaSConfiguration.OPERATE_CLIENT_URL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
classes = {SaaSConnectorRuntimeApplication.class, MockSaaSConfiguration.class},
properties = {
"camunda.saas.secrets.projectId=42",
"zeebe.client.cloud.cluster-id=42",
"zeebe.client.cloud.clusterId=42",
"zeebe.client.cloud.region=bru-1",
"zeebe.client.broker.gateway-address=zeebe-service:26500",
"zeebe.client.security.plaintext=true",
"camunda.connector.auth.audience=connectors.dev.ultrawombat.com",
"camunda.connector.auth.issuer=https://weblogin.cloud.dev.ultrawombat.com/",
Expand All @@ -52,11 +54,10 @@ public void contextLoaded() {
public void jwtCredentialConfigured() {
var jwtCredential = operateClientFactory.configureJwtCredential();
assertThat(jwtCredential).isNotNull();
assertThat(jwtCredential.getClientId())
.isEqualTo(MockSaaSConfiguration.OPERATE_CLIENT_CLIENT_ID);
assertThat(jwtCredential.getClientSecret())
.isEqualTo(MockSaaSConfiguration.OPERATE_CLIENT_SECRET);
assertThat(jwtCredential.getAudience()).isEqualTo(MockSaaSConfiguration.OPERATE_CLIENT_BASEURL);
assertThat(jwtCredential.getAuthUrl()).isEqualTo(MockSaaSConfiguration.OPERATE_CLIENT_AUTH_URL);
assertThat(jwtCredential.clientId()).isEqualTo(MockSaaSConfiguration.OPERATE_CLIENT_CLIENT_ID);
assertThat(jwtCredential.clientSecret()).isEqualTo(MockSaaSConfiguration.OPERATE_CLIENT_SECRET);
assertThat(jwtCredential.audience()).isEqualTo(MockSaaSConfiguration.OPERATE_CLIENT_BASEURL);
assertThat(jwtCredential.authUrl().toString())
.isEqualTo(MockSaaSConfiguration.OPERATE_CLIENT_AUTH_URL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
logging.level.io.camunda.connector=DEBUG

# Config for use with docker-compose-core.yml
camunda.client.mode=simple
camunda.client.mode=self-managed
camunda.client.auth.username=demo
camunda.client.auth.password=demo
camunda.client.auth.issuer="" # if present, will trigger OIDC mode
operate.client.profile=simple
14 changes: 10 additions & 4 deletions bundle/default-bundle/src/test/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,28 @@ management.endpoint.health.group.readiness.include[]=zeebeClient,operate
management.endpoint.health.show-components=always
management.endpoint.health.show-details=always

camunda.client.operate.base-url=http://localhost:8081
operate.client.base-url=http://localhost:8081
camunda.client.zeebe.gateway-url=http://localhost:26500
camunda.client.zeebe.defaults.max-jobs-active=32
camunda.client.zeebe.defaults.worker-threads=10
camunda.client.zeebe.defaults.stream-enabled=true

camunda.client.mode=self-managed

# Config for use with docker-compose.yml
camunda.client.mode=oidc
camunda.client.auth.client-id=connectors
camunda.client.auth.client-secret=XALaRPl5qwTEItdwCMiPS62nVpKs7dL7
camunda.client.auth.oidc-type=keycloak
camunda.client.auth.issuer=http://localhost:18080/auth/realms/camunda-platform
camunda.client.auth.issuer=http://localhost:18080/auth/realms/camunda-platform/protocol/openid-connect/token
camunda.client.identity.audience=connectors
camunda.client.identity.base-url=http://localhost:8084

operate.client.profile=oidc
operate.client.auth-url=http://localhost:18080/auth/realms/camunda-platform/protocol/openid-connect/token
operate.client.client-id=connectors
operate.client.client-secret=XALaRPl5qwTEItdwCMiPS62nVpKs7dL7

# Config for use with docker-compose-core.yml
#camunda.client.mode=simple
#camunda.client.auth.username=demo
#camunda.client.auth.password=demo
#operate.client.profile=simple
5 changes: 5 additions & 0 deletions connector-runtime/connector-runtime-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
<artifactId>slf4j-api</artifactId>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;

public class InboundConnectorDetailsUtil {

static InboundConnectorDetails create(
String deduplicationId, List<InboundConnectorElement> groupedElements) {
if (CollectionUtils.isEmpty(groupedElements)) {
if (groupedElements == null || groupedElements.isEmpty()) {
throw new IllegalArgumentException("At least one element must be provided");
}
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;

class InboundConnectorContextImplTest {
Expand Down Expand Up @@ -108,7 +107,6 @@ void bindProperties_shouldParseStringAsString() {
.isInstanceOf(String.class);
}

@NotNull
private static ValidInboundConnectorDetails getInboundConnectorDefinition(
Map<String, String> properties) {
properties = new HashMap<>(properties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,14 @@ public ZeebeFuture<ProcessInstanceEvent> send() {
future.complete(new ProcessInstanceEventDummy());
return future;
}

@Override
public CreateProcessInstanceCommandStep1 useRest() {
return this;
}

@Override
public CreateProcessInstanceCommandStep1 useGrpc() {
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,14 @@ public ZeebeFuture<PublishMessageResponse> send() {
future.complete(new PublishMessageResponseDummy());
return future;
}

@Override
public PublishMessageCommandStep1 useRest() {
return this;
}

@Override
public PublishMessageCommandStep1 useGrpc() {
return this;
}
}
4 changes: 2 additions & 2 deletions connector-runtime/connector-runtime-spring/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@

<!-- Camunda dependencies -->
<dependency>
<groupId>io.camunda.spring</groupId>
<artifactId>spring-client-zeebe</artifactId>
<groupId>io.camunda</groupId>
<artifactId>spring-boot-starter-camunda-sdk</artifactId>
</dependency>
<dependency>
<groupId>io.camunda.spring</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public class SpringConnectorJobHandler extends ConnectorJobHandler {

private static final Logger LOGGER = LoggerFactory.getLogger(SpringConnectorJobHandler.class);

private static final int MAX_ZEEBE_COMMAND_RETRIES = 3;

private final CommandExceptionHandlingStrategy commandExceptionHandlingStrategy;
private final MetricsRecorder metricsRecorder;
private final OutboundConnectorConfiguration connectorConfiguration;
Expand Down Expand Up @@ -78,7 +80,7 @@ public void handle(JobClient client, ActivatedJob job) {
Outbound.METRIC_NAME_INVOCATIONS,
Outbound.ACTION_FAILED,
connectorConfiguration.type());
LOGGER.warn("Failed to handle job: " + job);
LOGGER.warn("Failed to handle job: {}", job);
}
});
}
Expand All @@ -91,7 +93,13 @@ protected void failJob(JobClient client, ActivatedJob job, ConnectorResult.Error
Outbound.METRIC_NAME_INVOCATIONS, Outbound.ACTION_FAILED, connectorConfiguration.type());
} finally {
FinalCommandStep commandStep = prepareFailJobCommand(client, job, result);
new CommandWrapper(commandStep, job, commandExceptionHandlingStrategy).executeAsync();
new CommandWrapper(
commandStep,
job,
commandExceptionHandlingStrategy,
metricsRecorder,
MAX_ZEEBE_COMMAND_RETRIES)
.executeAsync();
}
}

Expand All @@ -106,7 +114,9 @@ protected void throwBpmnError(JobClient client, ActivatedJob job, BpmnError valu
new CommandWrapper(
prepareThrowBpmnErrorCommand(client, job, value),
job,
commandExceptionHandlingStrategy)
commandExceptionHandlingStrategy,
metricsRecorder,
MAX_ZEEBE_COMMAND_RETRIES)
.executeAsync();
}
}
Expand All @@ -122,7 +132,13 @@ protected void completeJob(
connectorConfiguration.type());
} finally {
FinalCommandStep commandStep = prepareCompleteJobCommand(client, job, result);
new CommandWrapper(commandStep, job, commandExceptionHandlingStrategy).executeAsync();
new CommandWrapper(
commandStep,
job,
commandExceptionHandlingStrategy,
metricsRecorder,
MAX_ZEEBE_COMMAND_RETRIES)
.executeAsync();
}
}
}
Loading
Loading