Wednesday, April 6, 2011

RosettaNet Attachment Handling in Oracle B2B 11g

I saw few queries on OTN related to RosettaNet attachment handling in Oracle B2B 11g recently. And hence thought to blog about the same.

In this blog post we will see -

1. How to create attachment XML for RosettaNet?
2. Configuration required in Oracle B2B?
3. How to pass payload and attachment to Oracle B2B from SOA composite using JMS interface of B2B Adapter?
4. How to verify whether attchments are being passed correctly using EM console and B2B reports?

So let's start with creating an attachment XML for RosettaNet.

Section#1 Creating Attachment XML for RosettaNet :-

This process is same as what you follwed for B2B 10g. The attchment XML must adhere to following DTD -

<!ENTITY % common-attributes "id CDATA #IMPLIED" >
<!ELEMENT B2BAttachment (Attachment*)>
<!ELEMENT Attachment (#PCDATA) >
<!ATTLIST Attachment Type CDATA #REQUIRED
ID CDATA #REQUIRED
Encoding CDATA #REQUIRED
Description CDATA #IMPLIED
FileName CDATA #IMPLIED>

I created a XML based on above DTD which looks like -

<?xml version="1.0" encoding="UTF-8"?>
<B2BAttachment>
<Attachment ID="123456" Type="text/plain" Encoding="none" Description="Description">Fisrt Text Attachment</Attachment>
<Attachment ID="123457" Type="text/plain" Encoding="none" Description="Description">Second Test Attachment</Attachment>
<Attachment ID="123457" Type="application/pdf" Encoding="base64" Description="Description"
FileName="OrderBill.pdf">file:///C:/b2bfile/OS/attachment/out/OrderBill.pdf</Attachment>
</B2BAttachment>

As you can see, there are three attachments included in this attachment XML -

i) A text attchment with content "Fisrt Text Attachment"
ii) Another text attachment with content "Second Test Attachment"
iii) A binary attachment (PDF) which is stored in file system in file "C:/b2bfile/OS/attachment/out/OrderBill.pdf"

Make sure to add "Type" and "Encoding" attributes correctly for all the attachments. Here "Type" attribute refers to MIME type and "Encoding" attribute refers to Content-Transfer-Encoding. I saved this attachment XML to directory "C:/b2bfile/OS/attachment/out". From this directory, composite will read the attachment XML and populate the attachment header.



Section#2 Configuring Oracle B2B :-


First of all create RosettaNet agreement between the trading partners and deploy the agreement. I won't show the steps to create RosettaNet agreements. You may use RosettaNet sample as well. So the agreement which I deployed, looks like -



As you can see the agreement "RNIF_O_M_3A4_0200_PO_Agr" has two participants – OracleServices (Host TP) and MarketInc (Remote TP). OracleServices is sending a PIP 3A4 PurchaseOrderRequest to MarketInc using this agreement.

Now we need to configure Oracle B2B for attachments.

By default Oracle B2B supports following MIME types -

text/plain : image/jpeg: text/xml : application/xml : application/octet-stream : application/EDIFACT : application/EDI-X12 : application/jpg : application/gzip : application/x-gzip : application/pkcs7-signature

If you need support for any additional MIME type then you have to add it in Oracle B2B configuration using B2B Web Console. As we need support for "application/pdf" to send PDF as attachment, we will add it in Oracle B2B configuration. Login to Oracle B2B console, navigate to Administration --> Configuration and in "Miscellaneous" section add "application/pdf" in "Additional MIME Types" -



On same page, set the "Use JMS Queue as default" to "true" so that B2B starts polling default JMS queue (B2B_OUT_QUEUE) instaed of default AQ (IP_OUT_QUEUE) for messages.


If Oracle B2B is receiving the RN document with attchment then you need to add a property "b2b.AttachmentInboundDirectory" as desrcibed in user guide. This property will hold the absolute directory name where incoming attachments will be stored. Make sure to restart the B2B server(s) after adding this property.


Section#3 Creating SOA composite for passing attachment and payload to Oracle B2B :-


Now create a SOA composite to pass the message to Oracle B2B. Open Jdeveloper and first of all create a SOA application and inside that create a SOA project with empty composite.

Drag the File Adapter into "Exposed Services" section of composite and configure it for picking up 3A4 PurchaseOrderRequest from the local file system. Drag the B2B Adapter into "External Reference" section of composite and configure it by following below steps -

1. On Welcome screen click on "Next"
2. On Service Name screen provide the service name as "SendB2B" and click "Next"



 3. On "B2B Integration Type" screen, select "JMS"


4. On "Application Server Connection" screen select the Application Server connection you have created or create a new one. This connection should be created to AdminServer of B2B domain.



5.  On "Operation" screen, select send



6. On "Document Definition Handling" screen, just click on "Next"

7. On "Document Definition" screen, select the 3A4 PurchaseOrderRequest's Document Definition




8.  On "JMS Provider" screen select the "Oracle Weblogic JMS" from the drop-down against Oracle Enterprise Messaging Service (OEMS) option




9.  On "Service Connection" screen again select the Application Server Connection



10.  On "Produce Operation Parameters" screen, click on the browse button against "Destination Name" and select "B2B_OUT_QUEUE (queue)" under "SOAJMSModule" and click ok. Accept the deafult for other settings and click on "Next"





11. Click on "Finish" to generate the adapter configuration files


Now drag a BPEL process to Components section of composite and configure it as below -

Name – SendToB2B
Namespace – Accept the default
Template – Define Service Later




Now connect this BPEL process with File Adapter and B2B Adapter by dragging wires appropriately and your composite should look like below-





Now double-click on BPEL Process SendToB2B to configure it. Add a receive activity in main scope to receive the 3A4 PurchaseOrderRequest payload from File Adapter and add an invoke activity to invoke B2B adapter to send message to B2B. In between receive and invoke activity add a Assign activity to assign values to B2B required headers and attchment. Your BPEL process should look like -




In main scope add below variables of xsd:string type -


i) ToParty
ii) FromParty
iii) DocType
iv) DocTypeRevision
v) MsgType
vi) MsgId
vii) Attachment




Now edit the Assign activity of BPEL process and perform following copy operations to assign values to above variables -


1. Copy the input variable (ReceiveFile_Read_InputVariable) body content of BPEL process to output variable (InvokeSendB2B_Produce_Message_InputVariable) body content. This will assign the 3A4 PurchaseOrderRequest payload read by file adapter to B2B adapter payload.
2. Copy the expression oraext:generate-guid() to variable MsgId
3. Copy the expression 'MarketInc' to variable ToParty
4. Copy the expression 'OracleServices' to variable FromParty
5. Copy the expression 'Pip3A4PurchaseOrderRequest' to variable DocType
6. Copy the expression 'V02.00' to variable DocTypeRevision
7. Copy the expression '1' to variable MsgType
8. Copy the expression ora:getContentAsString(ora:doc('file:///C:/b2bfile/OS/attachment/out/attachment.xml')) to variable Attachment

In 8th copy operation, we are reading the content of attachment XML using ora:doc() function and then converting the XML to string using ora:getContentAsString() function



As the last step, we need to populate the JMS headers with the value of variables, we assigned above. Go to source of BPEL process and modify the invoke node as below -

<invoke name="InvokeSendB2B"
inputVariable="InvokeSendB2B_Produce_Message_InputVariable"
partnerLink="SendB2B" portType="ns2:Produce_Message_ptt"
operation="Produce_Message" bpelx:invokeAsDetail="no">
<bpelx:inputProperty name="jca.jms.JMSProperty.FROM_PARTY" variable="FromParty"/>
<bpelx:inputProperty name="jca.jms.JMSProperty.TO_PARTY" variable="ToParty"/>
<bpelx:inputProperty name="jca.jms.JMSProperty.DOCTYPE_NAME" variable="DocType"/>
<bpelx:inputProperty name="jca.jms.JMSProperty.DOCTYPE_REVISION" variable="DocTypeRevision"/>
<bpelx:inputProperty name="jca.jms.JMSProperty.MSG_TYPE" variable="MsgType"/>
<bpelx:inputProperty name="jca.jms.JMSProperty.MSG_ID" variable="MsgId"/>
<bpelx:inputProperty name="jca.jms.JMSProperty.ATTACHMENT" variable="Attachment"/>
</invoke>

You can see here that invoke node is populating the JMS properties required for processing in Oracle B2B with the values of the variables we declared.

Save your project and deploy it to the SOA server.


Section#4 Running a test and verifying configuration :-

Drop a 3A4 PurchaseOrderRequest into the directory where File Adapter is polling. Wait until the files gets deleted from that directory.

Now login to EM console and navigate to your composite. You must see a instance under "Recent Instances" section. Click on Instance ID and it should open up the Flow Trace. Click on "SendToB2B" component on Flow Trace to view it's Audit Trail. See the Assign Action Audit Trail and expand the payload under "Updated variable "Attachment"" (You will only able to see payload if Audit level is set to Development). It should show you the exact content as our attachment XML. Even you can see under InvokeSendB2B audit trail that headers are being populated with exact values. Make sure that content of header "jca.jms.JMSProperty.ATTACHMENT" is same as our attachment XML.




Now login to B2B console and go to Reports section. In Business Message Reports, expand the details of 3A4 PurchaseOrderRequest which has been sent to TP. Scroll down and click on the link against "Attachment" in Business Message Report details. It must show you exactly same content as out attachment XML -



Now to check whether attchments have been included in the message sent to TP, go to Wire Message Report and expand the details of 3A4 PurchaseOrderRequest which has been sent to TP. In details, click on the "Packed Message" link and scroll down. At the bottom, you must be able to see the attachments -




 You are done with sending Text and Binary attachments with RosettaNet message using Oracle B2B and composite with JMS interface.

8 comments:

  1. Hi,

    I found your site when i was googling.this site is pretty good.the screenshots had clearly explained the creation of soa composite.

    Oracle R12 Upgrade.

    ReplyDelete
  2. As stated earlier, You are doing amazing job by providing such useful information and that too through screeshots which made the programs more clear and better understandable.

    ReplyDelete
  3. Hello Anuj,
    I installed the latest Oracle SOA Suite 11g on Windows 7 64 bit with the Healthcare adapter and it installed but the b2bui shows installed but doesn't start and shows this error
    at java.security.AccessController.doPrivileged(Native Method)
    at oracle.tip.b2b.security.SecurityUtility.isB2BAdminUser(SecurityUtilit
    y.java:713)
    at oracle.soa.b2b.console.fastpath.security.UserManagement.checkB2BUserH
    asAdminRole(UserManagement.java:323)
    at oracle.soa.b2b.console.fastpath.security.UserManagement.checkB2BUserH
    asAdminRole(UserManagement.java:302)
    at oracle.soa.b2b.console.fastpath.util.LoginRedirectServlet.doPost(Logi
    nRedirectServlet.java:108)
    at oracle.soa.b2b.console.fastpath.util.LoginRedirectServlet.doGet(Login
    RedirectServlet.java:83)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run
    (StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecuri
    tyHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.jav
    a:301)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
    va:56)
    at oracle.adf.library.webapp.LibraryFilter.doFilter(LibraryFilter.java:1
    79)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
    va:56)
    at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:119)

    at java.security.AccessController.doPrivileged(Native Method)
    at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:31
    5)
    at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUt
    il.java:442)
    at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.jav
    a:103)
    at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:1
    71)
    at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:71)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
    va:56)
    at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:13
    9)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
    va:56)
    at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsF
    ilter.java:27)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.ja
    va:56)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationActio
    n.wrapRun(WebAppServletContext.java:3730)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationActio
    n.run(WebAppServletContext.java:3696)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(Authenticate
    dSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:
    120)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppS
    ervletContext.java:2273)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletC
    ontext.java:2179)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.j
    ava:1490)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:256)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:221)
    Caused by: oracle.security.jps.service.policystore.PolicyObjectNotFoundException
    : Application with name "b2bui" does not exist.
    at oracle.security.jps.internal.policystore.xml.XmlPolicyStore.unsync_ge
    tApplicationPolicy(XmlPolicyStore.java:704)
    at oracle.security.jps.internal.policystore.xml.XmlPolicyStore.getApplic
    ationPolicy(XmlPolicyStore.java:673)
    at oracle.tip.b2b.security.SecurityUtility.isB2BAdminUser_wrapper(Securi
    tyUtility.java:738)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)

    ReplyDelete
    Replies
    1. Fred,

      You may like to refer -

      http://anuj-dwivedi.blogspot.com/2011/02/b2b-consolesoa-composer-not-opening-up.html
      http://anuj-dwivedi.blogspot.com/2011/03/starting-weblogic-serverssoa-osb.html

      Delete
  4. Thanks a lot Anuj!
    The above link was very helpful and resolved my issue :-)
    Thanks again, Fred

    ReplyDelete
  5. Thanks Anuj for the above link.It resolved my issue.God bless you

    ReplyDelete
  6. Hi Anju, Can I use Just one B2B adapter on BPEL and send different documents like purchase order, invoice, status etc and then have B2B identify based on document type, partner etc?

    ReplyDelete
  7. Hi Anuj,

    It is a nice post, I am having one issue, I configured the file channel in parent trading partner , but while configuring agreement i am not able to see any file channel in drop down list, could you please suggest soultion to this problem?

    Kind Regards,
    Vinay Kumar

    ReplyDelete