Skip to content

Commit

Permalink
Support feature flags in java client (#619)
Browse files Browse the repository at this point in the history
  • Loading branch information
demirkayaender authored Aug 24, 2021
1 parent c06ec9e commit 8c61213
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 9 deletions.
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

0 comments on commit 8c61213

Please sign in to comment.