-
1. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dward May 30, 2013 4:17 PM (in response to dustin.barlow)This all has to do with correlation. Your first invocation starts a new process. The sequence-generated bpm:processInstanceId will get returned in the response headers so that in future invocations, the same id can be sent back in as a request header so that the same process instance is correlated with your signal event.
Up until recently, this was the only correlation mechanism available. However, in 0.8 (what you're using), you can also make use of specifying your own business key when you start a process, and just keep sending in that same business key for any future interactions with the same process instance. Then you can ignore the processInstanceId. The responsibility of making sure business keys is unique is on YOU now, however.
To do this, send in a bpm:correlationKey request header with your start process, with any value that you want, and send that same value in with any subsequent signal event or abort process instance requests. If you're going to do this to the same instance of jbpm across multiple junit tests, you'll want to somehow make sure that each test uses it's own correlation key. You can probably use the java.util.UUID class for this.
-
2. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dustin.barlow May 30, 2013 4:33 PM (in response to dward)Two follow up questions:
First, how do I send in the bpm:correlationKey as a request header using the Invoker service API? I looked around the Invoker service functions and didn't see anything obvious. If you have an example or a link to online docs, I would appreciate it.
Second, as far as service scoping is concerned, I assume that in order to test a signal I first have to invoke the START_PROCESS so there is at least an existing instance and then send the signal request all WITHIN the same unit test method?
David Ward wrote:
...
To do this, send in a bpm:correlationKey request header with your start process, with any value that you want, and send that same value in with any subsequent signal event or abort process instance requests. If you're going to do this to the same instance of jbpm across multiple junit tests, you'll want to somehow make sure that each test uses it's own correlation key. You can probably use the java.util.UUID class for this.
-
3. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dward May 30, 2013 4:41 PM (in response to dustin.barlow)First, how do I send in the bpm:correlationKey as a request header using the Invoker service API? I looked around the Invoker service functions and didn't see anything obvious. If you have an example or a link to online docs, I would appreciate it.
Request headers are analagous to context propeties. Try something like this:
Exchange e = _myInvoker.operation("myOperation").createExchange(handler);
Message m = e.createMessage().setContent("myContent");
m.getContext().setProperty("{urn:switchyard-component-bpm:bpm:1.0}correlationKey", "myUniquePerTestBizKey");
Second, as far as service scoping is concerned, I assume that in order to test a signal I first have to invoke the START_PROCESS so there is at least an existing instance and then send the signal request all WITHIN the same unit test method?
Yes. In both invocations (the start process and the signal event), send in the SAME context property name+value.
-
4. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dward May 30, 2013 4:43 PM (in response to dward)Well I guess technically it doesn't have to be within the same unit test method, unless that unit test bootstraps the whole runtime up+down each time. The important part is that a process instance was already started - and exists - with the same correlation key that you're gonna send in again when you signal event.
-
5. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dustin.barlow May 30, 2013 5:18 PM (in response to dward)I'm honestly not sure if the unit test bootstraps the whole run-time up and down each time a test method is invoked since I'm using the injected service.
package com.example.switchyard; import org.junit.Test; import org.junit.runner.RunWith; import org.switchyard.component.test.mixins.cdi.CDIMixIn; import org.switchyard.test.Invoker; import org.switchyard.test.ServiceOperation; import org.switchyard.test.SwitchYardRunner; import org.switchyard.test.SwitchYardTestCaseConfig; @RunWith(SwitchYardRunner.class) @SwitchYardTestCaseConfig(mixins = CDIMixIn.class, config = SwitchYardTestCaseConfig.SWITCHYARD_XML) public class AsyncSignalEventTest { @ServiceOperation("AsyncSignalEvent") private Invoker service; @Test public void testStartProcess() throws Exception { ProcessInfo message = new ProcessInfo(); message.setGuid("SOMEGUID1234"); message.setJobId("JobID999"); message.setJobName("Some Job Name"); message.setUserId("bob@bob.com"); RequestAck result = service.operation("startProcess").sendInOut(message) .getContent(RequestAck.class); // validate the results Assert.assertTrue(result.getStatus()) } @Test public void testUpdateTask() throws Exception { TaskInfo message = new TaskInfo(); message.setGuid("SOMEGUID1234"); message.setWorkItemId(1); RequestAck result = service.operation("updateTask").sendInOut(message) .getContent(RequestAck.class); // validate the results Assert.assertTrue(result.getStatus()) } }
Am I correct that the Invoker service injected into the unit test survives the entire lifecycle of the class instance? In other words, the Switchyard runtime is bootstrapped when an instance of the AsyncSignalEventTest class is created and then torn down when the class goes out of scope?
-
6. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dward May 30, 2013 6:06 PM (in response to dustin.barlow)Depends on the lifecycle rules of @RunWith, which honestly I'm forgetting right now. However...
Put this line in each of your @Test methods to find out:
System.out.println("**** service invoker: " + System.identityHashCode(service) + " ****");
If it's the same in both test methods, it was only injected once per test class.
-
7. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dustin.barlow May 30, 2013 11:07 PM (in response to dward)Looks like it is a different instance per unit test method invoked:
**** testStartProcess: service invoker: 1465804433 **** **** testUpdateTask: service invoker: 1956433926 ****
So I'll have to do both the START_PROCESS and SIGNAL_EVENT service calls within the same method in order to ensure a BPMN process instance exists.
-
8. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
edevera Jun 21, 2013 11:30 AM (in response to dustin.barlow)Apparently the feature David is referring to will be released as part of 1.0 if I have understood correctly the following ticket: https://issues.jboss.org/browse/SWITCHYARD-325
-
9. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dward Jun 21, 2013 12:12 PM (in response to edevera)That is correct, Eduardo.
-
10. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dustin.barlow Jun 21, 2013 12:44 PM (in response to dward)Will there also be better support for setting the correlationId on the Invoker?
Right now, I have to do something like this...
import org.switchyard.Exchange; import org.switchyard.Message; ... TestExchangeHandler exchangeHandler = new TestExchangeHandler(); Exchange e = service.operation("updateTask").createExchange(exchangeHandler); Message m = e.createMessage().setContent(taskInfo); e.getContext().setProperty("{urn:switchyard-component-bpm:bpm:1.0}correlationKey", "2"); e.send(m); // TestExchangeHandler Class import org.switchyard.Exchange; import org.switchyard.ExchangeHandler; import org.switchyard.HandlerException; public class TestExchangeHandler implements ExchangeHandler { /* (non-Javadoc) * @see org.switchyard.ExchangeHandler#handleMessage(org.switchyard.Exchange) */ @Override public void handleMessage(Exchange exchange) throws HandlerException {} /* (non-Javadoc) * @see org.switchyard.ExchangeHandler#handleFault(org.switchyard.Exchange) */ @Override public void handleFault(Exchange exchange) {} }
The above code does not return the response from the service. I did look into the Invoker code to see how it handled returned content and found that I would need to register some type of result handler callback thing. I decided to punt at that point.
It would be nice if I could just do something like this:
@ServiceOperation("SomeProcess") private Invoker service; service.operation("startProcess").setProperty("{urn:switchyard-component-bpm:bpm:1.0}correlationKey", "myUniquePerTestBizKey"); RequestAck result = service.operation("startProcess").sendInOut(message).getContent(RequestAck.class);
-
11. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dward Jun 24, 2013 4:28 AM (in response to dustin.barlow)This really has nothing to do with our BPM component, or corelation keys. This has to do with desiring a fluent API to set context properties using our testcase ServiceInvoker stuff. Agreed?
-
12. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dustin.barlow Jun 24, 2013 10:05 AM (in response to dward)I suppose you're technically correct given what I understand. However, I don't know of anything else in SY aside from BPM that at its core needs context properties passed in from the caller in order to function propertly. So while it isn't directly related, having a fluent/clear/clean API certainly is desirable for unit testing BPM processes.
I spent a long time trying to figure out what on the surface seems to be a pretty simple concept of setting a property on a message. The API made it difficult to intuatively understand where to set it. Had you not given me some hints above, I don't think I would have ever figured it out just based on the documentation or the API JavaDocs.
I can certainly post the request in another forum topic or as a feature enhancement request in Jira if that would be more helpful. I suspect this will be a very common use case for others as well.
-
13. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dward Jun 24, 2013 11:43 AM (in response to dustin.barlow)I suppose you're technically correct given what I understand. However, I don't know of anything else in SY aside from BPM that at its core needs context properties passed in from the caller in order to function propertly
Both the BPM and Rules components can be stateful. I don't know of any other SwitchYard comopnents that are like that, at least off the top of my head.
Had you not given me some hints above, I don't think I would have ever figured it out just based on the documentation or the API JavaDocs.
Documentation is due for a major revamp. It's on my plate.
I can certainly post the request in another forum topic or as a feature enhancement request in Jira if that would be more helpful.
I think a feature request jira is the best place to start. You don't have to create a new forum topic, but please do link from the jira to the anchor of the first related comment in this thread. Thank you!!!
-
14. Re: How to create a Switchyard SIGNAL_EVENT from a jUnit test?
dustin.barlow Jun 25, 2013 9:46 AM (in response to dward)It appears a ticket already exists for enhancing the ServiceInvoker https://issues.jboss.org/browse/SWITCHYARD-923. Doesn't look like there has been any activity on it for about a year though.