How to - For Each Step

2,268 views
Skip to first unread message

Mike Rodriguez

unread,
Sep 10, 2009, 4:29:42 PM9/10/09
to Oracle Service Bus
Hey there, first of all I would like to let you know all, that I'm
brand new in this context of XQuery things. Besides, I'm learning at
the same time, how to work with the Oracle Service Bus, applying for
the SOA migration that we're pretending to reach.

So my main question in this time, would be how to use the "For Each"
step on the Message Flow at the Proxy service.

This is my situation.
I have to create a new message, gathering information from another
services. The situation in here is that the first request will send me
a sequence of items, and from that sequence I have to take one data,
to create a new request, building a new XML with it, so I can call out
another service, once I get the response from it, I have to gather
some information from it, and add it to the first main request XML.

So I guess I have to loop the sequence of items, and once I get into
one of the items, I should build the new XML and call out the service,
save the information in a variable, and paste that variable on the
main request.

But my main question in here is, does the For Each step, would loop
the items that I'm having for the new XML?

If it's correct my thought, then How to manipulate the step.
On the step fields I have the follow...
For Each Variable <- I guess this one will be the one that every loop
value would be assigned to...
XPath <- The Xpath expression that I want point for the loop in this
case, on the XML element that I wan to iterate
In Variable <- The variable that contains the information to iterate,
the one that has my XML response (in my case)

So inside the For Each I want to assign the values of the "For Each
Variable" (the container of the item's loop) to another variable, and
study (modify it) in some other steps.

So... If I'm right, why this is failing to me!!?!?!
I can send (whoever that answers me) an email with my response, and
the explanation of how am I doing this...

Otherwise if I'm wrong on this please help me out!
How could I do what I need to do??

Thank you so much for any of your answers!
What a great idea to have a group of this in google!

Have a great day all of you!

Regards,
Mike

Jeff

unread,
Sep 13, 2009, 5:35:28 PM9/13/09
to Oracle Service Bus
Sorry for the delay in getting back to you. My son got married on
Saturday and things have been a bit hectic.

I want to make sure that I understand your question fully. If I do,
then I envision a single proxy service that (for example) takes a
postal code and returns a list of all customers in that postal code
and their product history. The proxy service then needs to make calls
to two business services. The first business service would take the
postal code and return a list of customers. The proxy service then
needs to iterate over that list of customers, and make a subsequent
call for each customer to a business service like: getCustomerProducts
() that returns a list of products for a specific customer. Then the
proxy service needs to put all of that information into the correct
return value.

So the proxy service would have an operation with the following
signature:

getCustomersAndProductList(String postalCode) : CustomerProductList

Where a CustomerProductList would look something like:
<CustomerProductList>
<Customer id=123" name="Smith, John">
<Product id="475" name="Color TV" />
<Product id="576" name="Digital Camera" />
</Customer>
<Customer id=144" name="Ball, Lucille">
<Product id="475" name="Color TV" />
<Product id="999" name="iPod" />
</Customer>
<Customer id=567" name="Doe, Harry">
<Product id="475" name="Color TV" />
<Product id="576" name="Digital Camera" />
</Customer>
</CustomerProductList>

The first business service would have a signature like:

getCustomerListByPostalCode(String postalCode) : CustomerList

Where a CustomerList would look like:
<CustomerList>
<Customer id=123" name="Smith, John" />
<Customer id=144" name="Ball, Lucille" />
<Customer id=567" name="Doe, Harry" />
</CustomerProductList>

And the second business service would have an operation like:

getCustomerProducts(int CustomerID) : ProductList

and a ProductList would look like:

<ProductList>
<Product id="475" name="Color TV" />
<Product id="999" name="iPod" />
</ProductList>

If that is correct, let me know and I'll see what I can do to get a
sample working. Thanks!

- Jeff

Mike Rodriguez

unread,
Sep 14, 2009, 11:49:39 AM9/14/09
to Oracle Service Bus
Hey Jeff!!

First of all, CONGRATULATIONS!!
As we say in Mexico, now your son it's entirely a man! Hehehe no
offences it's just a nice way to say "The end of an age and the
beginning of a new one".

Now reading your inputs for the correct understanding about my
problem...
I have to say "Yes sir" you got the information.

If you want we can base your help (wich I appreciate really much btw)
on your example, anyway I'll give you some information based on the
reality that we have in here...

The first method to be called it's based on this signature
searchCustomers()
And well the parameters are many, that's why I'm adding the XML
<del:searchCustomers>
<Filter>
<java:City></java:City>
<java:Colonia></java:Colonia>
<java:Company></java:Company>
<java:Country></java:Country>
<java:Email></java:Email>
<java:FavcId></java:FavcId>
<java:LastName>SMITH</java:LastName>
<java:LastName2>CRAWL</java:LastName2>
<!--Zero or more repetitions:-->
<java:LoyaltyList>
<java:LoyaltyId></java:LoyaltyId>
</java:LoyaltyList>
<java:Names>SEAN MICHAEL</java:Names>
<java:Phone></java:Phone>
<java:Rfc></java:Rfc>
<java:State></java:State>
<java:Street></java:Street>
<java:SystemId>vartsjmSystem</java:SystemId>
<java:UserId>vartsjm</java:UserId>
<java:ZipCode></java:ZipCode>
</Filter>
</del:searchCustomers>

Ok so first of all I need to send this request, to a business service.
Then the business service will search the customers that might have
relation with that name.

And it will reply with an XML like this
<n1:result xmlns:n1="http://www.innovativesystems.com">
<n2:customers xsi:type="n2:ArrayOfCustomerVO"
xmlns:n2="java:com.innovativesystems.delpack">
<n2:CustomerVO>
<n2:customerAddress
xsi:type="n3:ArrayOfCustomerAddressVO"
xmlns:n3="java:com.innovativesystems.delpack.values">
<n3:CustomerAddressVO>
<n3:addressId>9036022</n3:addressId>
<n3:addressType>HOM</n3:addressType>
<n3:city>CIUDAD DE MEXICO</n3:city>
<n3:colonia>GRANJAS COAPA</n3:colonia>
<n3:country>MX</n3:country>
<n3:state>DF</n3:state>
<n3:street>SAUZALES 39 EDIF D 102 TLALPAN
TLALPAN</n3:street>
<n3:zipCode>14330</n3:zipCode>
</n3:CustomerAddressVO>
</n2:customerAddress>
<n2:ident>9362821</n2:ident>
<n2:lastName>SMITH</n2:lastName>
<n2:lastName2>JHONS</n2:lastName2>
<n2:names>SEAN MICHAEL</n2:names>
</n2:CustomerVO>
<n2:CustomerVO>
<n2:customerAddress
xsi:type="n4:ArrayOfCustomerAddressVO"
xmlns:n4="java:com.innovativesystems.delpack.values">
<n4:CustomerAddressVO>
<n4:addressId>6903602</n4:addressId>
<n4:addressType>BUS</n4:addressType>
<n4:city>D.F.</n4:city>
<n4:colonia>LOMAS DE CHAPULTEPEC</n4:colonia>
<n4:country>MX</n4:country>
<n4:state>DF</n4:state>
<n4:street>REFORMA 155 MEXICO</n4:street>
<n4:zipCode>11000</n4:zipCode>
</n4:CustomerAddressVO>
</n2:customerAddress>
<n2:ident>8155723</n2:ident>
<n2:lastName>SMITH</n2:lastName>
<n2:lastName2>JAMES</n2:lastName2>
<n2:names>SEAN MICHAEL</n2:names>
</n2:CustomerVO>
</n2:customers>
</n1:result>

So as you can see in here, I have two options.
The parameter that I'm interested in it's the

<n2:ident>8155723</n2:ident>

That will be the key to call the next Business Service. I have to add
that value to another call, for another method "customerProfile" wich
receives the follow XML
<del:customerProfile>
<del:customerProfileRequest>
<java:blockInfo>
<!--Zero or more repetitions:-->
<java1:string>LASTEMAIL</java1:string>
<java1:string>LOY</java1:string>
</java:blockInfo>
<java:ident>9362821</java:ident>
<java:hotelCode></java:hotelCode>
<java:systemId>PEB</java:systemId>
<java:userId>vartsjm</java:userId>
</del:customerProfileRequest>
</del:customerProfile>

So I need to create a call (an XML) per ident gathered on the
searchCustomers response, and call customerProfile.
Follow the flow, I got the first "ident" value, I create this new
request, I call the service with this method, and I'll get the follow
response.

<m:customerProfileResponse xmlns:m="http://
www.innovativesystems.com">
<n1:result xmlns:n1="http://www.innovativesystems.com/"
xmlns:n2="java:com.innovativesystems.delpack">
<n2:bas/>
<n2:comments/>
<n2:companies/>
<n2:dem/>
<n2:ident>9362821</n6:ident>
<n2:gvalue/>
<n2:hisAdd/>
<n2:hisEmail/>
<n2:hisPhone/>
<n2:hisRFC/>
<n2:histStay/>
<n2:lastAdd/>
<n2:lastEmail>
<n3:EMail
xmlns:n3="java:com.innovativesystems.delphospack.values">sean.m...@gmail.com</
n3:EMail>
<n3:type>P</n3:type>
</n2:lastEmail>
<n2:lastPhone/>
<n3:loy xsi:type="n3:ArrayOfLoyaltyItem">
<n3:LoyaltyItem>
<n3:level>DR</n3:level>
<n3:programNumber>62T25330</n3:programNumber>
<n3:programType>DR</n3:programType>
</n3:LoyaltyItem>
<n3:LoyaltyItem>
<n3:level>DR</n3:level>
<n3:programNumber>01E74532</n3:programNumber>
<n3:programType>DR</n3:programType>
</n3:LoyaltyItem>
</n3:loy>
<n2:pref/>
<n2:reservations/>
</n1:result>
</m:customerProfileResponse>

Ok now with this we're almost a the end... But from this response, I
need information.
The tags "lastEmail" and it's descendents, the tag "loy" and it's
descendents.

I need to add that information to another XML, based on the first
response from searchCustomer.
It should end in something like this

<n1:result xmlns:n1="http://www.innovativesystems.com">
<n2:customers xsi:type="n2:ArrayOfCustomerVO"
xmlns:n2="java:com.innovativesystems.delpack">
<n2:CustomerVO>
<n2:customerAddress
xsi:type="n3:ArrayOfCustomerAddressVO"
xmlns:n3="java:com.innovativesystems.delpack.values">
<n3:CustomerAddressVO>
<n3:addressId>9036022</n3:addressId>
<n3:addressType>HOM</n3:addressType>
<n3:city>CIUDAD DE MEXICO</n3:city>
<n3:colonia>GRANJAS COAPA</n3:colonia>
<n3:country>MX</n3:country>
<n3:state>DF</n3:state>
<n3:street>SAUZALES 39 EDIF D 102 TLALPAN
TLALPAN</n3:street>
<n3:zipCode>14330</n3:zipCode>
</n3:CustomerAddressVO>
</n2:customerAddress>
<n2:lastEmail>
<n4:EMail>sean.m...@gmail.com</n4:EMail>
<n4:type>P</n4:type>
</n2:lastEmail>
<n4:loy xsi:type="n4:ArrayOfLoyaltyItem">
<n4:LoyaltyItem>
<n4:level>DR</n4:level>
<n4:programNumber>62T25330</n4:programNumber>
<n4:programType>DR</n4:programType>
</n4:LoyaltyItem>
<n4:LoyaltyItem>
<n4:level>DR</n4:level>
<n4:programNumber>01E74532</n4:programNumber>
<n4:programType>DR</n4:programType>
</n4:LoyaltyItem>
</n4:loy>
<n2:ident>9362821</n2:ident>
<n2:lastName>SMITH</n2:lastName>
<n2:lastName2>JHONS</n2:lastName2>
<n2:names>SEAN MICHAEL</n2:names>
</n2:CustomerVO>
<n2:CustomerVO>
<n2:customerAddress
xsi:type="n4:ArrayOfCustomerAddressVO"
xmlns:n4="java:com.innovativesystems.delpack.values">
<n4:CustomerAddressVO>
<n4:addressId>6903602</n4:addressId>
<n4:addressType>BUS</n4:addressType>
<n4:city>D.F.</n4:city>
<n4:colonia>LOMAS DE CHAPULTEPEC</n4:colonia>
<n4:country>MX</n4:country>
<n4:state>DF</n4:state>
<n4:street>REFORMA 155 MEXICO</n4:street>
<n4:zipCode>11000</n4:zipCode>
</n4:CustomerAddressVO>
</n2:customerAddress>
<n2:ident>8155723</n2:ident>
<n2:lastName>SMITH</n2:lastName>
<n2:lastName2>JAMES</n2:lastName2>
<n2:names>SEAN MICHAEL</n2:names>
</n2:CustomerVO>
</n2:customers>
</n1:result>

And the next iteration will add the information about the email and
the loy for the next ident.

Soooo....
That's the whole proxy work.
And to be honest, I have the idea of how to do it technically... I
just need to understand how would OSB woul do it.

I really appreciate this help!
I'll be waiting on you, in the meanwhile, I'll try to find information
on how to work with the For Each step.

Once again, congratulations for your son and hope you had a awesome
weekend!

Thanks and best Regards,

Mike

Jeff

unread,
Sep 14, 2009, 12:29:36 PM9/14/09
to Oracle Service Bus
Thanks Mike. Your sample is using the "nesting" of calls at two
levels, whereas my sample shows a single level of nesting. It seems to
me that the core of the challenge here is to create the XQuery that
will iterate over a result set and then make multiple calls out to
another business service. Once we are able to demonstrate that
pattern, the number of times it is used in a nested fashion is up to
the author of the proxy service.

I'll develop a sample using my original XML simply because I plan on
posting this on my blog so that other people can also see the
solution. I also have a second person that wrote to me asking about
how to create a converter class for EJBs from within OSB, and I was
going to provide both solutions in a single project (I'm lazy like
that ;) )

This may take me a couple of days as I work it into my daily workload.
I may take a short cut and see if I can get your question answered
first simply because there are fewer moving parts (it can all be
represented using proxy services in OSB). I'll post a solution as soon
as I can.

- Jeff

Mike Rodriguez

unread,
Sep 14, 2009, 1:01:34 PM9/14/09
to Oracle Service Bus
Hey Jeff,

Well first of all... is this the blog where you'll post all of your
answers? -> http://blogs.oracle.com/jeffdavies/


Now I understand the nesting calls that I'm using in here, and believe
me, I'll be waiting on you so I can completely understand the
situation and the solution on this.

To be honest I don't have a clear idea of how to solve this.
I was thinking on save the first response (from searchCustomer) in a
variable, then make a call per ident on it to the second service (this
will be the first main question, how could I do this "many calls" in
order one by one, with steps, could that be done by a "For Each" step?
is there an Xquery function to do this? is there a way to call out a
service with XQuery?) then save the answer into a variable, paste the
values that I'm interested on the first response variable, using an
Xquery FLOWR expression, using the ident on the WHERE clausule... and
so on until there were no more ident's to be iterated.

I understand that you're really busy...
Just please give me some light on how to explode the OSB.

I'm reading right now your blog. I did read your book a couple of
month ago, btw, thanks for that great book it helped me A LOT.

Have a great day!
Regards,
Mike

PS - Sorry for being so annoying.. :)

Jeff

unread,
Sep 15, 2009, 2:43:50 AM9/15/09
to Oracle Service Bus
Yep, that's my blog at Oracle. I have good news in that I was able to
get some sample code working on this today. In the morning I'll post
to my blog with more details and the sample code. What you are asking
about is the foundation of service aggregation, so I'm sure alot of
folks will benefit from your question. Using a FLOWR expression wont
really do the trick because you cant do everything you need from
within the XQuery script. The solution is to use the For-Next action,
married to an XQuery script. It will make sense when I post to
solution along with the sample code in the morning.

If you have any trouble customizing it to meet your specific scenario,
let me know. Until tomorrow!

- Jeff

Mike Rodriguez

unread,
Sep 15, 2009, 9:56:53 AM9/15/09
to Oracle Service Bus
Hey Jeff!

Pretty cool!
I'll be waiting on you!! =)

Thank you for all the help and explanations!

Once I have had read your post, and tried some things on my project,
I'll feedback you, or ask you for a little more help...

Thank you so much for answering!
I'll be checking your blog.

Hope you had a great night.

Let's rock this OSB!
_
Mike

Jeff

unread,
Sep 15, 2009, 2:07:10 PM9/15/09
to Oracle Service Bus
Ok Mike, the sample code is up with my latest blog that describes the
solution in detail. Check out http://blogs.oracle.com/jeffdavies to
see the details. Let me know if you have any questions.

- Jeff

Mike Rodriguez

unread,
Sep 15, 2009, 5:06:01 PM9/15/09
to Oracle Service Bus
Jeff,

Well really helpful. Very well explained.
Right now I'm trying to import it (your project) to my workspace, so I
can start getting in deep of the descriptions that you're describing
on the post.


So, I might be asking you little details of it in a while.
Here in Mexico, tomorrow it's a holiday but for sure on Thursday I'll
be writing again.

But so far, for today I'm begging for a little help.
I started my own project once again so I can apply the things that I
would read on your post, to my project.
But suddenly (because here at the company the IT team are working on
some migrations) those services that used to work before (for the
call-outs) are not any longer, and well I'm not any sure about why...

They said that they changed the services from JAX-RPC to JAX-WS 2.1
Which btw I'm not sure how could that deactivate or unconfigure my
actual proxy services and their call-outs.

Because right now they only expose an error on the "problems" that
says as follows
"The configuration does not correspond to a SOAP RPC WSDL. The WSDL of
the target service may have changed making the configuration out of
sync."

Please help me out, why could this be happening, how did that happen?
It's ITs fault? Hehehe

I'm totally lost in here, I don't even know how could I solve this
issues.
I'll be really thankful with your feedback

Thanks in advance
And once again thank you so much, even for the reference in your post
"A reader of my book asked about using OSB to aggregate services"

Have a great day and thank you!

_
Mike

Jeff

unread,
Sep 15, 2009, 5:22:17 PM9/15/09
to Oracle Service Bus
Hi Mike,
If they changed the service from JAX-RPC to JAX WS its very likely
that their WSDL changed too. I would also check to see if they might
even have changed servers or URIs for the services. Get the updated
WSDL for their services, create a business service that calls it and
test to make sure the buisness service is working before you start
trouble-shooting your proxy service. If nothing changed on your side
and something changed on their side, odds are they changed something
important in the service definition ;)

By the way, I didn't use your name in the post just in case you wanted
to remain anonymous. Of course, you posted you name here, so you
probably dont really care about that. I just didn't think it through.

- Jeff

Mike Rodriguez

unread,
Sep 17, 2009, 6:30:47 PM9/17/09
to Oracle Service Bus
Hey Jeff!!

Great news from here!!
You know what I made it!! I just finished my proxy service with all
the details that I needed in there, I also didn't use an XQuery
element, I scripted on the Assign's Expression tag because it was
relatively easy and direct.

Anyway, at the end the work it's fully done and quite fast.
So far, and day by day I'm learning more and more about this great
tool.

By the way, more questions will come, as we move forward on the
migration...

I remember I read on your book that OSB can be straight connected to
Tuxedo. But I'm not sure, I'm thinking on that because the next
service that I will need to create, will be that one, I must
communicate with Tuxedo, the hypothesis it's that it will provide me
an XML and I'll have to take some information from it, and create a
SQL Query, throw it to the database and create a new XML from the
resultset that I could get.
Sounds quite nice, isn't?

Anyway I can't leave this comment, without thanking you once again for
your time and your post in your blog.

Was REALLY helpful!!

I'll bomb you later with some other direct questions.
Because so far the Tuxedo thing it's just an idea...

Carpe Diem!!

Regards!
Reply all
Reply to author
Forward
0 new messages