Skip to content

Commit

Permalink
chore(spring-boot-starter): Add Spring Boot External Client Config
Browse files Browse the repository at this point in the history
- Validate against misusing orderByCreateTime and useCreateTime configurations together
- Validate against wrong orderByCreateTime values
  • Loading branch information
psavidis committed Dec 4, 2023
1 parent 606dac4 commit dae9afb
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
long LONG_NULL_VALUE = Long.MIN_VALUE;
int INT_NULL_VALUE = Integer.MIN_VALUE;

String STRING_ORDER_BY_ASC_VALUE = "asc";
String STRING_ORDER_BY_DESC_VALUE = "desc";

/**
* Base url of the Camunda Runtime Platform REST API. This information is mandatory.
* Alias of {@link #baseUrl()}.
Expand Down Expand Up @@ -94,6 +97,22 @@
*/
boolean usePriority() default true;

/**
* Specifies whether tasks should be fetches based on their createTime or arbitrarily.
* This information is optional. Default is <code>false</code>.
*
* @return useCreateTime when fetching and locking tasks
*/
boolean useCreateTime() default false;

/**
* Specifies whether tasks should be fetched based on their createTime with a configured order ()
* This information is optional.
*
* @return useCreateTime when fetching and locking tasks
*/
String orderByCreateTime() default STRING_NULL_VALUE;

/**
* Asynchronous response (long polling) is enabled if a timeout is given.
* Specifies the maximum waiting time for the response of fetched and locked external tasks.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@
*/
package org.camunda.bpm.client.spring.impl.client;

import org.camunda.bpm.client.spring.annotation.EnableExternalTaskClient;

import static org.camunda.bpm.client.spring.annotation.EnableExternalTaskClient.INT_NULL_VALUE;
import static org.camunda.bpm.client.spring.annotation.ExternalTaskSubscription.LONG_NULL_VALUE;
import static org.camunda.bpm.client.spring.annotation.ExternalTaskSubscription.STRING_NULL_VALUE;

import org.camunda.bpm.client.spring.annotation.EnableExternalTaskClient;
import org.camunda.bpm.client.spring.annotation.ExternalTaskSubscription;

public class ClientConfiguration {

protected String baseUrl;
protected String workerId;
protected Integer maxTasks;
protected Boolean usePriority;
protected Boolean useCreateTime;
protected String orderByCreateTime;
protected String defaultSerializationFormat;
protected String dateFormat;
protected Long asyncResponseTimeout;
Expand Down Expand Up @@ -99,6 +101,22 @@ public void setUsePriority(Boolean usePriority) {
this.usePriority = usePriority;
}

public String getOrderByCreateTime() {
return orderByCreateTime;
}

public void setOrderByCreateTime(String orderByCreateTime) {
this.orderByCreateTime = orderByCreateTime;
}

public Boolean getUseCreateTime() {
return useCreateTime;
}

public void setUseCreateTime(Boolean useCreateTime) {
this.useCreateTime = useCreateTime;
}

public Boolean getDisableAutoFetching() {
return disableAutoFetching;
}
Expand Down Expand Up @@ -127,6 +145,9 @@ public void fromAnnotation(EnableExternalTaskClient annotation) {

setUsePriority(annotation.usePriority());

setUseCreateTime(annotation.useCreateTime());
configureOrderByCreateTime(annotation);

long asyncResponseTimeout = annotation.asyncResponseTimeout();
setAsyncResponseTimeout(isNull(asyncResponseTimeout) ? null : asyncResponseTimeout);

Expand All @@ -144,8 +165,16 @@ public void fromAnnotation(EnableExternalTaskClient annotation) {
setDefaultSerializationFormat(isNull(serializationFormat) ? null : serializationFormat);
}

protected void configureOrderByCreateTime(EnableExternalTaskClient annotation) {
if (EnableExternalTaskClient.STRING_NULL_VALUE.equals(annotation.orderByCreateTime())) {
setOrderByCreateTime(null);
} else {
setOrderByCreateTime(annotation.orderByCreateTime());
}
}

protected static boolean isNull(String value) {
return STRING_NULL_VALUE.equals(value);
return ExternalTaskSubscription.STRING_NULL_VALUE.equals(value);
}

protected static boolean isNull(long value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
*/
package org.camunda.bpm.client.spring.impl.client;

import static org.camunda.bpm.client.spring.annotation.EnableExternalTaskClient.STRING_ORDER_BY_ASC_VALUE;
import static org.camunda.bpm.client.spring.annotation.EnableExternalTaskClient.STRING_ORDER_BY_DESC_VALUE;

import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -89,6 +92,9 @@ public ExternalTaskClient getObject() {
if (backoffStrategy != null) {
clientBuilder.backoffStrategy(backoffStrategy);
}

tryConfigureCreateTimeOrder(clientBuilder);

client = clientBuilder.build();
}

Expand All @@ -101,6 +107,51 @@ protected void addClientRequestInterceptors(ExternalTaskClientBuilder taskClient
requestInterceptors.forEach(taskClientBuilder::addInterceptor);
}

protected void tryConfigureCreateTimeOrder(ExternalTaskClientBuilder builder) {
checkForCreateTimeMisconfiguration();

if (isUseCreateTimeEnabled()) {
builder.orderByCreateTime().desc();
return;
}

if (isOrderByCreateTimeEnabled()) {
handleOrderByCreateTimeConfig(builder);
}
}

protected void handleOrderByCreateTimeConfig(ExternalTaskClientBuilder builder) {
String orderByCreateTime = clientConfiguration.getOrderByCreateTime();

if (STRING_ORDER_BY_ASC_VALUE.equals(orderByCreateTime)) {
builder.orderByCreateTime().asc();
return;
}

if (STRING_ORDER_BY_DESC_VALUE.equals(orderByCreateTime)) {
builder.orderByCreateTime().desc();
return;
}

throw new IllegalArgumentException("Invalid value " + clientConfiguration.getOrderByCreateTime()
+ ". Please use either \"asc\" or \"desc\" value for configuring \"orderByCreateTime\" on the client");
}

protected boolean isOrderByCreateTimeEnabled() {
return clientConfiguration.getOrderByCreateTime() != null;
}

protected boolean isUseCreateTimeEnabled() {
return clientConfiguration.getUseCreateTime() != null && clientConfiguration.getUseCreateTime();
}

protected void checkForCreateTimeMisconfiguration() {
if (isUseCreateTimeEnabled() && isOrderByCreateTimeEnabled()) {
throw new IllegalStateException(
"Both \"useCreateTime\" and \"orderByCreateTime\" are enabled. Please use one or the other");
}
}

@Autowired(required = false)
public void setRequestInterceptors(List<ClientRequestInterceptor> requestInterceptors) {
if (requestInterceptors != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,23 @@
*/
package org.camunda.bpm.client.spring;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import java.util.HashMap;
import java.util.Map;
import org.camunda.bpm.client.spring.configuration.FullConfiguration;
import org.camunda.bpm.client.task.ExternalTaskHandler;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;

import java.util.HashMap;
import java.util.Map;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

@ContextConfiguration(classes = {FullConfiguration.class})
@DirtiesContext // context cannot be reused since the mocks need to be reinitialized completely
public class ConfigurationTest extends MockedTest {
Expand All @@ -40,6 +41,12 @@ public class ConfigurationTest extends MockedTest {
@Qualifier("handler")
protected ExternalTaskHandler handler;

@Before
public void init() {
when(clientBuilder.orderByCreateTime()).thenReturn(clientBuilder);
when(clientBuilder.asc()).thenReturn(clientBuilder);
}

@Test
public void shouldVerifyClientConfiguration() {
verify(clientBuilder).baseUrl("url");
Expand All @@ -52,7 +59,10 @@ public void shouldVerifyClientConfiguration() {
verify(clientBuilder).lockDuration(4444);
verify(clientBuilder).dateFormat("date-format");
verify(clientBuilder).defaultSerializationFormat("default-serialization-format");
verify(clientBuilder).orderByCreateTime();
verify(clientBuilder).asc();
verify(clientBuilder).build();

verifyNoMoreInteractions(clientBuilder);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public void shouldVerifyClientDefaults() {
verify(clientBuilder, never()).workerId(anyString());
verify(clientBuilder, never()).maxTasks(anyInt());
verify(clientBuilder, never()).usePriority(anyBoolean());
verify(clientBuilder, never()).useCreateTime(anyBoolean());
verify(clientBuilder, never()).orderByCreateTime();
verify(clientBuilder, never()).asyncResponseTimeout(anyLong());
verify(clientBuilder, never()).disableAutoFetching();
verify(clientBuilder, never()).disableBackoffStrategy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
*/
package org.camunda.bpm.client.spring;

import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.RETURNS_SELF;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;

import org.camunda.bpm.client.ExternalTaskClient;
import org.camunda.bpm.client.ExternalTaskClientBuilder;
import org.camunda.bpm.client.topic.TopicSubscription;
Expand All @@ -29,13 +36,6 @@
import org.mockito.junit.MockitoRule;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assume.assumeTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.RETURNS_SELF;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;

@RunWith(SpringRunner.class)
public abstract class MockedTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
maxTasks = 1111,
workerId = "worker-id",
usePriority = false,
useCreateTime = false,
orderByCreateTime = "asc",
asyncResponseTimeout = 5555,
disableAutoFetching = true,
disableBackoffStrategy = true,
Expand Down

0 comments on commit dae9afb

Please sign in to comment.