cancel
Showing results for 
Search instead for 
Did you mean: 

sending specific signal to custom behavior task

miran
Champ in-the-making
Champ in-the-making
Hi, I got following problem - I use custom behavior to do some async work and I need to notify the process instance with information how the async task ended  - I am using following code:

public class MyAsyncTask implements SignallableActivityBehavior {

    // something that takes long time (sending JMS message) 
    public void execute(ActivityExecution exec) throws Exception {
        // sending msg to JMS here, long running task …
    }

    // after processing JMS, queue the process is notified and this method is invoked:
    public void signal(ActivityExecution execution, String signalEvent,
                       Object signalData) throws Exception {
        PvmTransition transition = execution.getActivity().getOutgoingTransitions().get(0);
        execution.take(transition);
    }

}

  and to notify the process I use


runtimeService.signal(pid); // working ok …


I found this solution here: https://forums.activiti.org/content/suspending-process-instance and it works for me except for that I need to send to the process also information about how the long running task ended - in other words, I need to send also event name and some data; if I use method

runtimeService.signalEventReceived(eventName, pid, vars);

I got following error:

Exception in thread "main" org.activiti.engine.ActivitiException: Execution '15001' has not subscribed to a signal event with name 'Failure Local'.


I found this (or similar) issue several times on activiti forums, but without satisfying answer.

Is this somehow doable with activiti? Do I need to invoke some method to subscribe the process instance to the event or do I need to model something specific in the process?

Thanks in advance!
8 REPLIES 8

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi,

You can follow your first approach with using

  /**
   * Sends an external trigger to an activity instance that is waiting inside
   * the given execution.
   *
   * @param executionId
   *          id of execution to signal, cannot be null.
   * @param processVariables
   *          a map of process variables
   * @throws ActivitiObjectNotFoundException
   *           when no execution is found for the given executionId.
   */
  void signal(String executionId, Map<String, Object> processVariables);
example:
org.activiti.engine.test.api.runtime.RuntimeServiceTest#testSignalWithProcessVariables
or you can create message start event to wait on runtimeService.signalEventReceived(eventName, pid, vars);example:org.activiti.engine.test.bpmn.event.signal.SignalEventTest#testSignalStartEventFromAPI
Regards
Martin

rajivmoghe
Champ in-the-making
Champ in-the-making
Hello Martin,

For some reason, it does not seem to work for me. I took the SignalEventTest xml and tried to run that on my spring-boot-activiti installation, and signalled it using the ReST API (PUT /runtime/executions/{exId} ) , but it gave the following issues:

When using the signal method,
Payload:
{
  "action":"signal",
  "signalName":"waitsig"
}

It fails with :
java.lang.NullPointerException: null
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.signal(ExecutionEntity.java:404)
at org.activiti.engine.impl.cmd.SignalCmd.execute(SignalCmd.java:43)
at org.activiti.engine.impl.cmd.NeedsActiveExecutionCmd.execute(NeedsActiveExecutionCmd.java:55)
at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:24)
at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:57)
at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
at org.activiti.engine.impl.RuntimeServiceImpl.signal(RuntimeServiceImpl.java:231)
at org.activiti.rest.service.api.runtime.process.ExecutionResource.performExecutionAction(ExecutionResource.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
While with the payload of:

{
  "action":"signalEventReceived",
  "signalName":"waitsig",
}
It responds with : "message": "Execution '17' has not subscribed to a signal event with name 'waitsig'.",
I've been trying to figure this one out for a while now too, but unable to make a headway.

Is there something really simple that we are missing here?

I've attached the bpmn xml file with this.

miran
Champ in-the-making
Champ in-the-making
Martin, thanks a lot for your quick response. It worked for me. The trick was in using method

<code>void signal(String executionId, Map<String, Object> processVariables);</code>
instead of
<code>void signalEventReceived(String, String, Map<String, Object>);</code>

I must have missed it totally! 

rajivmoghe
Champ in-the-making
Champ in-the-making
@Miran,
Would you be able to share the (sanitised) caller code, from which you call the signal method?

@Martin: What could be the reason for the null pointer, when calling the signal through ReST API?

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi Rajiv,

Create jUnit test please
https://forums.activiti.org/content/sticky-how-write-unit-test

Regards
Martin

ptica
Champ in-the-making
Champ in-the-making
Hi!
I'm curious about the <code>org.activiti.engine.test.bpmn.event.signal.SignalEventTest#testSignalStartEventFromAPI</code> example

it is not included in the release package, (I've looked into the lib/activiti-engine.jar) right? I've downloaded it from github, but I still struggle to visualize it, as bpmn di is not included there, I've used the Eclipse Designer to load it, but upon autolayout and import into Explorer only one task is shown, even though when I peak into the xml, there is lot more to it.

Is that the expected behaviour?
thank you!

martin_grofcik
Confirmed Champ
Confirmed Champ
Hi Ptica,

it is not included in the release package, (I've looked into the lib/activiti-engine.jar) right?
release does not contain tests. Download project from source repository.

bpmn di is only presentation layer - not needed for the engine to execute the tests. Usually test processes are so simple that they can be easily understandable from bpmn xml.

Is that the expected behaviour?

May be designer could create better default diagram layout…., but I would not waste time to fix that. Just understand the process from the bpm.xml

Regards
Martin

rajivmoghe
Champ in-the-making
Champ in-the-making
Hi Martin,

Thanks for the pointer… as I started to create the test, I realized where I was going wrong.
Turns out that I was using the wrong execution (processInstance != execution when a boundary event is encountered on an activity, see here and here) on the void signalEventReceived(String, String, Map<String, Object>); call.

I will create and post the test for the void signal(String executionId, Map<String, Object> processVariables); piece soon.