Monday, October 29, 2012

Resolving Invalid State of SOA Composite

Ever wondered why a SOA composite goes to invalid state when the SOA server starts up? No matter what you try - restarting the composite from within the fusion middleware control (EM console) or undeploying - nothing would work. Only a server restart "Might" rid you of the issue.

I am carefully using "Might" here because, the SOA composite under consideration might refer to a service which could be down when the composite was started. This happens because;

The SOA server doesn't know of the service dependencies that a SOA composite has.

For instance let us consider a SOA composite A referencing external services B, C & D deployed on the same server instance. Ideally, we would like to have a service startup order where the services B, C & D are started ahead of composite A.


But that is not the reality as there is no way to set the service startup priority on the SOA server. It wouldn't be a nice idea to weave this setting at the server level as well because, consider a cyclic dependency issue where composite A references composite B and vice versa which would be too complex & cause instability.

This is a classic case for any SOA environment and the issue here is because the concrete WSDL references are used in the SOA composite to connect with the external services.

Now the question is how do we resolve these service dependency issues?

Answer lies in leveraging the SOA infrastructure capability. If you look closely into any SOA composite (source code), there will be a set of common services that will be referenced from the metadata store (MDS);


<import namespace="http://xmlns.oracle.com/bpel/workflow/taskService"
          location="oramds:/soa/shared/workflow/TaskServiceInterface.wsdl"
          importType="wsdl"/>


These service definitions are stored in the MDS repository which is available all the time for the SOA services to reference provided the underlying DB is up & running. You can check this for yourself by establishing a SOA MDS repository connection from the JDeveloper resource palette.

Similarly, as a best practice you can store all the abstract WSDL definitions of the referenced services in the MDS repository & reference them in your SOA composite. This way whenever the server tries to start the services, irrespective of the service startup order, the SOA composite starts up successfully as it will always have the abstract WSDL reference - After all, at design/compile time, the only thing that a SOA composite requires is the abstract WSDL definition. Only at runtime does the composite would require a concrete WSDL to invoke the right service.

Now, how do we let the design & runtime environments know what service reference (abstract/concrete) to use?

After storing the referenced abstract WSDLs & XSDs in the MDS repository, make the following changes to effect this;

1. Update the import statements in your composite XML to refer the WSDL/XSDs from concrete references to abstract ones;

<import namespace="http://www.oracle.com/orderprocess"
location="oramds:/apps/orderprocess/common/orderprocess_submitorder.wsdl" importType="wsdl"/>


2. Update the service wsdl location to MDS abstract WSDL reference as the soa engine would only look at this element to look up & start the services;

<reference name="SubmitOrder_OrderProcess" ui:wsdlLocation="oramds:/apps/orderprocess/common/orderprocess_submitorder.wsdl">

Leave the WSDL URL in the binding layer intact (to refer to concrete WSDL) because at runtime, the bindings will be used to invoke the actual web service.

To read more about abstract & concrete WSDLs, I recommend you to read my previous blog post here

How to store these artifacts in MDS repository? Ways to do it along with step-by-step instructions in my next post. Here it is!

8 comments:

  1. Hi Sathya,

    We got a issue in production environment. One of our interface failed to load post server restart and went in to retired state. after bouncing the particular node on which the interface failed to load, it became running successfully. Please let me know what to do.

    Thanks,
    Swaroop

    ReplyDelete
    Replies
    1. Swaroop,

      For a proper debug we need more information. However, one possible reason could be that the DB is not up & running before the services are started (provided the MDS store is utilized for WSDL referencing)

      Delete
  2. Hi,
    1) If we import wsdl from mds,how it look likes ?
    2)If mds server is down ,what effects in imported wsdl,other artifacts ?how to handle this one ?

    ReplyDelete
    Replies
    1. Hi Venkat,

      The idea here is to solve the application service dependency within WebLogic. Hence storing & referencing WSDL from MDS (DB) is great option that architects recommend and consider.

      1) Not sure what you mean by how it "looks". You will refer to the WSDL (or any other artifact like XSD using the oramds:// protocol from your SOA composite
      2. If MDS is down, then it means your DB is down. MDS is a critical underlying component that must be running (DB running) for your SOA suite to be working as expected. In a production environment this must be ensured by administrators (DB started and running before starting WLS services)

      Delete
  3. Hi Sathya, thanks for this excellent blog. It is very informative.

    I have a question on the following line:


    I don't see this "reference" element in the composite source code(composite.xml) of my project. However, I do see the following:


    Will the "reference" element automatically show up while calling a external service or do I need to add this reference? Thanks

    ReplyDelete
  4. Thanks for the nice explanation ...it answered my question -Why we should store Abstract WSDL’s only in MDS....

    ReplyDelete
  5. Hi sathya,

    We are using below concrete wsdl in our composite but what would be its binding to concrete wsdl look like ? What is the URL location of the actual task service in oracle soa

    ReplyDelete
    Replies
    1. Manoj, I don't think I understand your question.

      Delete