This post demonstrates how to expose an E-Business Suite interface as a web service, in this case the PL/SQL API for getting a price for a product.
Once you have exposed a service, you are probably going to want to consume it! An excellent way to do that is to use the Oracle Service Bus, providing service virtualisation and loose coupling, as well as the ability to cache service results and provide a simpler interface to downstream service consumers, like user interfaces for example.
In this post, we will explore consuming the E-Business Suite pricing service using Oracle Service Bus. In a subsequent post, we will look at using Oracle Service Bus to provide a simpler interface and service result caching.
Thanks to Dave Reid and Devon Winkworth for helpful ideas and suggestions.
To complete the steps in this post, you will need to have exposed your service from E-Business Suite and granted access to a user, as described here, and you will need an installation of Oracle Service Bus 126.96.36.199 with the Oracle Web Services Manager Extension installed. I used a WebLogic domain which contained both Oracle Service Bus 188.8.131.52 and Oracle SOA Suite 184.108.40.206.
To begin, we log on the the Oracle Service Bus console at http://yourserver:7001/sbconsole using an administrative user, like weblogic.
If you have just installed Oracle Service Bus, your console should look like the image below. If you have been using your installation for a while, there will probably be some more data in there. Let’s click on the Project Explorer view in the main navigation down the left hand side of the console window, to move from the dashboard to the project view.
In order to make some changes, we need to start a Session in the Change Center by clicking on the Create button in the top left of the console.
When you click on it, you will notice the Change Center window changes to look like the image below. Now, we will create a new project to hold our work. Enter a name in the Enter New Project Name field and then click on the Add Project button. I called mine RedStack.
Now, click on your newly created project in the tree under Project Explorer on the left hand side navigation to open the project. We will create a folder to hold our WSDL and related resources. Enter a name for the folder in the Enter New Folder Name field and click on the Add Folder button. I called mine Resources.
Click on the new folder in the Project Explorer to open it. Now we will add the details of our service. In the Create Resource pull down menu, select Resources from URL. This option allows us to point to a running service and automatically import the necessary information into the service bus.
Enter the URL for the WSDL (which we got at the end of the previous post) into the URL/Path field, choose a name, I called mine EBSGetPrice, and make sure the Resource Type is WSDL. Then click on the Next button to continue.
Your WSDL address should be something like this:
Oracle Service Bus will connect to E-Business Suite and read the WSDL and associated XSD, you will see these displayed, as in the image below. Click on Import to add them into the service bus.
You will now see the WSDL and XSD listed under the Resources folder in your project, as shown below.
Navigate back to the root of your project, and add another folder called BusinessServices to hold our business service definitions. Simply speaking, a “business service” in the Oracle Service Bus is a a service that is invoked by the service bus. The opposite is a “proxy service” which is a service that is exposed by the service bus.
Navigate into your new BusinessServices folder, and select Business Service from the Create Resource menu, as shown.
Enter a name for your business service, I called mine EBSGetPriceBS, and make sure the Service Type is WSDL Web Service. This tells the service bus that we are defining this new service based on a WSDL that already exists in the service bus. Click on the Browse button to locate the WSDL we just imported from E-Business Suite.
A list of WSDL resources will be displayed. Click on your EBSGetPrice WSDL.
Then highligt the port you want to use (in this case there is only one, but more complex services may provide multiple ports) and click on Sumbit.
You will return to the Create a Business Service wizard. Click on Next until you arrive at the HTTP Transport Configuration page. Open up the Advanced Settings and ensure the checkbox next to Use Chunked Streaming Mode is not selected.
Click on Next until you arrive at the final (summary) page, as shown below. You can accept all the defaults for this simple example. Then click on Sumbit to save your new business service definition.
Ok, so now we have defined a business service that will call the pricing web service that we exposed in E-Business Suite. Let’s save all our changes by activating the session – when you work in the Oracle Service Bus console, the changes you make are not “deployed” into the running service bus until you “activate” them.
Click on the Activate button in the Change Center. Enter a description if you want to (it makes it easier to find where you made changes later on) and click on Sumbit.
Now, since the E-Business Suite service uses WS-Security for authentication, we are going to need to set up a policy to add WS-Security credentials to our business service. There are several ways to acheive this, but the “best” way – well the way that is most in line with how Oracle recommends you do this, and how it is done in Oracle products – is to use the Oracle Web Services Manager. This approach also provides very neat separation of concerns, keeping the security as declarative and policy based, and applying it to the service defintions at runtime.
If you have not used Oracle Web Services Manager before in this domain, you will need to set up a keystore to hold the credentials. If you already have a keystore, you can skip the next few steps.
Create a directory to hold our keystore:
In this directory, create a new keystore and a RSA key pair. Note that this whole command is entered on one line. It is shown here on multiple lines for ease of reading only. You may need to put the path to your JDK’s bin directory before the keytool command if that directory is not in your PATH. You need to add in the appropriate Common Name (CN) as shown in bold. Here we have used the fully qualified hostname of the WebCenter server, with the hostname as a cn and each domain name component as a dc. You also need to provide a password for the key (keypass) and for the keystore (storepass), as shown.
keytool -genkeypair -keyalg RSA -dname "cn=yourserver,dc=au,dc=oracle,dc=com" -alias orakey -keypass welcome1 -keystore default.jks -storepass welcome1 -validity 1064
Copy your keystore into your domain configuration directory, using a command like this: (again, this command should be entered on one line)
cp default.jks /u02/user_projects/domains/boot_domain/config/fmwconfig/
Next, we will configure our domain to use this keystore. In Enterprise Manager, navigate to “Farm_boot_domain” -> “Weblogic Domain” -> “boot_domain”
From the context menu, select “Security” -> “Security Provider Configuration”
Scroll down to Keystore, expand it, and click Configure. Deselect (uncheck) the box Configure Keystore Management and click Ok. This will make sure that we reset the configuration and remove any old values. It is a good practice to follow this two step process of unconfiguring and then configuring.
Now go back to Keystore, and click Configure again, this time check the box Configure Keystore Management and enter the following information:
Keystore Path = ./default.jks Password = welcome1 Confirm Pwd = welcome1 Signature Key Alias = orakey Signature Password = welcome1 Confirm Pwd = welcome1 Encryption Key Crypt Alias = orakey Crypt Password = welcome1 Confirm Pwd = welcome1
Save your changes and then stop all managed servers, and then the admin server, then restart the admin server and then the managed servers.
That completes the steps needed to setup the keystore.
Now, we will create some credentials for E-Business Suite. In the Enterprise Manager, navigate to your WebLogic domain and then open the domain menu and select Security and then Credentials as shown below.
You should already have a map called oracle.wsm.security. If not, click on Create Map and add it. Note that is must have this exact name. Then highlight this map and click on Create Key. Name the key ebs-key and enter ASADMIN as the User Name (assuming this is the E-Business Suite user you selected in the previous post) and enter the password for this user. Then click on OK to save these credentials.
Now we will create a policy which uses these credentials. E-Business Suite requires us to use WS-Security Username Token policy. In Enterprise Manager, open the domain menu and select Web Services and then Policies as shown.
Change the Applies To filter to All and then click on the little green arrow in a blue circle icon next to the Name field to search for policies.
Scroll down to find the policy called oracle/wss_username_token_client_policy. Make sure you get the right one, there are a number of them with fairly similar names. This policy is almost exactly what we need, so we will just make a copy of it and add in our changes.
With this policy highlighted, click on the Create Like button.
Enter a name for your new policy. I just added EBS- to the beginning of the existing name, to get EBS-oracle/wss_username_token_client_policy.
Scroll down to the Assertions section, and highligh the WSSecurity UserName Token entry. Then click on the Configuration tab just below that. Your screen should look like the image below:
Highlight the csf-key entry in the Configurations table and click on the Edit button. Enter ebs-key in the Value field. This is the name of the credentials that we just created in the previous step. Again, notice the nice clean separation, with the actual credentials being stored separately to the policy, so that they are reusable. Click on the OK button and then the Save button to save this new policy.
Now that we have defined our policy, let’s apply it to our service and test it.
Back in the Oracle Service Bus console, create a new change session, and navigate to your EBSGetPriceBS service and open it. Use the project tree in the laft hand side navigation to get to the folder and then click on the service name to open it. Open the Policies tab as shown below. From the list of Service Policy Configuration options, select OWSM Policy Bindings. The screen will refresh, then click on the Add button in the Service Level Policies table.
Select your newly defined policy from the list and click on Submit.
Now save and activate your changes (as we did before).
Now we are ready to test our service. Click on the little green ladybug icon next to your service to open the test console.
Enter the test data into the SOAP Header and Payload fields as shown below. My test data is included just below the image. Then click on Execute to run the test.
Here is the test data that I used. This should work for you, but you may need to adjust some values to suit your E-Business Suite installation.
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <qp:SOAHeader> <qp:Responsibility>FND_REP_APP</qp:Responsibility> <qp:RespApplication>FND</qp:RespApplication> <qp:SecurityGroup>STANDARD</qp:SecurityGroup> <qp:NLSLanguage>AMERICAN</qp:NLSLanguage> <qp:Org_Id>204</qp:Org_Id> </qp:SOAHeader> </soap:Header>
<pric:InputParameters xmlns:pric="http://xmlns.oracle.com/apps/qp/soaprovider/plsql/qp_preq_pub/price_request/"> <pric:P_LINE_TBL> <pric:P_LINE_TBL_ITEM> <pric:REQUEST_TYPE_CODE>ONT</pric:REQUEST_TYPE_CODE> <pric:PRICING_EVENT>LINE</pric:PRICING_EVENT> <pric:LINE_INDEX>1</pric:LINE_INDEX> <pric:LINE_ID>190339</pric:LINE_ID> <pric:LINE_TYPE_CODE>LINE</pric:LINE_TYPE_CODE> <pric:PRICING_EFFECTIVE_DATE>2010-05-30</pric:PRICING_EFFECTIVE_DATE> <pric:ACTIVE_DATE_FIRST>2010-05-30</pric:ACTIVE_DATE_FIRST> <pric:ACTIVE_DATE_FIRST_TYPE>NO TYPE</pric:ACTIVE_DATE_FIRST_TYPE> <pric:ACTIVE_DATE_SECOND>2010-05-30</pric:ACTIVE_DATE_SECOND> <pric:ACTIVE_DATE_SECOND_TYPE>NO TYPE</pric:ACTIVE_DATE_SECOND_TYPE> <!--pric:USAGE_PRICING_TYPE>L</pric:USAGE_PRICING_TYPE--> <pric:LINE_UOM_CODE>Ea</pric:LINE_UOM_CODE> <pric:CURRENCY_CODE>USD</pric:CURRENCY_CODE> <pric:PRICE_FLAG>Y</pric:PRICE_FLAG> </pric:P_LINE_TBL_ITEM> </pric:P_LINE_TBL> <pric:P_QUAL_TBL> <pric:P_QUAL_TBL_ITEM> <pric:LINE_INDEX>1</pric:LINE_INDEX> <pric:QUALIFIER_CONTEXT>MODLIST</pric:QUALIFIER_CONTEXT> <pric:QUALIFIER_ATTRIBUTE>QUALIFIER_ATTRIBUTE4</pric:QUALIFIER_ATTRIBUTE> <pric:QUALIFIER_ATTR_VALUE_FROM>1000</pric:QUALIFIER_ATTR_VALUE_FROM> <pric:COMPARISON_OPERATOR_CODE>=</pric:COMPARISON_OPERATOR_CODE> <pric:VALIDATED_FLAG>Y</pric:VALIDATED_FLAG> </pric:P_QUAL_TBL_ITEM> <pric:P_QUAL_TBL_ITEM> <pric:LINE_INDEX>2</pric:LINE_INDEX> <pric:QUALIFIER_CONTEXT>CUSTOMER</pric:QUALIFIER_CONTEXT> <pric:QUALIFIER_ATTRIBUTE>QUALIFIER_ATTRIBUTE2</pric:QUALIFIER_ATTRIBUTE> <pric:QUALIFIER_ATTR_VALUE_FROM>1290</pric:QUALIFIER_ATTR_VALUE_FROM> <pric:COMPARISON_OPERATOR_CODE>=</pric:COMPARISON_OPERATOR_CODE> <pric:VALIDATED_FLAG>Y</pric:VALIDATED_FLAG> </pric:P_QUAL_TBL_ITEM> </pric:P_QUAL_TBL> <pric:P_LINE_ATTR_TBL> <pric:P_LINE_ATTR_TBL_ITEM> <pric:LINE_INDEX>1</pric:LINE_INDEX> <pric:PRICING_CONTEXT>ITEM</pric:PRICING_CONTEXT> <pric:PRICING_ATTRIBUTE>PRICING_ATTRIBUTE1</pric:PRICING_ATTRIBUTE> <pric:PRICING_ATTR_VALUE_FROM>208964</pric:PRICING_ATTR_VALUE_FROM> <pric:VALIDATED_FLAG>N</pric:VALIDATED_FLAG> </pric:P_LINE_ATTR_TBL_ITEM> </pric:P_LINE_ATTR_TBL> <pric:P_LINE_DETAIL_TBL/> <pric:P_LINE_DETAIL_QUAL_TBL/> <pric:P_LINE_DETAIL_ATTR_TBL/> <pric:P_RELATED_LINES_TBL/> <pric:P_CONTROL_REC> <pric:PRICING_EVENT>LINE</pric:PRICING_EVENT> <pric:CALCULATE_FLAG>Y</pric:CALCULATE_FLAG> <pric:SIMULATION_FLAG>N</pric:SIMULATION_FLAG> <pric:ROUNDING_FLAG>Q</pric:ROUNDING_FLAG> <pric:DEBUG_FLAG>Y</pric:DEBUG_FLAG> <pric:TEMP_TABLE_INSERT_FLAG>Y</pric:TEMP_TABLE_INSERT_FLAG> <pric:MANUAL_DISCOUNT_FLAG>Y</pric:MANUAL_DISCOUNT_FLAG> <pric:REQUEST_TYPE_CODE>ONT</pric:REQUEST_TYPE_CODE> <pric:ORG_ID>1642</pric:ORG_ID> </pric:P_CONTROL_REC> </pric:InputParameters>
When the test completes (should be less than a second) you will see the results window. Scroll down past the request message to find the response. In the response you will find the UNIT_PRICE has been populated by E-Business Suite, as shown in the image below:
You will see that there are also many other peices of data in the response – this is a fairly complex interface. In our next post in this series, we will look at how we can hide this complexity from clients and how we can cache the data from E-Business Suite to improve performance.
That completes this post, which shows us how to consume a WS-Security protected web service provided by E-Business Suite using the Oracle Service Bus and policy based security. Of course, this approach will work for any WS-Security Username Token based web service, not just thos provided by E-Business Suite. For example, JD Edwards Enterprise One uses this same style of security, so this approach will also work against JD Edwards.