Skip to content

Support feature flags in java client #619

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

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion src/main/idls
Submodule idls updated from 7d2d22 to d9811d
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
public class ServiceMethod {
public static final String DEPRECATE_DOMAIN =
MetricsType.CADENCE_METRICS_PREFIX + "DeprecateDomain";
public static final String GET_TASK_LISTS_BY_DOMAIN =
MetricsType.CADENCE_METRICS_PREFIX + "GetTaskListsByDomain";
public static final String DESCRIBE_DOMAIN =
MetricsType.CADENCE_METRICS_PREFIX + "DescribeDomain";
public static final String LIST_DOMAINS = MetricsType.CADENCE_METRICS_PREFIX + "ListDomains";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import com.google.common.base.Defaults;
import com.uber.cadence.*;
import com.uber.cadence.GetTaskListsByDomainRequest;
import com.uber.cadence.GetTaskListsByDomainResponse;
import com.uber.cadence.activity.ActivityOptions;
import com.uber.cadence.activity.LocalActivityOptions;
import com.uber.cadence.internal.metrics.NoopScope;
Expand Down Expand Up @@ -585,6 +587,13 @@ public void DeprecateDomain(
impl.DeprecateDomain(deprecateRequest, resultHandler);
}

@Override
public void GetTaskListsByDomain(
GetTaskListsByDomainRequest request, AsyncMethodCallback resultHandler)
throws org.apache.thrift.TException {
impl.GetTaskListsByDomain(request, resultHandler);
}

@Override
public void StartWorkflowExecution(
StartWorkflowExecutionRequest startRequest, AsyncMethodCallback resultHandler)
Expand Down Expand Up @@ -861,10 +870,18 @@ public UpdateDomainResponse UpdateDomain(UpdateDomainRequest updateRequest)

@Override
public void DeprecateDomain(DeprecateDomainRequest deprecateRequest)
throws BadRequestError, InternalServiceError, EntityNotExistsError, TException {
throws BadRequestError, EntityNotExistsError, LimitExceededError, ServiceBusyError,
ClientVersionNotSupportedError, TException {
impl.DeprecateDomain(deprecateRequest);
}

@Override
public GetTaskListsByDomainResponse GetTaskListsByDomain(GetTaskListsByDomainRequest request)
throws BadRequestError, EntityNotExistsError, LimitExceededError, ServiceBusyError,
ClientVersionNotSupportedError, TException {
return impl.GetTaskListsByDomain(request);
}

@Override
public StartWorkflowExecutionResponse StartWorkflowExecution(
StartWorkflowExecutionRequest startRequest)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package com.uber.cadence.internal.sync;

import com.uber.cadence.BadRequestError;
import com.uber.cadence.ClientVersionNotSupportedError;
import com.uber.cadence.ClusterInfo;
import com.uber.cadence.CountWorkflowExecutionsRequest;
import com.uber.cadence.CountWorkflowExecutionsResponse;
Expand All @@ -31,9 +32,12 @@
import com.uber.cadence.DomainAlreadyExistsError;
import com.uber.cadence.EntityNotExistsError;
import com.uber.cadence.GetSearchAttributesResponse;
import com.uber.cadence.GetTaskListsByDomainRequest;
import com.uber.cadence.GetTaskListsByDomainResponse;
import com.uber.cadence.GetWorkflowExecutionHistoryRequest;
import com.uber.cadence.GetWorkflowExecutionHistoryResponse;
import com.uber.cadence.InternalServiceError;
import com.uber.cadence.LimitExceededError;
import com.uber.cadence.ListArchivedWorkflowExecutionsRequest;
import com.uber.cadence.ListArchivedWorkflowExecutionsResponse;
import com.uber.cadence.ListClosedWorkflowExecutionsRequest;
Expand Down Expand Up @@ -453,6 +457,13 @@ public void DeprecateDomain(
impl.DeprecateDomain(deprecateRequest, resultHandler);
}

@Override
public void GetTaskListsByDomain(
GetTaskListsByDomainRequest request, AsyncMethodCallback resultHandler)
throws org.apache.thrift.TException {
impl.GetTaskListsByDomain(request, resultHandler);
}

@Override
public void StartWorkflowExecution(
StartWorkflowExecutionRequest startRequest, AsyncMethodCallback resultHandler)
Expand Down Expand Up @@ -738,6 +749,13 @@ public void DeprecateDomain(DeprecateDomainRequest deprecateRequest)
impl.DeprecateDomain(deprecateRequest);
}

@Override
public GetTaskListsByDomainResponse GetTaskListsByDomain(GetTaskListsByDomainRequest request)
throws BadRequestError, EntityNotExistsError, LimitExceededError, ServiceBusyError,
ClientVersionNotSupportedError, TException {
return impl.GetTaskListsByDomain(request);
}

@Override
public StartWorkflowExecutionResponse StartWorkflowExecution(
StartWorkflowExecutionRequest startRequest)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import com.uber.cadence.DomainNotActiveError;
import com.uber.cadence.EntityNotExistsError;
import com.uber.cadence.GetSearchAttributesResponse;
import com.uber.cadence.GetTaskListsByDomainRequest;
import com.uber.cadence.GetTaskListsByDomainResponse;
import com.uber.cadence.GetWorkflowExecutionHistoryRequest;
import com.uber.cadence.GetWorkflowExecutionHistoryResponse;
import com.uber.cadence.InternalServiceError;
Expand Down Expand Up @@ -210,6 +212,13 @@ public void DeprecateDomain(DeprecateDomainRequest deprecateRequest)
throw new UnsupportedOperationException("not implemented");
}

@Override
public GetTaskListsByDomainResponse GetTaskListsByDomain(GetTaskListsByDomainRequest request)
throws BadRequestError, EntityNotExistsError, LimitExceededError, ServiceBusyError,
ClientVersionNotSupportedError, TException {
throw new UnsupportedOperationException("not implemented");
}

@Override
public StartWorkflowExecutionResponse StartWorkflowExecution(
StartWorkflowExecutionRequest startRequest) throws TException {
Expand Down Expand Up @@ -795,6 +804,13 @@ public void DeprecateDomain(
throw new UnsupportedOperationException("not implemented");
}

@Override
public void GetTaskListsByDomain(
GetTaskListsByDomainRequest request, AsyncMethodCallback resultHandler)
throws org.apache.thrift.TException {
throw new UnsupportedOperationException("not implemented");
}

@Override
public void StartWorkflowExecution(
StartWorkflowExecutionRequest startRequest, AsyncMethodCallback resultHandler)
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/uber/cadence/serviceclient/ClientOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.uber.cadence.FeatureFlags;
import com.uber.cadence.internal.metrics.NoopScope;
import com.uber.m3.tally.Scope;
import java.util.Map;
Expand Down Expand Up @@ -76,6 +77,9 @@ public class ClientOptions {

private static final ClientOptions DEFAULT_INSTANCE;

/** Optional Feature flags to turn on/off some Cadence features */
private final FeatureFlags featureFlags;

static {
DEFAULT_INSTANCE = new Builder().build();
}
Expand Down Expand Up @@ -123,6 +127,8 @@ private ClientOptions(Builder builder) {
this.transportHeaders = ImmutableMap.of();
}

this.featureFlags = builder.featureFlags;

if (builder.headers != null) {
this.headers = ImmutableMap.copyOf(builder.headers);
} else {
Expand Down Expand Up @@ -179,6 +185,10 @@ public Map<String, String> getHeaders() {
return headers;
}

public FeatureFlags getFeatureFlags() {
return this.featureFlags;
}

/**
* Builder is the builder for ClientOptions.
*
Expand All @@ -197,6 +207,7 @@ public static class Builder {
private Scope metricsScope;
private Map<String, String> transportHeaders;
private Map<String, String> headers;
private FeatureFlags featureFlags;

private Builder() {}

Expand Down Expand Up @@ -252,6 +263,22 @@ public Builder setListArchivedWorkflowRpcTimeout(long timeoutMillis) {
return this;
}

/**
* Sets the feature flags to turn on/off some Cadence features By default, all features under
* FeatureFlags are turned off.
*
* @param featureFlags FeatureFlags
*/
public Builder setFeatureFlags(FeatureFlags featureFlags) {
this.featureFlags = featureFlags;
return this;
}

/** Returns the feature flags defined in ClientOptions */
public FeatureFlags getFeatureFlags() {
return this.featureFlags;
}

/**
* Sets the client application name.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package com.uber.cadence.serviceclient;

import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.uber.cadence.BadRequestError;
import com.uber.cadence.ClientVersionNotSupportedError;
import com.uber.cadence.ClusterInfo;
Expand All @@ -34,6 +36,8 @@
import com.uber.cadence.DomainNotActiveError;
import com.uber.cadence.EntityNotExistsError;
import com.uber.cadence.GetSearchAttributesResponse;
import com.uber.cadence.GetTaskListsByDomainRequest;
import com.uber.cadence.GetTaskListsByDomainResponse;
import com.uber.cadence.GetWorkflowExecutionHistoryRequest;
import com.uber.cadence.GetWorkflowExecutionHistoryResponse;
import com.uber.cadence.History;
Expand Down Expand Up @@ -203,6 +207,13 @@ private static Map<String, String> getThriftHeaders(ClientOptions options) {
}
}

if (options.getFeatureFlags() != null) {
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
String serialized = gson.toJson(options.getFeatureFlags());
builder.put("cadence-client-feature-flags", serialized);
}

return builder.build();
}

Expand Down Expand Up @@ -550,6 +561,51 @@ private void deprecateDomain(DeprecateDomainRequest deprecateRequest) throws TEx
}
}

@Override
public GetTaskListsByDomainResponse GetTaskListsByDomain(
GetTaskListsByDomainRequest getTaskListsByDomainRequest) throws TException {
return measureRemoteCall(
ServiceMethod.GET_TASK_LISTS_BY_DOMAIN,
() -> getTaskListsByDomain(getTaskListsByDomainRequest));
}

private GetTaskListsByDomainResponse getTaskListsByDomain(
GetTaskListsByDomainRequest getTaskListsByDomainRequest) throws TException {
ThriftResponse<WorkflowService.GetTaskListsByDomain_result> response = null;
try {
ThriftRequest<WorkflowService.GetTaskListsByDomain_args> request =
buildThriftRequest(
"GetTaskListsByDomain",
new WorkflowService.GetTaskListsByDomain_args(getTaskListsByDomainRequest));
response = doRemoteCall(request);
WorkflowService.GetTaskListsByDomain_result result =
response.getBody(WorkflowService.GetTaskListsByDomain_result.class);
if (response.getResponseCode() == ResponseCode.OK) {
return result.getSuccess();
}
if (result.isSetBadRequestError()) {
throw result.getBadRequestError();
}
if (result.isSetEntityNotExistError()) {
throw result.getEntityNotExistError();
}
if (result.isSetLimitExceededError()) {
throw result.getLimitExceededError();
}
if (result.isSetServiceBusyError()) {
throw result.getServiceBusyError();
}
if (result.isSetClientVersionNotSupportedError()) {
throw result.getClientVersionNotSupportedError();
}
throw new TException("GetTaskListsByDomain failed with unknown error:" + result);
} finally {
if (response != null) {
response.release();
}
}
}

@Override
public StartWorkflowExecutionResponse StartWorkflowExecution(
StartWorkflowExecutionRequest request) throws TException {
Expand Down Expand Up @@ -2593,4 +2649,11 @@ public void DeprecateDomain(
throws TException {
throw new UnsupportedOperationException("not implemented");
}

@Override
public void GetTaskListsByDomain(
GetTaskListsByDomainRequest request, AsyncMethodCallback resultHandler)
throws org.apache.thrift.TException {
throw new UnsupportedOperationException("not implemented");
}
}
14 changes: 7 additions & 7 deletions src/test/java/com/uber/cadence/workflow/WorkflowTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.uber.cadence.DomainAlreadyExistsError;
import com.uber.cadence.DomainNotActiveError;
import com.uber.cadence.EntityNotExistsError;
import com.uber.cadence.FeatureFlags;
import com.uber.cadence.GetWorkflowExecutionHistoryResponse;
import com.uber.cadence.HistoryEvent;
import com.uber.cadence.Memo;
Expand Down Expand Up @@ -206,7 +207,11 @@ protected void failed(Throwable e, Description description) {
private ScheduledExecutorService scheduledExecutor;
private List<ScheduledFuture<?>> delayedCallbacks = new ArrayList<>();
private static final IWorkflowService service =
new WorkflowServiceTChannel(ClientOptions.defaultInstance());
new WorkflowServiceTChannel(
ClientOptions.newBuilder()
.setFeatureFlags(
new FeatureFlags().setWorkflowExecutionAlreadyCompletedErrorEnabled(true))
.build());

@AfterClass
public static void closeService() {
Expand Down Expand Up @@ -2501,12 +2506,7 @@ public void testSignalingCompletedWorkflow() {
client.mySignal("Hello!");
assert (false); // Signal call should throw an exception, so fail if it doesn't
} catch (Exception e) {
if (e.getCause().getClass() != WorkflowExecutionAlreadyCompletedError.class
&& e.getCause().getClass() != EntityNotExistsError.class // only for legacy servers
) {
// Using assertEquals to output the actual error
assertEquals(WorkflowExecutionAlreadyCompletedError.class, e.getCause().getClass());
}
assertEquals(WorkflowExecutionAlreadyCompletedError.class, e.getCause().getClass());
}
}

Expand Down