6 Replies Latest reply on Apr 12, 2013 1:47 PM by dward

    How to map process variables to SwitchYard Service when using the standard BPMN2 Service Task

    jeffdelong

      The documentation https://docs.jboss.org/author/display/SWITCHYARD08/BPM says

       

      Using the standard BPMN2 Service Task

      It is possible to invoke SwitchYard Services using the standard BPMN2 Service Task <serviceTask>. It is conceptually similar, however you will use the Service Task icon from the BPMN2 Editor palette, and configure it slightly differently:

      • The <serviceTask> knows to invoke SwitchYard when it has an implementation="##SwitchYard" attribute.
      • The ServiceName is derived from the BPMN2 interfaceImplementationRef.
      • The ServiceOperationName is derived from the BPMN2 operationImplementationRef.
      • The ContentInputName is always called Parameter.
      • The ContentOutputName is always called Result.

       

      The Eclipse BPMN Editor displays:

       

      mappingvariables.png

       

      Map to a Variable has only one option in the Mapped To, which is PolicyQuoteProcess/policy (where policy is the name of the variable on the process). I believe I want to map From PolicyQuoteProcess/policy to a task variable.

       

      There also seems to be confusion between mapping direction. The documentation says

       

      Content I/O Properties

      • ContentInputName: (optional; default=contentInput) The process variable which the message content will be placed in.
      • ContentOutputName: (optional; default=contentOutput) The process variable which the message content will be gotten from.

       

       

      But above

       

      • The ContentInputName is always called Parameter.
      • The ContentOutputName is always called Result.

       

      Parameter should be used as the name of the variable going into the message (i.e. where the message content will be gotten from). and Result should be the name of the variable where the results of the Service task are placed.

        • 1. Re: How to map process variables to SwitchYard Service when using the standard BPMN2 Service Task
          rcernich

          Hey Jeff,

           

          For the ServiceTask integration, the parameter is always Parameter and the result is always Result.  This is the convention used by jBPM.  If you were using a Java class for the service (not a SwitchYard bean service), jBPM would instantiate the class from interfaceImplementationRef and invoke the method in operationImplementationRef with the contents of Parameter.

           

          As for the I/O mapping, when using the SwitchYard ServiceTask (as shown in your screenshot), there is no I/O mapping as the parameter and result are available to be mapped directly on the SwitchYard page (i.e. you don't have to create a Parameter DataInput or Result DataOutput).  Beyond that, I do not understand how having additional I/O parameters would be useful.

           

          That said, SwitchYard still supports a custom Task which can be used to dynamically specify invocation information (e.g. service name, operation name).  When using this method, you must specify the content input name and content output name manually, which default to contentInput and contentOutput.  Using this method also requires you to manually create the I/O mappings and you must ensure your task variable names match what you specify for ContentInputName and ContentOutputName.

           

          Not sure if that explanation helps or not.

           

          Best,

          Rob

          • 2. Re: How to map process variables to SwitchYard Service when using the standard BPMN2 Service Task
            jeffdelong

            Maybe a concrete example will help in the discussion. I am trying to get the Savara purchasing example working with the StoreService implemented as a BPM component. This example exposes the service through a SOAP Binding, and the Java Interface is

             

            public interface Store {

             

                public org.jboss.examples.store.BuyConfirmedType buy(

                    org.jboss.examples.store.BuyRequestType content

                ) throws AccountNotFoundFault;

                //, InsufficientCreditFault;

            }

             

             

             

            As a Bean component the following logic is performed:

             

                   CreditCheckType creditCheckReq = new CreditCheckType();
                    creditCheckReq.setId(content.getId());
                    creditCheckReq.setCustomer(content.getCustomer());
                   
                    CreditRatingType creditCheckResult = _creditAgency.creditCheck(creditCheckReq);

             

             

            I want to implement this same logic as part of a BPMN2 process.

             

            So when I start the process, the message.content is mapped to a process variable Store_buy_content

             

               <sca:component name="StoreProcess">

                  <bpm:implementation.bpm persistent="false" processId="org.savara.purchasing.store.PurchasingProcess">

                    <bpm:actions>

                      <bpm:action operation="buy" type="START_PROCESS">

                        <bpm:inputs>

                          <bpm:mapping expression="message.content" expressionType="MVEL" variable="Store_buy_content"/>

             

            Store_buy_content was automatically created by the BPMN Editor when I imported the Store interface.

             

            So next the process should invoke the CreditAgencyService using a CreditCheckType. I don't have a CreditCheckType, so I define an on-entry script to create one using data in the Store_buy_content variable.

             

             

             

            <serviceTask id="ServiceTask_1" tns:icon="org.switchyard.tools.ui.editor.SwitchYard.16" name="CreditAgencyService" implementation="##SwitchYard" operationRef="Operation_1">
              <extensionElements>
                <tns:onEntry-script scriptFormat="http://www.java.com/java">
                  <tns:script>Store_buy_content = new org.jboss.examples.store.BuyRequestType();

            CreditCheckType creditCheckReq = new CreditCheckType();

            creditCheckReq.setId(Store_buy_content.getId());

            creditCheckReq.setCustomer(Store_buy_content.getCustomer());/kcontext.setVariable(&quot;CreditAgency_creditCheck_content&quot;, creditCheckReq);</tns:script>

                </tns:onEntry-script>

             

             

            where CreditAgency_creditCheck_content is also a process variable.

             

             

            By the way deployement fails due to the first line of this script

             

            "Store_buy_content cannot be resolved"

             

             

            I can see under the ioSpecification element:

             

             

            <ioSpecification id="_InputOutputSpecification_4">
                <dataInput id="_DataInput_8" itemSubjectRef="ItemDefinition_1" name="Parameter"/>

             

            which refers to

             

              <itemDefinition id="ItemDefinition_1" structureRef="org.jboss.examples.creditagency.CreditCheckType"/>

              <message id="CreditAgency_creditCheck_content" itemRef="ItemDefinition_1" name="CreditAgency_creditCheck_content"/>

             

            So my question is then how to specify make Store_buy_content available to the script (or perhaps suggest another approach).

             

            The other point is that if Parameter and Result are already set why does the BPMN Editor show Map a Variable, etc.

            • 3. Re: How to map process variables to SwitchYard Service when using the standard BPMN2 Service Task
              dward

              One piece to this puzzle might be variable visibility in the runtime.  "Store_buy_content" is a process-level variable.  "Parameter" is a node-level variable to the node/task/workItem.  If I'm understanding what you're trying to do correctly, what you'll have to do in the BPMN2 editor is map processName/processVar -> localVar going in, and the same going out, if desired.  So, for you, whatever your "processName" is, you would map "processName/Store_buy_content" to "Parameter" on the way in, and "Result" to "processName/yourResultProcessVar" on the way out.  That should make your data available to your script, accessible using the "Parameter" variable name.

              • 4. Re: How to map process variables to SwitchYard Service when using the standard BPMN2 Service Task
                jeffdelong

                You are correct that Store_buy_content is a process variable, so either I map it to a node level variable or read it from the kcontext. The challenge with the former is that I don't think I can map it to Parameter since it is a different Java type. There is also the issue that I cannot see how to map it in the BPMN Editor (and there is only so much hand editing of the bpmn2 xml that I am willing to do).

                 

                So I read Store_buy_content from the kcontext, which makes it visible to the script. But still not sure how to get the input to the CreditAgency set correctly. "Parameter" is not a local variable that can be referenced in the script.

                 

                So my currrent script looks like

                 

                     org.jboss.examples.store.BuyRequestType content = (org.jboss.examples.store.BuyRequestType) kcontext.getVariable("Store_buy_content");

                org.jboss.examples.creditagency.CreditCheckType creditCheckReq = new org.jboss.examples.creditagency.CreditCheckType();

                creditCheckReq.setId(content.getId());

                creditCheckReq.setCustomer(content.getCustomer());

                kcontext.setVariable(&quot;CreditAgency_creditCheck_content&quot;, creditCheckReq);</tns:script>

                 

                 

                Which results in a runtime exception;

                 

                15:41:55,783 INFO  [org.switchyard.handlers.MessageTrace] (http--127.0.0.1-8080-1)

                ------- Begin Message Trace -------

                Service -> {http://www.savara.org/purchasing/Store}StoreService

                Operation -> buy

                Phase -> IN

                State -> OK

                Exchange Context ->

                Message Context ->

                    org.switchyard.messageId : 7e10c91c-f8ad-4d08-9539-298559b8fe54

                    org.switchyard.contentType : {http://www.jboss.org/examples/store}BuyRequest

                    org.switchyard.soap.messageName : buyRequest

                Message Content ->

                <?xml version="1.0" encoding="UTF-8"?><stor:BuyRequest customer="Bob" id="1" product="100" xmlns:stor="http://www.jboss.org/examples/store"/>

                ------ End Message Trace -------

                15:41:55,799 ERROR [stderr] (http--127.0.0.1-8080-1) Could not find variable CreditAgency_creditCheck_content

                15:41:55,801 ERROR [stderr] (http--127.0.0.1-8080-1) Using process-level scope

                15:41:55,803 INFO  [org.switchyard.handlers.MessageTrace] (http--127.0.0.1-8080-1)

                ------- Begin Message Trace -------

                Service -> {http://www.savara.org/purchasing/Store}CreditAgencyService

                Operation -> creditCheck

                Phase -> IN

                State -> OK

                Exchange Context ->

                Message Context ->

                    operationImplementationRef : creditCheck

                    FaultSignalId : _DataInput_9

                    org.switchyard.contentType : java:org.jboss.examples.creditagency.CreditCheckType

                    ParameterType : org.jboss.examples.creditagency.CreditCheckType

                    org.switchyard.messageId : 0f7c167d-cd83-4423-8f6f-d07c9b494c2d

                    interfaceImplementationRef : CreditAgencyService

                    implementation : ##SwitchYard

                    Interface : CreditAgency

                    Operation : creditCheck

                Message Content ->

                null

                ------ End Message Trace -------

                15:41:55,815 INFO  [org.switchyard.handlers.MessageTrace] (http--127.0.0.1-8080-1)

                ------- Begin Message Trace -------

                Service -> {http://www.savara.org/purchasing/Store}CreditAgencyService

                Operation -> creditCheck

                Phase -> OUT

                State -> FAULT

                Exchange Context ->

                    org.switchyard.exchange.transaction.beforeInvoked : true

                    org.switchyard.exchangeDurationMS : 12

                Message Context ->

                    org.switchyard.contentType : {http://www.jboss.org/examples/creditAgency}CustomerUnknown

                    org.switchyard.relatesTo : 0f7c167d-cd83-4423-8f6f-d07c9b494c2d

                    org.switchyard.messageId : 88ea0514-c449-49a0-8e71-59b0a2993b99

                Message Content ->

                org.switchyard.HandlerException: java.lang.IllegalArgumentException: obj parameter must not be null

                --- Caused by java.lang.IllegalArgumentException: obj parameter must not be null

                -----

                • 5. Re: How to map process variables to SwitchYard Service when using the standard BPMN2 Service Task
                  jeffdelong

                  I think I finally have the Variable Mapping worked out.

                   

                  First off, I needed to create the Variables. Importing the interface created Messages, not Variables (this was confusing because Messages are the same type as Variables).

                   

                  Once the Variables are created, the do show up in the

                   

                  Parameter Mapping Details

                   

                  Map to a Variable

                   

                  Mapped To   list

                   

                  I now I see the way to read this "The Variable selected in the Mapper To list will be mapped to the local Variable Parameter."

                   

                  Without knowing Parameter is an already created local variable, I was looking at this thinking I should be specifying the Local Variable being mapped to.

                   

                  I implemented the script to create the creditCheckVar from the buyRequestVar in a separate Script Task (although I should be able to get this to work in an on entry script). I even called the ScriptTask, AssignDataToCreditCheck.

                   

                  At this point it is modeled similar to a BPEL process, which would have an Assign Activity between the Receive and the Invoke. In the BPEL Editor the Assign would consist of a series of Copy Statements where the user could select parts of the from and to variables to map. With jBPM, there is not concept of data mapping, so this must be performed manually in the Script task.

                   

                  On to resolving the next exception

                  • 6. Re: How to map process variables to SwitchYard Service when using the standard BPMN2 Service Task
                    dward

                    Wow. Good detective work.  Wrestling with the BPMN2 editor is not fun, especially when you want to specificy something that seems only possible to be done by-hand.  The whole "importing the interface creating Messages vs. Variables" issue would have made me bang my head on the table for a while, to be sure.   Luckily, work on the BPMN2 editor is acive, so hopefully issues will get worked out, a higher level of synergy between the editor and the jBPM runtime will be met, and the dust will settle.