From 9ea9dcaa552245139cf120bf8ed0dc921e4da9db Mon Sep 17 00:00:00 2001 From: 1nb0und <133918079+1nb0und@users.noreply.github.com> Date: Wed, 20 Dec 2023 23:45:28 -0500 Subject: [PATCH] feat: streamlining loading of operate client (cherry picked from commit 56b5a4734e2edd921e7dc088fb8a725e140090d3) --- .../io/camunda/common/auth/JwtConfig.java | 4 + .../client/CamundaAutoConfiguration.java | 3 +- .../CommonClientConfiguration.java | 92 +++++--------- ...n.java => OperateClientConfiguration.java} | 23 ++-- .../condition/OperateClientCondition.java | 17 ++- .../OperateClientConfigurationProperties.java | 120 ++++++++++++++---- 6 files changed, 159 insertions(+), 100 deletions(-) rename spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/{CamundaOperateClientConfiguration.java => OperateClientConfiguration.java} (63%) diff --git a/camunda-sdk-java/java-common/src/main/java/io/camunda/common/auth/JwtConfig.java b/camunda-sdk-java/java-common/src/main/java/io/camunda/common/auth/JwtConfig.java index 02ea9ed9e..9f399d44a 100644 --- a/camunda-sdk-java/java-common/src/main/java/io/camunda/common/auth/JwtConfig.java +++ b/camunda-sdk-java/java-common/src/main/java/io/camunda/common/auth/JwtConfig.java @@ -18,6 +18,10 @@ public void addProduct(Product product, JwtCredential jwtCredential) { map.put(product, jwtCredential); } + public JwtCredential getProduct(Product product) { + return map.get(product); + } + public Map getMap() { return map; } diff --git a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/CamundaAutoConfiguration.java b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/CamundaAutoConfiguration.java index 7d35bb180..2845b2d39 100644 --- a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/CamundaAutoConfiguration.java +++ b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/CamundaAutoConfiguration.java @@ -31,8 +31,7 @@ ZeebeClientProdAutoConfiguration.class, ZeebeClientAllAutoConfiguration.class, CommonClientConfiguration.class, - CamundaOperateClientConfiguration.class, // deprecated - OperateClientProdAutoConfiguration.class, + OperateClientConfiguration.class, ZeebeActuatorConfiguration.class, MetricsDefaultConfiguration.class }) diff --git a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/CommonClientConfiguration.java b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/CommonClientConfiguration.java index d22cdf120..be4e67708 100644 --- a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/CommonClientConfiguration.java +++ b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/CommonClientConfiguration.java @@ -6,7 +6,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; -@EnableConfigurationProperties(CommonConfigurationProperties.class) +@EnableConfigurationProperties({CommonConfigurationProperties.class, ZeebeSelfManagedProperties.class}) public class CommonClientConfiguration { @@ -16,9 +16,6 @@ public class CommonClientConfiguration { @Autowired(required = false) ZeebeClientConfigurationProperties zeebeClientConfigurationProperties; - @Autowired(required = false) - OperateClientConfigurationProperties operateClientConfigurationProperties; - @Autowired(required = false) ConsoleClientConfigurationProperties consoleClientConfigurationProperties; @@ -28,9 +25,11 @@ public class CommonClientConfiguration { @Autowired(required = false) TasklistClientConfigurationProperties tasklistClientConfigurationProperties; - // TODO: Remove below properties when we deprecate camunda.[product].client.* @Autowired(required = false) - CamundaOperateClientConfigurationProperties camundaOperateClientConfigurationProperties; + OperateClientConfigurationProperties operateClientConfigurationProperties; + + @Autowired(required = false) + ZeebeSelfManagedProperties zeebeSelfManagedProperties; @Bean public Authentication authentication() { @@ -42,23 +41,22 @@ public Authentication authentication() { return SaaSAuthentication.builder() .jwtConfig(configureJwtConfig()) .build(); - } else if (zeebeClientConfigurationProperties.getBroker().getGatewayAddress() != null) { + } else if (zeebeClientConfigurationProperties.getBroker().getGatewayAddress() != null || zeebeSelfManagedProperties.getGatewayAddress() != null) { // figure out if Self-Managed JWT or Self-Managed Basic - // TODO: Remove when we deprecate camunda.[product].client.* - if (camundaOperateClientConfigurationProperties != null) { - if (camundaOperateClientConfigurationProperties.getKeycloakUrl() != null) { + if (operateClientConfigurationProperties != null) { + if (operateClientConfigurationProperties.getKeycloakUrl() != null) { return SelfManagedAuthentication.builder() .jwtConfig(configureJwtConfig()) - .keycloakUrl(camundaOperateClientConfigurationProperties.getKeycloakUrl()) - .keycloakRealm(camundaOperateClientConfigurationProperties.getKeycloakRealm()) + .keycloakUrl(operateClientConfigurationProperties.getKeycloakUrl()) + .keycloakRealm(operateClientConfigurationProperties.getKeycloakRealm()) .build(); - } else if (camundaOperateClientConfigurationProperties.getUsername() != null && camundaOperateClientConfigurationProperties.getPassword() != null) { + } else if (operateClientConfigurationProperties.getUsername() != null && operateClientConfigurationProperties.getPassword() != null) { SimpleConfig simpleConfig = new SimpleConfig(); - SimpleCredential simpleCredential = new SimpleCredential(camundaOperateClientConfigurationProperties.getUsername(), camundaOperateClientConfigurationProperties.getPassword()); + SimpleCredential simpleCredential = new SimpleCredential(operateClientConfigurationProperties.getUsername(), operateClientConfigurationProperties.getPassword()); simpleConfig.addProduct(Product.OPERATE, simpleCredential); return SimpleAuthentication.builder() .simpleConfig(simpleConfig) - .simpleUrl(camundaOperateClientConfigurationProperties.getUrl()) + .simpleUrl(operateClientConfigurationProperties.getUrl()) .build(); } } @@ -108,51 +106,27 @@ private JwtConfig configureJwtConfig() { String operateAuthUrl = zeebeClientConfigurationProperties.getCloud().getAuthUrl(); String operateAudience = "operate.camunda.io"; if (operateClientConfigurationProperties != null) { - if (operateClientConfigurationProperties.getEnabled()) { - if (operateClientConfigurationProperties.getAuthUrl() != null) { - operateAuthUrl = operateClientConfigurationProperties.getAuthUrl(); - } - if (operateClientConfigurationProperties.getBaseUrl() != null) { - operateAudience = operateClientConfigurationProperties.getBaseUrl(); - } - if (operateClientConfigurationProperties.getClientId() != null && operateClientConfigurationProperties.getClientSecret() != null) { - jwtConfig.addProduct(Product.OPERATE, new JwtCredential( - operateClientConfigurationProperties.getClientId(), - operateClientConfigurationProperties.getClientSecret(), - operateAuthUrl, - operateAudience) - ); - } else if (commonConfigurationProperties.getClientId() != null && commonConfigurationProperties.getClientSecret() != null) { - jwtConfig.addProduct(Product.OPERATE, new JwtCredential( - commonConfigurationProperties.getClientId(), - commonConfigurationProperties.getClientSecret(), - operateAuthUrl, - operateAudience) - ); - } else { - // TODO: Remove this in the future, new property scheme shouldn't depend on Zeebe - jwtConfig.addProduct(Product.OPERATE, new JwtCredential( - zeebeClientConfigurationProperties.getCloud().getClientId(), - zeebeClientConfigurationProperties.getCloud().getClientSecret(), - operateAudience, operateAuthUrl) - ); - } + if (operateClientConfigurationProperties.getAuthUrl() != null) { + operateAuthUrl = operateClientConfigurationProperties.getAuthUrl(); } - } - if (camundaOperateClientConfigurationProperties != null) { - // TODO: Remove this else if block when we deprecate camunda.[product].client.* - if (camundaOperateClientConfigurationProperties.getEnabled()) { - if (camundaOperateClientConfigurationProperties.getAuthUrl() != null) { - operateAuthUrl = camundaOperateClientConfigurationProperties.getAuthUrl(); - } - if (camundaOperateClientConfigurationProperties.getBaseUrl() != null) { - operateAudience = camundaOperateClientConfigurationProperties.getBaseUrl(); - } - if (camundaOperateClientConfigurationProperties.getClientId() != null && camundaOperateClientConfigurationProperties.getClientSecret() != null) { - jwtConfig.addProduct(Product.OPERATE, new JwtCredential(camundaOperateClientConfigurationProperties.getClientId(), camundaOperateClientConfigurationProperties.getClientSecret(), operateAudience, operateAuthUrl)); - } else { - jwtConfig.addProduct(Product.OPERATE, new JwtCredential(zeebeClientConfigurationProperties.getCloud().getClientId(), zeebeClientConfigurationProperties.getCloud().getClientSecret(), operateAudience, operateAuthUrl)); - } + if (operateClientConfigurationProperties.getBaseUrl() != null) { + operateAudience = operateClientConfigurationProperties.getBaseUrl(); + } + if (operateClientConfigurationProperties.getClientId() != null && operateClientConfigurationProperties.getClientSecret() != null) { + jwtConfig.addProduct(Product.OPERATE, new JwtCredential(operateClientConfigurationProperties.getClientId(), operateClientConfigurationProperties.getClientSecret(), operateAudience, operateAuthUrl)); + } else if (commonConfigurationProperties.getClientId() != null && commonConfigurationProperties.getClientSecret() != null) { + jwtConfig.addProduct(Product.OPERATE, new JwtCredential( + commonConfigurationProperties.getClientId(), + commonConfigurationProperties.getClientSecret(), + operateAuthUrl, + operateAudience) + ); + } else if (zeebeClientConfigurationProperties.getCloud().getClientId() != null && zeebeClientConfigurationProperties.getCloud().getClientSecret() != null) { + jwtConfig.addProduct(Product.OPERATE, new JwtCredential(zeebeClientConfigurationProperties.getCloud().getClientId(), zeebeClientConfigurationProperties.getCloud().getClientSecret(), operateAudience, operateAuthUrl)); + } else if (zeebeSelfManagedProperties.getClientId() != null && zeebeSelfManagedProperties.getClientSecret() != null) { + jwtConfig.addProduct(Product.OPERATE, new JwtCredential(zeebeSelfManagedProperties.getClientId(), zeebeSelfManagedProperties.getClientSecret(), operateAudience, operateAuthUrl)); + } else { + throw new RuntimeException("Unable to determine OPERATE credentials"); } } return jwtConfig; diff --git a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/CamundaOperateClientConfiguration.java b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/OperateClientConfiguration.java similarity index 63% rename from spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/CamundaOperateClientConfiguration.java rename to spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/OperateClientConfiguration.java index cfd62e697..7ed3d15c5 100644 --- a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/CamundaOperateClientConfiguration.java +++ b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/OperateClientConfiguration.java @@ -3,11 +3,12 @@ import io.camunda.common.auth.Authentication; import io.camunda.operate.CamundaOperateClient; import io.camunda.operate.CamundaOperateClientBuilder; -import io.camunda.zeebe.spring.client.configuration.condition.CamundaOperateClientCondition; -import io.camunda.zeebe.spring.client.properties.CamundaOperateClientConfigurationProperties; +import io.camunda.zeebe.spring.client.configuration.condition.OperateClientCondition; +import io.camunda.zeebe.spring.client.properties.OperateClientConfigurationProperties; +import io.camunda.zeebe.spring.client.testsupport.SpringZeebeTestContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -15,22 +16,18 @@ import java.lang.invoke.MethodHandles; -/** - * This will be deprecated once we move to the new schema (i.e. not prefixing with camunda.*) - */ -@Deprecated -@Conditional(CamundaOperateClientCondition.class) +@Conditional(OperateClientCondition.class) @ConditionalOnProperty(prefix = "camunda.operate.client", name = "enabled", havingValue = "true", matchIfMissing = true) -@EnableConfigurationProperties(CamundaOperateClientConfigurationProperties.class) -public class CamundaOperateClientConfiguration { +@ConditionalOnMissingBean(SpringZeebeTestContext.class) +@EnableConfigurationProperties(OperateClientConfigurationProperties.class) +public class OperateClientConfiguration { private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - @Autowired - Authentication authentication; @Bean - public CamundaOperateClient camundaOperateClient(CamundaOperateClientConfigurationProperties props) { + @ConditionalOnMissingBean + public CamundaOperateClient camundaOperateClient(OperateClientConfigurationProperties props, Authentication authentication) { LOG.warn("Using a deprecated operate properties"); CamundaOperateClient client; try { diff --git a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/condition/OperateClientCondition.java b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/condition/OperateClientCondition.java index 9bf093ec4..4e1d452f5 100644 --- a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/condition/OperateClientCondition.java +++ b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/configuration/condition/OperateClientCondition.java @@ -8,15 +8,24 @@ public OperateClientCondition() { super(ConfigurationPhase.PARSE_CONFIGURATION); } - @ConditionalOnProperty(name = "operate.client.client-id") + @ConditionalOnProperty(name = "camunda.operate.client.client-id") static class ClientIdCondition { } - @ConditionalOnProperty(name = "operate.client.username") + @ConditionalOnProperty(name = "camunda.operate.client.username") static class UsernameCondition { } - @ConditionalOnProperty(name = "operate.client.auth-url") + @ConditionalOnProperty(name = "camunda.operate.client.auth-url") static class AuthUrlCondition { } - @ConditionalOnProperty(name = "operate.client.base-url") + @ConditionalOnProperty(name = "camunda.operate.client.base-url") static class BaseUrlCondition { } + + @ConditionalOnProperty(name = "camunda.operate.client.keycloak-url") + static class KeycloakUrlCondition { } + + @ConditionalOnProperty(name = "camunda.operate.client.url") + static class UrlCondition { } + + @ConditionalOnProperty(name = "camunda.operate.client.enabled") + static class EnableCondition { } } diff --git a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/properties/OperateClientConfigurationProperties.java b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/properties/OperateClientConfigurationProperties.java index ff516b546..10b8651b9 100644 --- a/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/properties/OperateClientConfigurationProperties.java +++ b/spring-boot-starter-camunda/src/main/java/io/camunda/zeebe/spring/client/properties/OperateClientConfigurationProperties.java @@ -1,7 +1,5 @@ package io.camunda.zeebe.spring.client.properties; -import io.camunda.zeebe.spring.client.properties.common.Client; -import jakarta.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -9,26 +7,115 @@ import java.lang.invoke.MethodHandles; -@ConfigurationProperties(prefix = "operate.client") -public class OperateClientConfigurationProperties extends Client { +@ConfigurationProperties(prefix = "camunda.operate.client") +public class OperateClientConfigurationProperties { private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - // Normal Zeebe Engine Properties @Value("${zeebe.client.cloud.cluster-id:#{null}}") private String clusterId; @Value("${zeebe.client.cloud.region:bru-2}") private String region; - // TODO: This currently assumes PROD in Cloud - do we want to support DEV and INT? - // and make it configurable? At the moment the workaround is to set the operateUrl yourself - public static String operateCloudBaseUrl = "operate.camunda.io"; + private String clientId; + private String clientSecret; + private String username; + private String password; + private Boolean enabled = false; + private String url; + + private String keycloakUrl; + private String keycloakRealm = "camunda-platform"; + + private String baseUrl; + + private String authUrl; + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getClientSecret() { + return clientSecret; + } + + public void setClientSecret(String clientSecret) { + this.clientSecret = clientSecret; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getKeycloakUrl() { + return keycloakUrl; + } + + public void setKeycloakUrl(String keycloakUrl) { + this.keycloakUrl = keycloakUrl; + } + + public String getKeycloakRealm() { + return keycloakRealm; + } + + public void setKeycloakRealm(String keycloakRealm) { + this.keycloakRealm = keycloakRealm; + } + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + public String getAuthUrl() { + return authUrl; + } + + public void setAuthUrl(String authUrl) { + this.authUrl = authUrl; + } public String getOperateUrl() { - if (getUrl() != null) { - LOG.debug("Connecting to Camunda Operate on URL: " + getUrl()); - return getUrl(); + if (url != null) { + LOG.debug("Connecting to Camunda Operate on URL: " +url); + return url; } else if (clusterId != null) { String url = "https://" + region + "." + getFinalBaseUrl() + "/" + clusterId + "/"; LOG.debug("Connecting to Camunda Operate SaaS via URL: " + url); @@ -45,15 +132,4 @@ private String getFinalBaseUrl() { return "operate.camunda.io"; } } - - @PostConstruct - private void applyFinalValues() { - if (this.getClientId() != null && this.getClientSecret() != null) { - this.setEnabled(true); - } else if (this.getUsername() != null && this.getPassword() != null) { - this.setEnabled(true); - } else if (this.getAuthUrl() != null || this.getBaseUrl() != null) { - this.setEnabled(true); - } - } }