Services with a SmileBy Steve Muench
Create data-centric Web services for SOA development in minutes.
In this third-anniversary column, let's take another look at the upcoming Oracle JDeveloper/Application Development Framework (Oracle ADF) 11g release and explore a major new feature that simplifies the creation of data-centric Web services. With this feature and a few mouse clicks, you can turn any Oracle ADF application module into a powerful Web service that interoperates with other standards-based clients and services within a service-oriented architecture (SOA).
To get started, make sure you are using the Oracle JDeveloper 18.104.22.168 Technology Preview 2 release, which is available as a free download on the Oracle Technology Network (OTN). Further, download the starter workspace. This starter workspace eliminates many of the initial project steps we've performed many times before in previous columns.
Extract the contents of the o18frame.zip file to a path that doesn't contain any spaces (such as c:\jdeveloper). Then open the FrameworksJanFeb2008.jws workspace in Oracle JDeveloper. Note that the starter workspace defines a familiar Emp entity object, an Employee view object, and an HRModule application module. The Emp entity object is configured with several declarative features, including a TotalComp calculated attribute that computes an employee's total compensation, a range validation rule on its Sal attribute that enforces a value between 0 and 5000, and an alternate key on its Ename attribute that enables easy employee lookup by name. The Employee view has a named query filter criterion—EmployeesByDepartment—that can be used to find employees in a department with a specific department number. The HRModule has one custom method—totalEmployeeCompensation()—that returns the total compensation for an employee, given that person's name.
To finish the project setup, go to Application Resources in the Application Navigator and adjust the properties of the database connection named scott to ensure that you can successfully test a connection to a SCOTT schema. If you need to create the tables, use the CreateDeptEmpTables.sql script provided with the starter workspace.
Enabling the Service Interface
With SOA, different application systems cooperate by invoking each other's application programming interfaces (APIs). The service interface for your application module enables other applications to interact with its data and custom methods by using standard Web services calls. In Oracle JDeveloper, the service interface is a declaratively configured feature of your application module. To create a service interface, you simply identify which view object instances in your data model to expose to clients, which built-in data access operations you want each one to support, and which custom methods you want to make available.
Start by double-clicking the HRModule application module to open the editor. In the editor, click Data Model and note that there is a single view object instance named Employee in the data model. Next, click Service Interface and the green plus sign at the right to create the service interface. When the Create Service Interface screen appears, change the Web Service Name to HRService, leave Target Namespace at its default value, and click Next . On the Service Custom Methods screen, select the totalEmployeeCompensation() method from the Available list and click Add ( > ) to add the custom method to the Selected list. Then click Next .
On the Service View Instances screen, select the Employee view instance on the Available list and click Add ( > ) to add the view instance to the Selected list. Click the Employee view instance in the Selected list, and note the set of operations that appears in the View Instance Operations table. This table enables you to control which built-in operations your service interface will support. Resize the screen to be taller to see more of the basic operations in the table. Check the check boxes next to the Create, Update, Delete, Merge, GetByKey , and Find operations—you may need to scroll down the table to see all of them. The Process and ProcessChangeSummary operations are for more-advanced use cases, so leave their check boxes unchecked for this exercise. In the View Criteria Find Operations table, click the green plus sign to add a new find operation based on declarative view criteria. When the Configure View Criteria Find Operation dialog box appears, select EmployeesByDepartment from the View Criteria list, change the Operation Name to findEmployeesByDepartment, and click OK . Finally, click Finish to enable the service interface. Be sure to save all of your changes by selecting File -> Save All from the main menu.
In the Application Navigator , expand the HRModule node as well as the serviceinterface folder it contains. Note that Oracle JDeveloper has automatically generated the artifacts necessary to implement the service you configured. HRService.java is the interface that represents the service contract for Java clients. HRServiceImpl.java is an Enterprise JavaBeans (EJB) 3.0 session bean that implements this interface. The HRService .wsdl and the HRService.xsd files are the standards-based Web Services Description Language (WSDL) and XML Schema documents that describe the service contract's methods and datatypes. In the future, if you need to adjust your service interface settings, you can click the yellow-pencil edit button in the Service Interface editor, and Oracle JDeveloper will automatically keep your implementation files in sync with changes you make in the Oracle JDeveloper user interface.
Testing the Service
As you might expect, it is very easy to test your Web service interface by using the embedded Oracle Application Server Containers for Java (OC4J) server inside Oracle JDeveloper. However, before testing your service, verify the following settings to ensure a successful result. First, select Tools -> Preferences... from the main menu. When the Preferences dialog box appears, click Web Browser and Proxy . Make sure the Use HTTP Proxy Server check box is unchecked. (You won't need a browser proxy for this exercise.) Next, click Deployment and check the check box labeled Allow Deployed Module access to OC4J internal classes . Click OK to dismiss the Preferences dialog box.
To test your service interface by using the embedded OC4J server, go to the serviceinterface folder in the Applications Navigator , right-click the HRServiceImpl.java file, and select Run . You'll know the service is ready for testing when Running: Embedded OC4J Server - Log displays the target URL and Oracle Containers for J2EE 10g (22.214.171.124.0) initialized. You can safely ignore warning messages that might appear due to known issues in the technology preview release.
Next to the target URL message, note (but don't click) the hyperlink. If you were to click the link, you would open the HTTP Analyzer in this preview release (which isn't what we want to do). Instead, test the service in your Web browser, by copying the target URL and pasting it into the browser's address bar. If you haven't changed your default embedded OC4J server port numbers, the URL will be http://localhost:8988/EJBFrameworksJanFeb2008/HRService. You should see an HRService endpoint Web service test page appear in the browser.
To test the Web service in the browser, using a sample parameter, select getEmployee from the Operation list. Then enter the value 7839 in the Empno field in the Parameters area and click the Invoke button. The Test Result page should display the standard XML format of the Web service's result, and the employee data for KING should be contained in the data inside the tags. Note that when the Web service is accessed by programmatic clients, the XML-based Web service requests and responses are implementation details that guarantee interoperability but don't require any manual processing.
Now click the Return to Test Page link and select updateEmployee from the Operation list. Enter 7839 in the Empno field, enter 5005 in the Sal field, and uncheck the Include in Message check boxes for all of the other parameters so that they are not included in the request. When you click Invoke , you should see an XML-based exception message with the fault string Salary must be between 0 and 5000 on the Test Result page. This operation fails whenever you attempt an update that violates the range validation rule on the Sal attribute of the Emp entity object. Now try repeating the updateEmployee test with a salary of less than 5000. This time, the Test Result page will confirm a successful update by displaying the modified employee data.
To stop the embedded OC4J server, in Oracle JDeveloper, click the red terminate icon in the Log window toolbar or select Run -> Terminate -> Embedded OC4J Server from the main menu.
Deploying the Service
Testing with the embedded OC4J server can be useful while you're developing your service, but once you're satisfied with it, you'll need to deploy it on an external application server. Using the Oracle JDeveloper 11g Technology Preview 2 release, you can launch the embedded OC4J server in standalone mode for this purpose. To start the server, open a command shell window, navigate to the ./jdev/bin subdirectory of your Oracle JDeveloper 11g installation, and run the start_oc4j script. The first time you run it, it will prompt you to create and confirm the password for the fmwadmin account. Remember this password, because you will need it a bit later. You can ignore any warning messages you may see while the server is starting up. When the server is ready, it will display the message Oracle Containers for J2EE 10g (126.96.36.199.0) initialized.
Now that the OC4J server is running, the next step is to define an application server connection for this server. In Oracle JDeveloper, select View -> Resource Palette from the main menu. In the Resource Palette , click the folder with a plus-sign icon (to the left of the search field), and select New Connection -> Application Server from the list that appears. On the Type page of the Application Server Connection Wizard, name the connection localoc4j, leave the Connection Type set at Standalone OC4J 11g , and click Next . On the Authentication page, leave Username set as fmwadmin , enter the password you entered for this account when you first started the embedded OC4J server in standalone mode, and click Next . On the Connection page, leave the defaults and click Next . Finally, on the Test page, click Test Connection and wait for the Success! message to appear in the Status area. Click Finish to define the new application server connection.
The next step is to create a business components service interface deployment profile, which defines the set of files or runtime artifacts required to deploy the service to an external server. To create the profile, right-click the Model project node in the Application Navigator and select New.... When the New Gallery dialog box appears, expand the General category, select Deployment Profiles , and double-click Business Components Service Interface . When the Create Deployment Profile dialog box appears, enter HRService for Deployment Profile Name and click OK . The Project Properties dialog box should then appear, indicating where your project-level deployment profiles can be found, in case you need to modify them for any reason. Click OK to close the Project Properties dialog box.
Finally, deploy your service interface project to the localoc4j application server connection. To do so, right-click the Model project in the Application Navigator and select Deploy -> HRService -> Deploy . When the Deployment Plan dialog box appears, click OK to begin the deployment by using the default deployment plan. At this point, the Deployment tab of the Log window will show the progress of the deployment. One important status line to look for is Binding FrameworksJanFeb2008 web-module ... under context root /FrameworksJanFeb2008.
This line tells you the context root name to use when accessing the service on the external server. Note that it does not include the EJB- prefix, in contrast to the URL we used above when testing with the embedded OC4J running inside Oracle JDeveloper 11g. Once the deployment is done, you can point your browser to the URL of the service on the standalone server: http://localhost:8888/FrameworksJanFeb2008/HRService.
As before, the HRService endpoint testing page should appear, but this time the service is running on the standalone OC4J server. To make sure all is well, select totalEmployeeCompensation from the Operation list and enter an ename value of martin. After you click Invoke , the Test Result window should show a total compensation value of 2650 (among all the tags). That result includes the sum of Martin's salary (1250) and his commission (1400).
The previous example showed the results of a single employee row along with a simple scalar value. As a final test, select the findEmployeesByDepartment operation. This test shows an operation that can return multiple employee rows. Enter the value 10 in the DepartmentNumber field in the Parameters area. Enter the value 0 (zero) for fetchStart and -1 for fetchSize to retrieve all rows in the result. For now, you won't need to include any of the more advanced search options, so collapse the filter, sortOrder, findAttribute , and childFindCriteria sections and uncheck the Include in Message check box next to each heading. After you click Invoke , the Test Result page should show data for all the employees in Department 10.
Although we've only scratched the surface of this powerful new feature, I hope you can already appreciate how handy it will be for your future service-oriented architecture development tasks. Whether the client of your service interface is a .NET application, a Business Process Execution Language (BPEL) business process, or another Web service, Oracle ADF 11g will make quick work of the task. For more information on this topic, see the "Integrating ADF Applications with External Services" chapter in the Release 11g version of Oracle ADF Developer's Guide.
Steve Muench is a consulting product manager for Oracle JDeveloper and an Oracle ACE. Since 1990 he has developed and supported Oracle tools and XML technologies and continues to evangelize them. Muench coauthored the Oracle ADF Developer's Guide for Forms/4GL Developers (Oracle, 2006), wrote Building Oracle XML Applications (O'Reilly Media, 2000), and shares tips and tricks on OTN (oracle.com/technetwork) and in his Dive into ADF blog (radio.weblogs.com/011823 ).