Friday, December 13, 2013

Webservice interaction patterns - part 1 - very basic DML

There are a number of ways you 'call' web services from an ADF application. The best method to choose would depend on the individual scenario.

This particular example is the most suitable option where:
- Our application is allowed to read from the database using its own business services - i.e. ADFbc (which are fairly easy to create and don't require a lot of 'plumbing' code compared to other technologies) but we need to delegate any transactional calls (such as create/update/deletes) to an external web service.

The reasons could be many: Most commonly, such business (web) services already exist with a number of person-years of effort, testing & polishing already gone into them and they already meet the requirements perfectly. So it makes perfect sense to not re-develop all that logic into ADFbc and just reuse the existing service.

What this post is not: If you have written all your business logic using ADF business components then you can expose that as a web service (e.g. for consumption of the mobile version of your app.) That is a different scenario altogether.

If ALL data access operations (both reads and writes) are based on web services, I would most likely choose a different approach. (which I will cover in the subsequent posts in this series).


The sample application (Created in JDev 11.1.1.6) has three parts
1)  the web service which provides the Create operation.
I simply created it using the SOA Suite - but that's not the important part - you can pick the wsdl and implement the service using any technology. I also exposed only the Create operation for now and that too, just for a single row. It's easy to expose all the other CRUD operations as well.

2) The ADF application (Application TestWSCreate in the zip file). Contains the Model and ViewController projects (thing to note is the EmployeeImpl class and its doDML operation)
3) The web service proxy - which is just code generated from the wsdl. I have kept it in the Model project but it should probably be in its own project or application which you could call ExternalService clients etc.
Contents of my Model project are shown below:




Setup:
Download the application from here1) On the server where you'll deploy the web service, create an XA data source pointing to the XE schema with the JNDI name jdbc/hrXADS
2) Create a connection pool on the DBAdapter with the jndi name eis/db/hrXA
and point it to the above XA data source

3. Open the application EmpDeptCRUD and deploy the project DataService on the SOA server.
I used the SOA-BPM VM and on my machine it runs at http://soabpm-vm:7001 . If your SOA server is running at a different
address, just point the location inside the WSDL in the proxy to your server's location (see the screenshot of the Model project) and re-generate the proxy classes (right click - generate web service proxy....)

4. Open and run the adfc-config from ViewController in the application TestWSCreate
Clicking 'Create New' will create a new Employee record - you can enter data, perform validations.
Finally, when you click 'Commit' the web service is invoked.





Here is how/why it happens:



Coming up:
- Detecting and Handling timeouts
- Leveraging the SOA Suite features (if the implementation technology for your external webservices is the SOA suite or even if you have a SOA Suite license).
- Optimizing web service calls when performing creates in a table / collection

Also see:
http://www.ateam-oracle.com/going-mobile-with-adf-programmatically-invoking-soap-web-services-with-complex-types/

Update: updated the step on what to do when the web service URL is changed.

No comments: