Interface ContextPropagator


public interface ContextPropagator
Context Propagators are used to propagate information from the workflow client to workflow execution, workflow to activity, workflow to child workflow, and workflow to child thread created using Async.
The propagation works from top to bottom, lower level contexts are not propagated back to the top.

A sample ContextPropagator that copies all MDC entries starting with a given prefix along the code path looks like this:


 public class MDCContextPropagator implements ContextPropagator {
   public String getName() {
     return this.getClass().getName();
   }

   public Object getCurrentContext() {
     Map<String, String> context = new HashMap<>();
     for (Map.Entry<String, String> entry : MDC.getCopyOfContextMap().entrySet()) {
       if (entry.getKey().startsWith("X-")) {
         context.put(entry.getKey(), entry.getValue());
       }
     }
     return context;
   }

   public void setCurrentContext(Object context) {
     Map<String, String> contextMap = (Map<String, String>) context;
     for (Map.Entry<String, String> entry : contextMap.entrySet()) {
       MDC.put(entry.getKey(), entry.getValue());
     }
   }

   public Map<String, Payload> serializeContext(Object context) {
     Map<String, String> contextMap = (Map<String, String>) context;
     Map<String, Payload> serializedContext = new HashMap<>();
     for (Map.Entry<String, String> entry : contextMap.entrySet()) {
       serializedContext.put(entry.getKey(), DataConverter.getDefaultInstance().toPayload(entry.getValue()).get());
     }
     return serializedContext;
   }

   public Object deserializeContext(Map<String, Payload> context) {
     Map<String, String> contextMap = new HashMap<>();
     for (Map.Entry<String, Payload> entry : context.entrySet()) {
       contextMap.put(entry.getKey(), DataConverter.getDefaultInstance().fromPayload(entry.getValue(), String.class, String.class));
     }
     return contextMap;
   }
 }
 
To set up the context propagators, you must configure them during creation of WorkflowClient on both client/stubs and worker side:

 WorkflowClientOptions options = WorkflowClientOptions.newBuilder()
                 .setContextPropagators(Collections.singletonList(new MDCContextPropagator()))
                 .build();
 WorkflowClient client = WorkflowClient.newInstance(service, factoryOptions);

 Workflow workflow = client.newWorkflowStub(Workflow.class,
                WorkflowOptions.newBuilder().setTaskQueue("taskQueue").build());
 //or
 WorkerFactory workerFactory = WorkerFactory.newInstance(client);
 

If you wish to override them for a workflow stub or a child workflow, you can do so when creating a
WorkflowStub:

 Workflow workflow = client.newWorkflowStub(Workflow.class,
                WorkflowOptions.newBuilder()
                        //...
                        .setContextPropagators(Collections.singletonList(new MDCContextPropagator()))
                        .build());
 

ChildWorkflowStub:

 ChildWorkflow childWorkflow = Workflow.newChildWorkflowStub(ChildWorkflow.class,
                ChildWorkflowOptions.newBuilder()
                        .setContextPropagators(Collections.singletonList(new MDCContextPropagator()))
                        .build());
 

  • Method Details

    • getName

      String getName()
      Returns the unique name of the context propagator. This name is used to store and address context objects to pass them between threads. This name is not used for serialization, serialization is fully controlled by serializeContext(Object)
      Returns:
      The unique name of this propagator.
    • serializeContext

      Map<String,io.temporal.api.common.v1.Payload> serializeContext(Object context)
      Given context data, serialize it for transmission in the RPC header.

      Note: keys of the result map should have unique values across all propagators and interceptors, because they all share the same single keyspace of a single instance of temporal.api.common.v1.Header

      Returns:
      serialized representation to be sent in request temporal.api.common.v1.Header
    • deserializeContext

      Object deserializeContext(Map<String,io.temporal.api.common.v1.Payload> header)
      Turn the serialized header data into context object(s)
    • getCurrentContext

      Object getCurrentContext()
      Returns the current context in object form
    • setCurrentContext

      void setCurrentContext(Object context)
      Sets the current context