1 2 Previous Next 20 Replies Latest reply on Mar 28, 2014 4:34 PM by Dustin Barlow

    How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?

    Dustin Barlow Newbie

      I am looking for some information or an example project that demonstrates how to send and receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings.

       

      The documentation for BPM integration in Switchyard only shows how to accomplish this exchange of context/correlation meta-data via SOAP headers.  Since this exchange happens automatically (ie no coding or mapping needed) when a BPM component is promoted and uses a SOAP binding, it is unclear to me how I would accomplish this same context passing to a BPM component from a REST binding?

       

      Thanks!

      Dustin

        • 1. Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
          Keith Babo Master

          We don't have a specific example of this, but it's identical in concept to what you would do with SOAP.  In the case of SOAP, information outside of the SOAP Body (SOAP headers, HTTP headers) can be passed into SY as context properties.  For REST, the same principle applies - HTTP headers or JAX-RS parameters (e.g. path element) can be passed in as context properties.  You can configure the default context mapper for REST bindings to pass along HTTP headers.  For JAX-RS parameters, you will need a custom message composer.  An example of a message composer used with REST can be found in the rest-binding quickstart (although it doesn't do exactly what you're asking):

          quickstarts/rest-binding at master · jboss-switchyard/quickstarts · GitHub

           

          To get started, how do you plan on passing these from a REST client standpoint?  As HTTP headers?

          • 2. Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
            Dustin Barlow Newbie

            Thanks for the info Keith.  I had looked into the rest quickstart prior to asking the question but I wasn't really sure where to get access to those BPM generated parameters since they all magically appeared in the SOAP header without requiring any custom message composers.  I did have to add ".*" on the header configuration of the SOAP binding in order to see them in the SOAP response.

             

            I also wasn't sure where I was suppose to set them on inbound requests either.  Your point about a custom message composer to poke those values into the context seems to make sense.  I'm not 100% on how to do that though since I'm new to custom message composers but I'll take a closer look.  I also wasn't sure if the message composer fired pre or post the REST resource mapping class.

             

            At this point, I am open to suggestions on the best way to pass the IDs from a REST client.  I have full control over client as well as the server (B2B).  I could add it to the XML payload (JAXB based), the URL path, or perhaps even the HTTP headers.  The HTTP headers approach would be the one I'm the least familiar with on how to accomplish.

            • 3. Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
              Keith Babo Master

              The easiest way to handle this is to enable message tracing and then tweak the context mapper settings as needed.  For example, if you have an existing process with SOAP bindings already defined, then you should be able to turn on message tracing and see the appropriate context properties flow into and out of the process.  Once you're there, you can then add a REST binding and configure the context mapper to include ".*".  Kick off a process and verify that the appropriate property is returned in the message trace and available as an HTTP header in your return message.  If not, holler back in the forum and we'll help you work through it.  Rinse, wash, and repeat for the next case where you pass the HTTP headers from a REST client containing the correlation information in a subsequent invocation.

               

              I would start with HTTP headers for the IDs right now.  Once we are good there, we can debate the finer points of whether it belongs somewhere else. :-)

              1 of 1 people found this helpful
              • 4. Re: Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
                Dustin Barlow Newbie

                I added a REST binding to one of my test projects that successfully uses SOAP bindings to send correlationKeys back and forth to the BPM component.  I included the ".*" in Includes field of the Message Composer tab of the REST Binding.

                 

                With tracing turned on, I tried kicking off the BPM process without sending a correlationKey in the HTTP header.  I saw in the Message Context section that {urn:switchyard-component-bpm:bpm:1.0} processInstanceId : 1 was in the OUT message.  However it did not show up in the HTTP header of the response.

                 

                The next test I tried was to send "correlationKey" as a header value.  I only saw in the Message Context section the "correlationKey" name and value I passed in but only in the second message trace.  After that, the name and value was gone.  It was also not returned in the HTTP header of the response.

                 

                I then decided to try putting "{urn:switchyard-component-bpm:bpm:1.0}correlationKey" to match what I saw in the SOAP tests.  This test resulted in the following error:

                 

                23:43:00,881 ERROR [org.switchyard.component.resteasy] (http-localhost/127.0.0.1:8080-1) SWITCHYARD037601: Unexpected exception composing inbound Message: java.lang.IllegalArgumentException: cannot create QName from "{urn", missing closing "}"
                    at javax.xml.namespace.QName.valueOf(QName.java:504) [classes.jar:1.6.0_65]
                    at org.switchyard.common.xml.XMLHelper.createQName(XMLHelper.java:720) [switchyard-common-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.common.composer.BaseRegexContextMapper.matches(BaseRegexContextMapper.java:100) [switchyard-component-common-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.composer.RESTEasyContextMapper.mapFrom(RESTEasyContextMapper.java:51) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.composer.RESTEasyContextMapper.mapFrom(RESTEasyContextMapper.java:33) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.composer.RESTEasyMessageComposer.compose(RESTEasyMessageComposer.java:39) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.composer.RESTEasyMessageComposer.compose(RESTEasyMessageComposer.java:31) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.InboundHandler.invoke(InboundHandler.java:108) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.util.RESTEasyProxy.invoke(RESTEasyProxy.java:94) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at com.sun.proxy.$Proxy115.submit(Unknown Source)
                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [classes.jar:1.6.0_65]
                    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [classes.jar:1.6.0_65]
                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [classes.jar:1.6.0_65]
                    at java.lang.reflect.Method.invoke(Method.java:597) [classes.jar:1.6.0_65]
                    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:269) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:227) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:216) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:542) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:524) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:126) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1]
                    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)
                    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
                    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
                    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)
                    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145)
                    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)
                    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)
                    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336)
                    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
                    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)
                    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920)
                    at java.lang.Thread.run(Thread.java:695) [classes.jar:1.6.0_65]
                
                23:43:00,887 WARN  [org.jboss.resteasy.core.SynchronousDispatcher] (http-localhost/127.0.0.1:8080-1) failed to execute: javax.ws.rs.WebApplicationException: java.lang.IllegalArgumentException: cannot create QName from "{urn", missing closing "}"
                    at org.switchyard.component.resteasy.InboundHandler.invoke(InboundHandler.java:111) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.util.RESTEasyProxy.invoke(RESTEasyProxy.java:94) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at com.sun.proxy.$Proxy115.submit(Unknown Source)
                    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [classes.jar:1.6.0_65]
                    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) [classes.jar:1.6.0_65]
                    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) [classes.jar:1.6.0_65]
                    at java.lang.reflect.Method.invoke(Method.java:597) [classes.jar:1.6.0_65]
                    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:269) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:227) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:216) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:542) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:524) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:126) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50) [resteasy-jaxrs-2.3.6.Final-redhat-1.jar:2.3.6.Final-redhat-1]
                    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1]
                    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)
                    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
                    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
                    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)
                    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145)
                    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)
                    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)
                    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336)
                    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
                    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653)
                    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920)
                    at java.lang.Thread.run(Thread.java:695) [classes.jar:1.6.0_65]
                Caused by: java.lang.IllegalArgumentException: cannot create QName from "{urn", missing closing "}"
                    at javax.xml.namespace.QName.valueOf(QName.java:504) [classes.jar:1.6.0_65]
                    at org.switchyard.common.xml.XMLHelper.createQName(XMLHelper.java:720) [switchyard-common-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.common.composer.BaseRegexContextMapper.matches(BaseRegexContextMapper.java:100) [switchyard-component-common-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.composer.RESTEasyContextMapper.mapFrom(RESTEasyContextMapper.java:51) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.composer.RESTEasyContextMapper.mapFrom(RESTEasyContextMapper.java:33) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.composer.RESTEasyMessageComposer.compose(RESTEasyMessageComposer.java:39) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.composer.RESTEasyMessageComposer.compose(RESTEasyMessageComposer.java:31) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    at org.switchyard.component.resteasy.InboundHandler.invoke(InboundHandler.java:108) [switchyard-component-resteasy-1.1.1-p5-redhat-1.jar:1.1.1-p5-redhat-1]
                    ... 29 more
                

                 

                I then thought that maybe that I needed to encode the parameter name to be "%7Burn%3Aswitchyard-component-bpm%3Abpm%3A1.0%7DcorrelationKey".  While I didn't get the exception, the behavior was exactly the same as when I just set "correlationKey" as the parameter name in the HTTP Header.

                 

                So, in short, I'm not seeing any of the BPM added processInstanceIds in the HTTP Header in any case.  The headers I send that don't error out do get set in the Message Context but they get discarded early in the process.  I suspect this is due to them not being mapped automatically further down the message exchange lifecycle.

                • 5. Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
                  Tadayoshi Sato Novice

                  Hello Dustin and Keith,

                   

                  Excuse me for chiming in this discussion. I also know another user who encountered the very similar question, in which case they wanted to know how to signal those jBPM metadata via SCA binding instead.

                   

                  Now I believe this topic is one of the recurring hot spots for SwitchYard usages and it would be ideal to have quickstarts for this, so I've gone ahead and filed a feature request for those quickstarts.

                  [SWITCHYARD-1983] Add quickstarts for signaling metadata (processInstanceId, correlationKey, sessionId, etc.) to BPM ser…

                   

                  I hope you both think that's relevant.

                   

                  -- Tadayoshi

                  • 7. Re: Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
                    Dustin Barlow Newbie

                    I am using the Switchyard version 1.1.1-p5-redhat-1 that comes bundled with Fuse Service Works 6.0.0.GA.

                    • 8. Re: Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
                      Keith Babo Master

                      OK, there was a bug in the REST binding in pre-1.1 versions that could impact returning context properties as headers.

                      • 9. Re: Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
                        Dustin Barlow Newbie

                        Hi Tadayoshi,

                         

                        I think it is relevant.  I voted for your feature enhancement and will be watching to see what happens with it.

                         

                        I have spent quite a bit of time trying to figure out how all the BPM integration points with Switchyard actually work and how the various bindings expose and manage those things.  I've had limited success due to a lack of documentation and/or example code.

                         

                        I would also like to see more documentation around the message context and exchanges.  When to use them and why.

                        • 11. Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
                          Keith Babo Master

                          I don't think so.  I'm going to give this a try with a modified version of our bpm-service quickstart and I'll get back to you.  I'm neck deep in a couple of other issues at the moment, so it might not be until the end of the week.

                          • 13. Re: Re: Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
                            Keith Babo Master

                            I think the issue that you are hitting is that the REST binding is a bit too restrictive with its inclusion criteria for property values:

                            components/resteasy/src/main/java/org/switchyard/component/resteasy/composer/RESTEasyContextMapper.java at master · jbos…

                             

                            Since the process id value is a Long, it doesn't get mapped regardless of how the context mapper is configured.  A workaround for now is to simply extend the default RESTEasy context mapper and pick up the property on your own.  I have attached an example based on the bpm-service quickstart.  Things to check out:

                             

                            • RESTEasy binding added to the ProcessOrder service in addition to the SOAP binding already there.
                            • OrderResource JAX-RS interface added
                            • WebServiceTest updated to use non-SOAP XML payload, new endpoint address, and assertion that the processId header is present
                            • BPMClient updated to use non-SOAP XML payload with new endpoint address

                             

                            hth,

                            keith

                            1 2 Previous Next