Wednesday, January 23, 2013

For Each Action In OSB


I was replying to OTN  forum post regarding OSB For each action at :


So thought of writing it down to make it more clear.....

  1. I have made xml based proxy service.



2. I assumed the payload would be 

<request>
<CompanyCollection>
<company>
<name>name1</name>
</company>
<company>
<name>name2</name>
</company>
</CompanyCollection>
<CompanyCollection>
<company>
<name>name3</name>
</company>
<company>
<name>name4</name>
</company>
</CompanyCollection>
</request>

3. Assigned $body to companycollreq ( user defined variable) using Assign action
    
4. To keep a count of companycollection elemennt in the  request payload
   Assign count($companycollreq/request/CompanyCollection) to  companyCount
   


5. Now use a for each action to iterate over companycollection
    For each expression would like as:
   For Each variable companycoll   in ./request/CompanyCollection of variable  companycollreq 
   Indexed by variable currIndex with total count in variable  companycount


6.  Under Do 
      I am logging the companycollection element based upon the currindex count in for loop.
      This is important as we need to pass payload under iteration in for loop. 

     Assign $companycollreq/request/CompanyCollection[xs:int($currIndex)] in log action with annotation 
     of companycoll

Now Testing is done with above payload.


In Console logs obtained:



This is how for each action works.
Log action runs twice as companycollection count was two in payload passed.
In place of log action we can use service callout/Publish/Java callout .
The payload passed must contain currIndex as xquery predicates expression while passing value to other services being called from for loop.




14 comments:

  1. Hi Abhinav,

    We are facing the same issue with the index variable.

    is it possible to pass the $index in the insert variable? We tried this but we are getting some name space errors?

    Could you please let us know whether can we pass $index in the insert action?

    Thanks,
    SV

    ReplyDelete
  2. $index variable will determine the current iteration level during the processing of the payload.

    [xs:int($currIndex)] is being used as predicate xquery expression for the dynamic assignment of payload depending upon the iteration count.

    ReplyDelete
  3. Hi,

    Can you please suggest xml parsing into database tables through OSB console as I am very new to OSB. I mean I hvae the xml file which is input to proxy service, then how the data of xml file is inserted into the table which we have created.

    ReplyDelete
    Replies
    1. Hi,

      You can use Oracle XML DB leveraging XML type .. to store the XML payload into the DB..
      http://www.oracle.com/technetwork/database-features/xmldb/xmldb-11g-twp-132368.pdf


      or the other way .. is to use DB adapter to to write the records into the DB ..
      You need to perform a transformation to transform your input xml payload to DB adapter write operation request payload ...

      Thanks,
      Abhinav

      Delete
  4. Hello id like to publish JMS-BS for each element of collection. My problem is that my index is still 0.

    2 questions:
    What can be a problem that my loop doesnt itarate?
    Is it ok if i publish BS in loop?

    Thanks,
    Tom Lexington

    ReplyDelete
    Replies
    1. Hi Tom,

      Check total count and current index variable .. try logging them to debug the same..
      You can use Publish BS inside loop, there won't be any issue !

      Regards,
      Abhinav

      Delete
    2. Hello again.
      Thank you for ur replay. It really helped.
      Im facing these days other problem. I'd like to add transport header on Outbound Request in every loop iteration.
      Every iteration publish BS as i mentioned upper. This is queue BS. I can see in my logs result that headers have been added propperly for every iteration. But when I d like to pull them in PS JMSConsumer(get all headers is turned ON) there are no any headers which i have added. Have u ever faced this problem?

      I know its little offtop here, but have no idea where i should ask for it.

      Thank you again very much,
      Tom Lexington

      Delete
    3. Hi Tom,

      1. Try enabling Enabling Execution & Message Tracing - Full level under operational settings log for the business service and proxy service to trace at what point headers are falling apart.
      2. Disable your PS JMSConsumer for some time & monitor the queue message under weblogic console ( JMS Modules - Queues) to look for headers are they showing up there ..

      Hope it helps !

      Regards,
      Abhinav

      Delete
  5. this example help me a lot but i am facing one problem. pl give idea to resolve.
    line 1, column 22: {err}FORG0003: expected zero or one item, got two or more items

    using fn:data($LineCollection/ns1:Lines[xs:integer($Index)]/Item assinged to Xitem. If tested single item, working fine. if use mutliple items, got the above error.

    ReplyDelete
  6. Hi Rao,
    FORG0003 : fn:zero-or-one() was called with more than one item is functional error
    Check your request payload and xpath,there is error traversing xpath.

    Regards,
    Abhinav

    ReplyDelete
  7. Thank you Abhinav. i am not callling the function fn:zero-or-one. In For loop, i am assigning the value to another variable. pesudo code looks below

    For Each <> ..xpath in var <>
    index to totalcount
    Do
    {
    fn:data($LineCollection/ns1:Lines[xs:integer($Index)]/Item) to XYZ
    }

    ReplyDelete
  8. Hi Rao,
    1.
    As you mentioned .."If tested single item, working fine. if use mutliple items, got the above error."
    You are using Assign action inside for each loop, it will overwrite what was assigned to XItem, try using some other actions such as log action to debug the same and try logging XItem to see the different payload request passed. Do check whether total count var is getting populated or not

    2.
    fn:data($LineCollection/ns1:Lines[xs:integer($Index)]/Item) - check the expression if it is in conformation with request payload, as I can see 'Item' is not qualified


    ReplyDelete
  9. Hi Abhinav,
    I am using for-each loop in Proxy message flow.
    i am trying to use the index ($index) variable in the replace activity but getting an error saying
    [RouteNode1, Replace action] XPath expression validation failed: An error was reported compiling the XPath expression: XQuery exception: line 37, column 107: {err}XP0008 [{bea-err}XP0008a]: Variable "$index" used but not declared for expression:

    My replace action contains expression:

    Replace ./test/testItem[$index]/cost in variable body with $OriginalCost


    My payload contains multiple entries for testItem so i need to replace all cost element inside testItem with OriginalCost.

    Please guide me to achieve this.
    Thanks.

    ReplyDelete
  10. Hi,

    How we can use nested for each loop is it work same as if I have two for each loop then once inner loop complete with all data comes out ....then only outer loop will increment by 1 and again it come to inner loop and process same.

    Thanks,
    Nimish

    ReplyDelete