Use activity polymorphism in workflow

Hello,

we have a case, when workflow accepts object with type.
Then workflow sends request to 3rd party system with data, based on type. For this we implemented activity interface with several method and for each supported type we add its own method with ActivyMethod name defined.

This approach is not flexible, and we have to change both workflow and activity to support new type.
We’d like to use polymorphism and use single interface with single method and differ implementations. These implementations have info of which type they support, workflow only requires to go through implementations and get one, which was send.

Now we faced problem, that workflow requires interface to be stubbed with Workflow.newActivityStub

Ok, we may create bridge between list of services, that will really do the job. And this bridge will only collect them and execute by passed type.

But then we loose activity method name, now it will be named by default.

Is there a way to add to a workflow ability to use this or that implemented interface and change it on fly?

Thank you for your help,
Pavel

You can do something like:

interface A {
   foo();
}

@ActivityInterface
interface Activity1 extends A {}

@ActivityInterface
interface Activity2 extends A {}

class Activity1Impl implements Activity1 {
  foo() { ... }
}

class Activity2Impl implements Activity2 {
  foo() { ... }
}

Then inside the workflow code you can do something like:

A a1 = Workflow.newActivityStub(Activity1.class);
A a2 = Workflow.newActivityStub(Activity2.class);
a1.foo();
a2.foo();

Would it help to solve your problem?

Hi Maxim,
Thanks for reply

We investigated this case, but it does not fit our needs, as we have to update workflow each time we add some new type.
Same would be, if we add new methods into activity interface. Functionality extends only by changing interface and thus implementation. Not flexible, and fragile

What we want, is that, e.g.:

@WorkflowImpl
class WorkflowService{
ActivityInterface activityInterface;

WorkflowService(ActivityOptions activityOptions){
activityInterface = Workflow.newActivityStub(ActivityInterface.class, activityOptions);
}
.....

void start(String type){
.....
activityInterface.send(payload, type);
}
}

@ActivityInterface
interface ActivityInterface{
void send(Object payload, String type);
}

class ActivityInterfaceImpl implements {
List<Sender> senders;
//initiate in constructor

  void send(Object payload, String type){
  senders.stream().filter( x -> x.getType().equals(type)).findFirst()
                  .orElseThrow(() -> ApplicationFailure.newNonRetryableFailure(
                          String.format("Type %s not supported", type),
                          IllegalArgumentException.class.getName()))
                  .send(payload);
  }
}


public interface Sender {
    String getType();
    Boolean send(Object payload);
}


//Create many many implementations of Sender with different types

In this case in workflow history we see only event with name Send.

Is there a way to pass event name some other way? E.g. Sender would have method getName, and this would be used in ActivityInterfaceImpl to set event type?

I see. You can use the DynamicActivity to implement this.

Thanks! We will try