Skip to content

Commit

Permalink
Merge pull request #287 from conductor-oss/fix/java-client-v4-spring-…
Browse files Browse the repository at this point in the history
…modules-autoconfig

[Java client v4] Improve Spring modules with auto-configuration
  • Loading branch information
jmigueprieto authored Oct 30, 2024
2 parents 3f4d917 + ff25fcc commit 61960bc
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,40 @@
@ConfigurationProperties("conductor.client")
public class ClientProperties {

public static class Timeout {
private int connect = -1;
private int read = -1;
private int write = -1;

public int getConnect() {
return connect;
}

public void setConnect(int connect) {
this.connect = connect;
}

public int getRead() {
return read;
}

public void setRead(int read) {
this.read = read;
}

public int getWrite() {
return write;
}

public void setWrite(int write) {
this.write = write;
}
}

private String rootUri;

private String basePath;

private String workerNamePrefix = "workflow-worker-%d";

private int threadCount = 1;
Expand All @@ -39,6 +71,26 @@ public class ClientProperties {

private int taskPollTimeout = 100;

private Timeout timeout = new Timeout();

private boolean verifyingSsl = true;

public void setVerifyingSsl(boolean verifyingSsl) {
this.verifyingSsl = verifyingSsl;
}

public boolean isVerifyingSsl() {
return verifyingSsl;
}

public Timeout getTimeout() {
return timeout;
}

public void setTimeout(Timeout timeout) {
this.timeout = timeout;
}

public String getRootUri() {
return rootUri;
}
Expand Down Expand Up @@ -110,4 +162,12 @@ public int getTaskPollTimeout() {
public void setTaskPollTimeout(int taskPollTimeout) {
this.taskPollTimeout = taskPollTimeout;
}

public String getBasePath() {
return basePath;
}

public void setBasePath(String basePath) {
this.basePath = basePath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;

import com.netflix.conductor.client.automator.TaskRunnerConfigurer;
Expand All @@ -32,34 +36,46 @@

import lombok.extern.slf4j.Slf4j;

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ClientProperties.class)
@AutoConfiguration
@Slf4j
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
@EnableConfigurationProperties(ClientProperties.class)
public class ConductorClientAutoConfiguration {

@ConditionalOnMissingBean
@Bean
public ConductorClient conductorClient(ClientProperties clientProperties) {
// TODO allow configuration of other properties via application.properties
return ConductorClient.builder()
.basePath(clientProperties.getRootUri())
.build();
@ConditionalOnMissingBean
public ConductorClient conductorClient(ClientProperties properties) {
var basePath = StringUtils.isBlank(properties.getRootUri()) ? properties.getBasePath() : properties.getRootUri();
if (basePath == null) {
return null;
}

var builder = ConductorClient.builder()
.basePath(basePath)
.connectTimeout(properties.getTimeout().getConnect())
.readTimeout(properties.getTimeout().getRead())
.writeTimeout(properties.getTimeout().getWrite())
.verifyingSsl(properties.isVerifyingSsl());
return builder.build();
}

@ConditionalOnMissingBean
@Bean
@ConditionalOnBean(ConductorClient.class)
@ConditionalOnMissingBean
public TaskClient taskClient(ConductorClient client) {
return new TaskClient(client);
}

@ConditionalOnMissingBean
@Bean
@ConditionalOnBean(ConductorClient.class)
@ConditionalOnMissingBean
public AnnotatedWorkerExecutor annotatedWorkerExecutor(TaskClient taskClient) {
return new AnnotatedWorkerExecutor(taskClient);
}

@ConditionalOnMissingBean
@Bean(initMethod = "init", destroyMethod = "shutdown")
@ConditionalOnBean(ConductorClient.class)
@ConditionalOnMissingBean
public TaskRunnerConfigurer taskRunnerConfigurer(Environment env,
TaskClient taskClient,
ClientProperties clientProperties,
Expand Down Expand Up @@ -90,12 +106,15 @@ public TaskRunnerConfigurer taskRunnerConfigurer(Environment env,
}

@Bean
@ConditionalOnBean(ConductorClient.class)
@ConditionalOnMissingBean
public WorkflowExecutor workflowExecutor(ConductorClient client, AnnotatedWorkerExecutor annotatedWorkerExecutor) {
return new WorkflowExecutor(client, annotatedWorkerExecutor);
}

@ConditionalOnMissingBean
@Bean
@ConditionalOnBean(ConductorClient.class)
@ConditionalOnMissingBean
public WorkflowClient workflowClient(ConductorClient client) {
return new WorkflowClient(client);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,32 @@

import java.util.Map;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import com.netflix.conductor.client.http.TaskClient;
import com.netflix.conductor.sdk.workflow.executor.task.AnnotatedWorkerExecutor;
import com.netflix.conductor.sdk.workflow.executor.task.WorkerConfiguration;

@Component
public class ConductorWorkerAutoConfiguration implements ApplicationListener<ContextRefreshedEvent> {
@AutoConfiguration
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
@ConditionalOnBean(TaskClient.class)
public class ConductorWorkerAutoConfiguration {

private final TaskClient taskClient;

public ConductorWorkerAutoConfiguration(TaskClient taskClient) {
this.taskClient = taskClient;
}

@Override
@EventListener(ContextRefreshedEvent.class)
public void onApplicationEvent(ContextRefreshedEvent refreshedEvent) {
ApplicationContext applicationContext = refreshedEvent.getApplicationContext();
Environment environment = applicationContext.getEnvironment();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
com.netflix.conductor.client.spring.ConductorClientAutoConfiguration
com.netflix.conductor.client.spring.ConductorWorkerAutoConfiguration
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public WorkflowDef getWorkflowDef(String name, Integer version) {
public List<WorkflowDef> getAllWorkflowsWithLatestVersions() {
ConductorClientRequest request = ConductorClientRequest.builder()
.method(Method.GET)
.path("metadata/workflow/latest-versions")
.path("/metadata/workflow/latest-versions")
.build();

ConductorClientResponse<List<WorkflowDef>> resp = client.execute(request, new TypeReference<>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class MetadataClientSpec extends ClientSpecification {
then:
1 * apiClient.execute(builder()
.method(ConductorClientRequest.Method.GET)
.path('metadata/workflow/latest-versions')
.path('/metadata/workflow/latest-versions')
.build(), _) >> new ConductorClientResponse(200, [:], result)
ret == result
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=4.0.0
version=4.0.1
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import com.netflix.conductor.client.exception.ConductorClientException;
Expand Down Expand Up @@ -150,8 +151,8 @@ public static ApiClientBuilder builder() {
public static class ApiClientBuilder extends Builder<ApiClientBuilder> {

public ApiClientBuilder credentials(String key, String secret) {
if (key == null || secret == null) {
throw new IllegalArgumentException("Key and secret must not be null");
if (StringUtils.isBlank(key) || StringUtils.isBlank(secret)) {
throw new IllegalArgumentException("Key and secret must not be blank (null or empty)");
}

this.addHeaderSupplier(new OrkesAuthentication(key, secret));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2024 Conductor Authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package io.orkes.conductor.client.spring;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import lombok.Getter;


@Component
@Getter
public class OrkesClientProperties {
private final String keyId;
private final String secret;
// for backwards compatibility
private final String conductorServerUrl;
private final String securityKeyId;
private final String securitySecret;

public OrkesClientProperties(@Value("${conductor.client.keyId:${conductor.client.key-id:#{null}}}") String keyId,
@Value("${conductor.client.secret:#{null}}") String secret,
// for backwards compatibility
@Value("${conductor.server.url:#{null}}") String conductorServerUrl,
@Value("${conductor.security.client.keyId:${conductor.security.client.key-id:#{null}}}") String securityKeyId,
@Value("${conductor.security.client.secret:#{null}}") String securitySecret) {
this.keyId = keyId;
this.secret = secret;
this.conductorServerUrl = conductorServerUrl;
this.securityKeyId = securityKeyId;
this.securitySecret = securitySecret;
}
}
Loading

0 comments on commit 61960bc

Please sign in to comment.