Thursday, October 20, 2011

AIA Requester Process Fail to Deploy on Server Restart - Abstract WSDL Issue

I have seen many posts on this issue. People offered different solutions. Here is how I figured out my solution.

When an EBS is generated based on WSDL from Oracle MDS, it's very likely that your EBS will not have a locally associated WSDL or XSD (I figure if you choose to copy WSDL to local project folder, if that's an option in JDeveloper wizard, you may get a local duplicate of the WSDL from MDS).

After EBS is deployed, now you create a Web Service call to this EBS in your Requester process. However, since the EBS doesn't have an associated abstract WSDL on the deployment server (unlike other typical BPEL process), so your JDeveloper will treat the call as an external web service call, therefore, generate a "xxxRef.WSDL" for your EBS call. Also JDeveloper inserted two a few concrete WSDL references in the project. And two of these places really mattered for me, in order for my Requester process to auto deploy on server restart.

Here are the two places I had to change to make it work.

1.In composite WSDL I had to make this change (the high lighted wsdlLocation used to point to concrete WSDL)

    <reference ui:wsdlLocation="oramds:/apps/AIAMetaData/AIAComponents/EnterpriseBusinessServiceLibrary/Industry/Utilities/EBO/MeterReading/V1/UtilitiesMeterReadingEBSV1.wsdl" name="UtilitiesMeterReadingEBS">
        <interface.wsdl interface="http://xmlns.oracle.com/EnterpriseServices/Core/MeterReading/V1#wsdl.interface(UtilitiesMeterReadingEBS)" xmlns:ns="http://xmlns.oracle.com/sca/1.0"/>
        <binding.ws port="http://xmlns.oracle.com/EnterpriseServices/Core/MeterReading/V1#wsdl.endpoint(CreateMeterReadingEBS/UtilitiesMeterReadingEBS_pt)" location="http://soadev.example.com:7001/soa-infra/services/Foo/CreateMeterReadingEBS/CreateMeterReadingEBS?WSDL" xmlns:ns="http://xmlns.oracle.com/sca/1.0"/>

2. Inside "xxxRef.WSDL" where location used to point to concrete WSDL:

    <import namespace="http://xmlns.oracle.com/EnterpriseServices/Core/MeterReading/V1"
    location="oramds:/apps/AIAMetaData/AIAComponents/EnterpriseBusinessServiceLibrary/Industry/Utilities/EBO/MeterReading/V1/UtilitiesMeterReadingEBSV1.wsdl"/>


That's about it. Redeploy, and it worked for me.

Monday, October 17, 2011

implement BPEL with existing WSDL

It is generally straight forward to create a BPEL process (composite) with an existing WSDL. When the wizard prompts to select "synch/asynch" etc, move down the list and select existing WSDL. Notice that JDeveloper generates a wrapper WSDL for the existing WSDL.
If you view the WSDL of your deployed composite, you will see an "import" section in your WSDL that references the real WSDL.
A WSDL generally has one or more bindings defined, and one or more end points (service section) defined. The end points URL is likely not the same as your composite end points URL, since the existing WSDL obviously came from somewhere else. If you leave the endpoints unchanged, then it may potentially leads to big time confusion.

The reason is this. Even though the endpoints are incorrect, you can still deploy your composite, and if you test your composite from the "em" console, it actually works. However, if you try to invoke the composite web service from an external client, such as SOAP UI, a Java client or even from a browser (not the "em" console), then you will see your web service call will fail, because the endpoint URL is incorrect.

There are two ways to deal with this problem.

1) after deploying your composite, you can find out the true URL of your composite from the "em" console. You can update your WSDL with the correct URL.

2) the above solution ends up with hard coded endpoint URL, that's not ideal. The preferred way is to let SOA server decide the URL for you dynamically. To do that, go to the WSDL, comment out (or delete) the entire "Binding" and "Service" section. Now SOA server will treat the existing WSDL just like an abstract WSDL and fill in the binding and service section dynamically for you.

Saturday, October 15, 2011

Deployment Plan File not Taking Effect?

I suppose there can be many reasons that the deployment file plan does not work properly.

I ran into a perticular situtation where my deployment plan file won't take effect, so all my replacement strings have no effect. It baffled me for a long time. I accidentally figured out the reason today.

In my particular case, I have an AIA EBS process, which uses mediator to route services. So there is no XSD and no WSDL for the project. So the generated plan file has this section at the bottom:
   <wsdlAndSchema name="">
      <searchReplace>
         <search/>
         <replace/>
      </searchReplace>
   </wsdlAndSchema>
I think the empty "name" attribute renders the plan file invalid, therefore it won't take effect. I simply changed it to 
   <wsdlAndSchema name="NONE">
that did the trick for me. With that change, my plan file worked without problem.

Wednesday, October 12, 2011

oracle.tip.adapter.file.outbound.FileReadInteractionSpec class not found

For more information about file adapter, please refer to this document:
Oracle® Fusion Middleware
User's Guide for Technology Adapters
11g Release 1 (11.1.1)
E10231-02

A few weeks ago, I encountered this class not found error on "oracle.tip.adapter.file.outbound.FileReadInteractionSpec" while using JCA file adapter in SOA 11.1.1.5.

It turned out that Oracle just decided to move their class around a bit :(

I fixed my issue by editing the .jca file:

        <interaction-spec className="oracle.tip.adapter.file.outbound.FileIoInteractionSpec">
        <!--interaction-spec className="oracle.tip.adapter.file.outbound.FileReadInteractionSpec"-->
            <property name="SourcePhysicalDirectory" value="foo1"/>
            <property name="SourceFileName" value="bar1"/>
            <property name="TargetPhysicalDirectory" value="foo2"/>
            <property name="TargetFileName" value="bar2"/>
            <property name="Type" value="COPY"/>
        </interaction-spec>
Look closely, you can see they change the class to "oracle.tip.adapter.file.outbound.FileIoInteractionSpec".

Additionally, you can choose which of these parameters are used as defined here, or overwritten dynamically by the BPEL variables. The following example shows how to replace 3 parameters at run time, but using "TargetDirectory" from jca, although jca internally references it as "TargetPhysicalDirectory" (I guess that's called undocummented Oracle feature :)

         <invoke name="InvokeCopyFile" bpelx:invokeAsDetail="no"
                  inputVariable="Invoke_FileMove_InputVariable"
                  outputVariable="Invoke_FileMove_OutputVariable"
                  partnerLink="JcaCopyFile" portType="ns2:FileMove_ptt"
                  operation="FileMove">
            <bpelx:inputProperty name="jca.file.SourceDirectory"
                                 variable="sourceDirectory"/>
            <bpelx:inputProperty name="jca.file.SourceFileName"
                                 variable="sourceFileName"/>
          <!-- ### do not assign target directory, pick up from jca directly, so it can be ###
            <bpelx:inputProperty name="jca.file.TargetDirectory"
                                 variable="targetDirectory"/>
                                 -->
            <bpelx:inputProperty name="jca.file.TargetFileName"
                                 variable="targetFileName"/>
          </invoke>

2013-02-20 update:
with jdev 11.1.1.6 and bpel 2.0, here is the syntax:

        <invoke name="InvokeMoveOperation"
                partnerLink="moveFile2Error" portType="ns3:FileMove_ptt"
                operation="FileMove"
                inputVariable="InvokeMoveOperation_FileMove_InputVariable"
                outputVariable="InvokeMoveOperation_FileMove_OutputVariable"
                bpelx:invokeAsDetail="no">
          <bpelx:toProperties>
            <bpelx:toProperty name="jca.file.SourceDirectory" variable="sourceDirectory"/>
            <bpelx:toProperty name="jca.file.SourceFileName" variable="filename"/>
            <bpelx:toProperty name="jca.file.TargetDirectory" variable="targetDirectory"/>
             <bpelx:toProperty name="jca.file.TargetFileName" variable="filename"/>
          </bpelx:toProperties>
        
                </invoke>