1 2 Previous Next 20 Replies Latest reply on Mar 28, 2014 4:34 PM by dustin.barlow Go to original post
      • 15. Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
        dustin.barlow

        Thank you Keith for the example.  I'm working through it now.

         

        The one gap in my head in thinking about the current restriction on property values in the version I'm using is that correlationKey is a String so it should work even without the custom context mapper correct?

         

        The reason I ask is I did try correlationKey a few days back and it also didn't seem to get picked up.

         

        I notice in your example that you are setting the HTTP header to a value of "processId" which is different from "{urn:switchyard-component-bpm:bpm:1.0}processInstanceId".  The later is the property name the BPM component expects.  I see as well that you fix this mismatch in your custom context mapper by mapping "processId" to "{urn:switchyard-component-bpm:bpm:1.0}processInstanceId".

         

        I think the reason the "correlationKey" didn't work for me earlier was that it is not being mapped to a property name of "{urn:switchyard-component-bpm:bpm:1.0}correlationKey".  When I tried to put "{urn:switchyard-component-bpm:bpm:1.0}correlationKey" as the actual header value in the HTTP request, that is when I received the exception stack I pasted a few message up from this one.

         

        So it appears to me that even with the current restriction limitation, you'd still need a custom context mapper for correlationKey to do this property name mapping since it seems you are not allowed to use the "urn" style property name in the HTTP header.  Is this a bug?

        • 16. Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
          kcbabo

          One thing to keep in mind with my example is that it only demonstrates returning the process instance id in an HTTP response header.  The app does not signal the process on a request.  I did that on purpose so that we could focus on one bit at a time.  To your specific questions:

           

          • The header name "processId" was an arbitrary choice on my part.  You could return it as "{urn:switchyard-component-bpm:bpm:1.0}processInstanceId" if you wanted.
          • The custom context mapper does not fix a mismatch, since it's mapping from context properties to HTTP headers.  So it's really just changing the name, which is not required.
          • You need a context mapper for the response for sure.  I haven't tested a subsequent reply with a correlation key, but since you already have a context mapper in place, it's not a huge deal. :-)
          • 17. Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
            dustin.barlow

            Ok, I thought you were setting the processId in the WebServiceTest class with this line httpMixIn.setExpectedHeader("processId", "1");.  I take it that really is just to check that you get that header back not that it is setting the headers on the outgoing request.  If so, cool .. didn't know you could do that.

             

            Since I'm using Switchyard 1.1.1, I'm not able to build and run your project because I don't have all the other 2.0.0-SNAPSHOT artifacts like the parent poms, so I'm just going by what I see at the moment.

             

            The BPM component seems to require the property name in the form of "{urn:switchyard-component-bpm:bpm:1.0}processInstanceId" for either initial requests or subsequent signals.  This is what the message trace shows all the way through for SOAP bindings where that SOAP header is set by the client.

             

            I still am unclear though in the case of sending in either processInstanceId or a correlationKey as an HTTP header on either initial or subsequent signal requests how I could set the property "{urn:switchyard-component-bpm:bpm:1.0}processInstanceId" without doing as you did (EDIT: i.e., using a custom context mapper and setting the header to "processId" on the inbound request).  You simply cannot send in a header value of "{urn:switchyard-component-bpm:bpm:1.0}processInstanceId".  It throws that error about missing a "}" right up front.

            • 18. Re: Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
              dustin.barlow

              Just in case this is useful to someone reading this thread, I thought I would post how I was able to pass and set jBPM values from the inbound message instead of the headers.

               

              In my case I am using REST bindings but I assume the same technique would work for the other binding types as well.

               

              The REST interface:

               

              @Path("/")
              public interface PayloadServiceResource {
                 
                  @POST
                  @Path("/submit")
                  @Produces({"text/xml"})
                  public Payload submit(Payload payload);
                 
                  @POST
                  @Path("/signalOne")
                  @Produces({"text/xml"})
                  public Payload signalOne(Payload payload);
              }
              
              

               

              This is the PayloadContextMapper class I select for the context mapper the REST binding will use.

               

              public class PayloadContextMapper extends RESTEasyContextMapper {
              
                  private static final Logger logger = Logger.getLogger(PayloadContextMapper.class);
              
                  private static final String PROCESS_ID_KEY = "{urn:switchyard-component-bpm:bpm:1.0}processInstanceId";
                  private static final String CORRELATION_KEY = "{urn:switchyard-component-bpm:bpm:1.0}correlationKey";
              
                  // Takes the payload key from the inbound Payload and maps it to the jBPM correlationKey
                  // Assumption is that there will only be one Payload object in the "source" parameter
                  @Override
                  public void mapFrom(RESTEasyBindingData source, Context context) throws Exception {
              
                      super.mapFrom(source, context);
                     
                      for (Object obj : source.getParameters()) {
                          if (obj instanceof Payload) {
                              Payload payload = (Payload) obj;
                              context.setProperty(CORRELATION_KEY, payload.getKey());
                          }
                      }
                  }
              
                  // Takes the processInstanceId and sets the value on the Payload object being returned.
                  // NOTE: Not sure why the correlationKey is not available here.  Only the processInstanceId.
                  @Override
                  public void mapTo(Context context, RESTEasyBindingData target) throws Exception {
                     
                      super.mapTo(context, target);
              
                      Long pid = context.getPropertyValue(PROCESS_ID_KEY);
                      logger.info("processInstanceId: " + pid);
              
                      if (pid != null) {
                          for (Object obj : target.getParameters()) {
                              if (obj instanceof Payload) {
                                  Payload payload = (Payload) obj;
                                  payload.setProcessId(pid.toString());
                              }
                          }
                      }
                  }
              }
              
              

               

              I don't really like having to loop through the source and target parameters to pick out the Payload object.  If there is a better way to do this, I'd be interested to hear how.  Obviously this logic wouldn't work if there ended up being more than one Payload object in source or target parameters.

               

              One other thing that was a bit strange and I noted it in the code is that the correlationKey does not get sent back from the jBPM component.  Only the processInstanceId.  Is this a bug or intended behavior?

              • 19. Re: Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
                dward

                This jira should help make your custom context mapper unnecessary in the future, in case you want to follow it:

                 

                [SWITCHYARD-1585] Allow correlationKey to come from message content vs message context - JBoss Issue Tracker

                 

                Setting the correlationKey in the response was not done intentionally because it was deemed unnecessary.  Reason is that it is the client that creates and sends in the correlationKey in the first place, and thus should already know what it is.  The processInstanceId, however, is generated from jBPM.  Do you see a need for having the correlationKey in the response?

                • 20. Re: Re: How to send/receive jBPM processInstanceId, correlationKey, and sessionId using REST bindings?
                  dustin.barlow

                  Yes, the client would have sent the correlationKey in the first place and I figured that might be the answer.

                   

                  I was thinking it might be needed in the case that you have a Bean tied to an outbound reference binding that gets invoked by BPM.  It doesn't appear that you would be able to pull the correlationKey from the message context coming out of jBPM into that outbound reference binding without somehow stuffing the value into the payload itself.

                  1 2 Previous Next