OSB development

OSB is an abbreviation for Oracle Service Bus and is the entry point for others consuming your services. Developing on the OSB layer is mostly straight forward once you get to know the different components available for you to use. These components are added through a drag and drop type interface, and offer configurable properties to define behavior, variables etc.

An OSB service can be very simple or complex depending on the use case. It can call other services internally on the OSB, consume external services, persist data in a DB, write content to a file, call processes in the SOA layer (BPELs and BPMs) and much more. For this introduction to OSB development we are going to create a simple service that receives a request and give a simple response. Persisting the data will be covered in the next tutorial.

Creating application and project

If you have recently joined a team where they have been developing for some time, then you will most likely have an existing application. If not create a new application first:

  • File->New->Application
  • Choose Service Bus Application from the gallery
  • Choose an appropriate name and location, and click Finish

Then we need to add a project to that application, which eventually will become a service that others can consume when it gets deployed. Follow the same steps as above, but choose Project instead of Application, and choose Service Bus Project (Under Service Bus Tier).

In the project I am working on we use the following naming pattern for our services:
projectname.service.groupindicator.nameOfTheServiceInCamelCase

Example
projectx.service.pro.productStorageService

After the project is created I always start by adding subfolders to separate the different components I am going to use. Good organization of code makes your life easier. The setup I am used to is (You will see why in a bit):

->ProjectFolder (Created when creating the project)
    ->BusinessServices
    ->Pipelines
    ->ProxyServices
    ->Resources
        ->Transformations
        ->WSDLs
        ->XSDs

You'll notice that when you created the project there are two files added. A pom.xml and a file with the same name of the project (file ending .jpr if you look in a browser). We are not going to bother about the pom file for now, so just go ahead and open the other one. The view presented to you now is a blank slate which you are going to fill with one or more proxy services, one or more pipelines and most likely a business service.

Creating a WSDL, XSD and Proxy

A proxy service is the entry point to your service, and is what is exposed to the outside world. There are several types of protocols to choose from when setting up a proxy service, and the most commonly used is HTTP. When creating a new HTTP proxy you will be asked to provide a WSDL file that defines which service operations are available. So the next step is to add a WSDL and an XSD to the project. Hopefully you’ll have a design team that will provide you with WSDL’s and XSD’s, otherwise you need to create your own.

Unfortunately I don't have my own design team for this tutorial, so we will go ahead with creating our own XSD and WSDL file now. Right click on your XSD folder and choose New->XML Schema. Name it ProductStorageService.xsd, choose the Resources->XSDs folder if not already selected. Then fill in the Target Namespace with:
urn:no:projectx:pro:wsdl:productstorageservice:v1

On the bottom of the view click on Source, then replace the content automatically created with the following:

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:no:projectx:pro:wsdl:productstorageservice:v1"
            targetNamespace="urn:no:projectx:pro:wsdl:productstorageservice:v1" elementFormDefault="qualified">
    <xsd:element name="createProductRequest">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="ProductInformation" type="ProductInformation"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="createProductResponse">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="ProductId" type="xsd:integer"/>
                <xsd:element name="Message" type="xsd:string"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:complexType name="ProductInformation">
        <xsd:sequence>
            <xsd:element name="ProductName" minOccurs="1" maxOccurs="1" type="xsd:string"/>
            <xsd:element name="Description" minOccurs="0" maxOccurs="1" type="xsd:string"/>
            <xsd:element name="Price" minOccurs="1" maxOccurs="1" type="xsd:decimal"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Next we need to create our WSDL file. So right click on your WSDLs folder and choose New->SOA WSDL document. Then fill in the required information. Use the same File name and Target namespace as for your XSD. For the rest:

  • Binding: ProductStorageServiceBinding
  • Port type: ProductStorageServicePortType
  • Operation: createProduct
  • Interface Type: Synchronous Interface

For the input and output fields, click the green + sign and fill in (We'll leave Fault empty for now):

  • Part Name: createProductRequest (input) / createProductResponse (output)
  • URL: click the search tool and locate the ProductStorageService.xsd file and choose the request object for Input and response object for Output
  • Click Finish

In the file that opens, click on Source and replace:

name="requestMessage" with name="createProductRequestMessage"
name="replyMessage" with name="createProductResponseMessage"
message="tns:requestMessage" with message="tns:createProductRequestMessage"
message="tns:replyMessage" with message="tns:createProductResponseMessage"

This is so that we can have a more unique name if we wish to add more operations later on with different request and response message types.

Now we are ready to create our first proxy, so go back to the project file you opened earlier. In the view just right click in the Proxy Services lane and choose Transport->HTTP. Then follow these steps:

  • Service name should be ProductStorageService_HTTP.
  • Make sure you change location to point to the ProxyServices folder.
  • Leave Transport as is
  • Uncheck the Generate Pipeline check box.
  • Then you click next and select the WSDL radio button, and click on the icon with the @ sign. (If JDeveloper at this point shows an Unexpected Error window, just choose Continue and check Remember settings..)
  • Locate the WSDL file we just created and click OK.
  • Then click Next and Finish.

The reason for appending _HTTP to the file we just created is just to have an indication of what kind of transport protocol this service is. Now we are ready to create our first pipeline.

Creating pipeline

A pipeline is where you start processing the data being sent into your service and is ideally bound to one specific service operation. In our current example we only have one service operation, which we are going to be working with now.

To start you should right click in the Pipelines / Split joins lane, and choose Insert->Pipeline. Then start filling in:

  • Service name: createProduct_OP
  • Change location so that it is pointing to your Pipelines folder
  • Click next
  • Again we need to select the WSDL file
  • Uncheck Expose as a Proxy Service check box.
  • Click Finish

Now from the arrow on the proxy, click and drag to connect with the pipeline and save. Then the red cross, indicating an error, should disappear from the proxy. Then we can start working on the pipeline. Just double click on the green thing in your view to open the pipeline view.

Right now there is nothing in here. So from the Components view to your right, find the component called Pipeline Pair and drag it in. The view should then indicate where this component can be dropped. Now you should have a Request and Response Pipeline in your view. Nothing much is happening yet, so we need to add some more components.

It is always a good idea to validate the messages coming in to make sure that the data conforms to the XSD, and we are not receiving any unwanted data that could cause an error situation. So in the Components view, scroll down until you find the Validate component and drag it into Stage1 in the Request pipeline. I also recommend that you rename Stage1 into ValidateRequest (or something similar). This makes it easier to recognize the different steps in a flow when testing it later.

Again you will see that there are some red markings in the view. So we need to configure the component to resolve this. In the bottom view you should see a tab called Validate - Properties (Side note: Whenever you click on a component in the view, you will be able to configure the various properties for that component here). Here we need to fill in some information:

  • Location: body
  • Click the "calculator" icon with the text fx below the first dropdown
  • In the window that opens just enter ./*[1] in the Expression window and click OK. ./*[1] is an Xpath expression to select the first element inside the Soap body tag.
  • Schema: Choose static, then click on the search icon.
  • Locate the XSD by expanding Application Schema files etc.
  • Choose the createProductRequest object
  • Click OK

If you adhered to my earlier advice about reading up on SOAP, you should know why we chose to choose Location->Body for our validation. If not, then the short explanation is that this is where the content of the incoming request is found. You'll see what I mean when we are going to test this later after we have deployed it to the local server.

Since we don't have anywhere else to pass the data coming in yet (will be covered in the next tutorial), there are only three more components and a transformation file we are going to add before testing the service.

Lets start by creating a transformation file for the response. Right click on the transformations folder. Select New->XQuery File ver 1.0... Then fill in:

  • File Name: XQ_Create_createProductResponse.xqy
  • Make sure Location is pointing to the Resources->Transformations folder
  • In Sources click on the green arrow
  • In the new window fill in Name: id
  • Then click the pencil icon to open a new window
  • Click on the icon to the right of Schema Object Reference
  • Expand XML Schema Simple Types
  • Scroll down until you find integer, and double click on that.
  • Click on the green plus again to add another variable
  • Follow same steps as above, but name it message and choose string as type
  • Next click on the pencil icon for Target
  • Again click on the icon to the right
  • Expand Application Schema Files and locate your XSD
  • Choose the createProductResponse type
  • Click OK in all windows until you can view the newly created file

In the view that opens, in the right horizontal lane, expand the createProductResponse object. Right click on the ProductId object and choose Insert. Then select the $id variable on the left and drag across to this object. Do the same for Message. Hit save when done.

Now go back to the pipeline and drag a new component called Replace into the Response pipeline. Again we need to fill in some properties at the bottom.

  • Location: Body (you should know why by now)
  • Value: Click on the drop down arrow and choose XQuery Resources
  • In the new window, locate the XQuery file we just created
  • Now you will see the variables in the view, and we need to enter some values
  • In message: 'New product created'
  • In id: 1
  • Click OK
  • Finally choose the radio button Replace node contents (This will keep the Soap body tag, but replace everything inside it)
  • Rename the stage to CreateResponse

The next component we are going to add is a new Stage, which we are going to rename ValidateResponse. Into that stage we are going to add another Validate component. Here you can follow almost the same steps we did for the previous Validate component. But instead of choosing the request object from the XSD, we are now choosing the response object. We just want to make sure that the consumer gets the response they are expecting as well.

Congratulations! You have now successfully completed your first OSB service. Now we just have to deploy and test it to make sure it is functioning as expected.

Deploying and testing

Before we can deploy anything we need to make sure that the weblogic server is started. Go to the domain folder where you created your compact domain and run the startWeblogic script. On my linux virtual machine, this script is located in /u01/oracle/fmw/user_projects/domains/osb_domain

Starting the WebLogic server can take up to 5 mins to complete. If running this in a terminal window you will eventually see "SOA platform is RUNNING and ready accept requests". This means you are good to go. I suggest that you always run the script in a terminal window so that you can see what is happening while running your application.

When the server is up and running, right click on your project and choose Deploy. The first option in the list will say something like NameOfApplication_projectx.service.pro.productStorageService_ServiceBusProjectProfile (Unless you have previously deployed that project, then it will say 1. Deploy to Service Bus Server). In the window that pops up click next until you can see Application Servers. If you haven't added any connections yet, the only item in the list will most likely be IntegratedWeblogicServer. We are not going to deploy there, so click the green plus sign to add a new connection. Then do the following:

  • Connection Name: localDev (or some other name)
  • Connection Type: WebLogic 12.x
  • Click next
  • Username: The username you set up your compact domain with
  • Password: The password you set up your compact domain with
  • Click next
  • Weblogic Hostname: localhost
  • Port: 7001 (If you chose a different port during configuration of your compact domain, then use that)
  • WebLogic Domain: The name you chose when setting up your compact domain (mine is osb_domain)
  • Click next
  • Press the Test Connection button to make sure the connection works. And click Finish
  • If something fails, then go back and review your settings.

You can now see that the server is added to the list of Application Servers. Make sure that it is highlighted before clicking next. I also usually tick the check box "Overwrite modules of the same name", so that if I make any changes to the project after I deploy it the first time, then the already deployed project will be overwritten by the new changes when I redeploy. Then click Finish.

Now we can test the service to make sure it is functioning as expected. So open a web browser and enter localhost:7001/servicebus in the address bar and log in with the same credentials you set up your domain with. (If you chose another port number than 7001 when setting up your domain, use that number instead) After logging in you should see your project listed on the left side. Click on the right arrow to expand the project. Then expand ProxyServices and click on ProductStorageService_HTTP. A tab should then open in the main window, and you should see a green "play" button in the top right corner. Click that button to open a new window.

Under Service Operation we can see a drop down with available operations. Since we only created one operation this time, createProduct will be the only option available. Under Request Document we can enter the data we are sending into our service. SOAP Header we can disregard, but in the payload section you will see that this is already filled in with some default data, and you can recognize the xml tags from the elements that we defined in the XSD.

Since we have hard coded the response in our pipeline, the response will be the same regardless of what we enter here. Unless we remove some required element causing a validation failure in the request pipeline. Try hitting the Execute button while leaving the data as is, and see that the response contains the hard coded data we entered as input to the XQuery transformation earlier. Then hit the back button and remove one of the required elements before executing the request again.

You can also do the same test by opening the pipeline. This view offers some more details of the request/response flow when we run the request. I suggest you use this one while looking for errors in your code, as you are more likely to locate the exact spot where the error occurs.

And that is all for this tutorial. In the next tutorial we will go through how to persist the incoming data in a database, and how to configure and use the DB adapter.