Showing posts with label SOA 12c. Show all posts
Showing posts with label SOA 12c. Show all posts

Friday, September 28, 2018

Working with an SOA MDS: using abstract WSDL's

The WSDL plays an essential role in defining a web service. Besides describing the structure of the SOAP message, it often contains additional implementation details about the location of the service by having the endpoint described in the service tag. This is what we call a concrete WSDL and it may look as follows:


When we populate our MDS we want it to contain abstract WSDL’s that do not contain these implementation details. This way we take away the direct dependencies between services. It means that the actual referenced services don’t need to be deployed and active in order for our SOA composite to be compiled. It also means we keep our MDS clean in the sense that it does not have any references to other environments.

The way of working with abstract WSDL’s in jDeveloper differs slightly compared to concrete WSDL’s. When creating a reference to a service, you would typically select the WSDL needed from the MDS, as below:


In contrary to using a concrete WSDL you will now get the following warning to notify you the WSDL doesn’t contain any bindings. This is perfectly fine and we can just continue by clicking ‘Yes’.


If you now check the composite.xml, you will notice that no binding details were provided in the binding.ws tag.


We need to provide them manually by looking up the concrete WSDL within the development environment. The format is as follows for the port details:
<Namespace service>#wsdl.endpoint(Service name/Port name)


In our case it becomes:
http://www.stellent.com/FolderInfo/#wsdl.endpoint(FolderInfo/FolderInfoSoap)

In the location attribute we provide the endpoint. Altogether your service reference should look like this:


When we create a deployment for installation on a different environment we will create a deployment plan which contains the endpoints of the target environment. This will overwrite the endpoint we provided in the location attribute of the composite.xml.

Wednesday, April 25, 2018

Error calling an external service from composite: oracle.fabric.common.FabricInvocationException: Unable to find the WSDL service defined for service name


I want to share an error that has kept me busy for a bit. I could not find the cause of the error easily, but as always with troubleshooting: afterwards it all made sense.

So I had an SOA composite calling an external service. Invoking this service resulted in the error below. This happened after deploying the service in my test environment.

      <bpelFault>
        <faultType>0</faultType>
         <remoteFault xmlns="http://schemas.oracle.com/bpel/extension">
           <part name="summary">
              <summary>oracle.fabric.common.FabricInvocationException: Unable to find the WSDL service defined for service name {http://www.stellent.com/GetCaseNumberWCC/}GetCaseNumberWCC.  Please make sure that the port attribute for the binding defined in the composite file is correct by checking the namespace and service name in the #wsdl.endpoint element. In addition, check that the WSDL associated with the binding namespace is imported and currently reachable (check the import nodes at the top of the composite file). Finally, validate any HTTP proxy settings for the server.</summary>
           </part>
            <part name="code">
              <code>null</code>
            </part>
           <part name="detail">
              <detail>Unable to find the WSDL service defined for service name {http://www.stellent.com/GetCaseNumberWCC/}GetCaseNumberWCC.  Please make sure that the port attribute for the binding defined in the composite file is correct by checking the namespace and service name in the #wsdl.endpoint element. In addition, check that the WSDL associated with the binding namespace is imported and currently reachable (check the import nodes at the top of the composite file). Finally, validate any HTTP proxy settings for the server.</detail>
           </part>
         </remoteFault>
       </bpelFault>

It didn’t make sense to me as the external service was up and running and I could call it from SoapUI. The endpoint looked good and I could view the WSDL in my browser. I checked my composite as the text in the exception suggested, but it looked fine and in accordance with my WSDL:



The SOA service worked fine in my development environment but failed in my test environment. It lead me to the configuration plan I generated using jDeveloper. In the reference part I changed the location to my test environment, the rest I had left untouched.



When I viewed the WSDL in my browser (http://tstenvironment:80/default/WCC/Services/GetCaseNumberWcc/V1?wsdl) I saw the following:



Apparently the service and port names were different in OSB, so it made sense that the port attribute wasn’t updated correctly in the configuration plan. This caused the invocation of the service to throw an error about the service name. I corrected the configuration plan (see yellow underlined text), redeployed the composite and it resolved my problem!





In my case the error was caused by a wrong service name and port generated in the configuration file. But while looking for a solution I saw that this error could also be caused by using version specific abstract WSDL’s or the WSDL location in your composite.xml pointing to the wrong destination (for example your local machine). If you’re using an MDS make sure it is in sync with the target MDS.

Friday, February 16, 2018

A simple example of the for-each functionality

A component that I frequently use in my BPEL processes is the for-each component. It's an easy feature to loop through data, assert data to a variable and do multiple service calls. I will show you a simple example of how the for-each component can be used. Suppose we retrieve a list of folder ID's and for each of these we will do a service call which returns additional data about those folders. This data will be asserted altogether so we can do some data transformation later in our BPEL process.

So this is the list of folders we are working with and is stored in a variable. We want to call a service that retrieves additional data about the FOLDERGUIDs.
 
The for-each part of our BPEL process looks like this:

After dragging the for-each component to our canvas we can edit the conditions. We can give our for-each loop a name. In this case I just called it 'ForEach'. The for-each has a counter variable that keeps track of the index of loops. Here I named the counter variable 'ForEachCounter'.
Next we define the start and final value of our counter. Here the counter starts with index 1. The final value of the counter is determined by the number of FOLDERGUIDs I have in my list. That's why I used the count function that will calculate the occurences of FOLDERGUIDS in the variable that holds the list.
In the tab 'Completion' you could enter an expression that will determine when to exit the for-each loop. For example when a certain condition is met it would not be necessary anymore to proceed with the loop.
Next we want to provide the element FOLDERGUID from our list to be the input parameter to call the service that retrieves additional data about our folders. When we assign the FOLDERGUID as the input parameter we have to keep the counter in mind that keeps track of the position of our FOLDERGUIDS. That's why we put [$ForEachCounter] in our expression.
The data returned could be asserted to a new variable for further transformation.

And that's it basically! Here I have demonstrated a common use of the for-each function in BPEL.