Oracle® Retail Integration Bus Service-Oriented Architecture Enabler Tool Guide Release 15.0.1 E74930-01 |
|
![]() Previous |
![]() Next |
This chapter provides a set of implementation notes that may be helpful when implementing the Oracle Retail Service-Oriented Architecture Enabler (RSE) tool. The information included here is intended to provide guidance on the following topics:
PL/SQL Service Consumer
PL/SQL Provider Service
Java EE Web Service Consumer
Java EE Service Provider
Web Service Call as a Remote EJB Call
Web Service Call as a POJO Call
Deploying the Web Service
Creating a JDBC Data Source
The implementation notes in this chapter are intended to provide some guidance in the development and deployment of the Web service layer. This information does not take into account the implementation of the business logic required to complete the application API layer.
The RSE tool and approaches described in this section are complex. A high level of skill and knowledge of the product is required to complete these implementation tasks. Also required is technology specific development of application APIs and the business logic that is needed to complete it.
Any issues that may arise with development tools, development environments, custom APIs, or custom message flows are the responsibility of the customer and not Oracle Retail.
To set up the Web service consumer side proxies, complete the following steps:
loadjava -u <username>/<password>@<host>:<port>:<SID> -r -v -f -genmissing dbwsclientws.jar dbwsclientdb102.jar
Note: loadjava is a utility available in Oracle Database. |
Edit and run *_grant.sql script as sysdba to give the user proper permission.
Load the following jars to the database.
Instructions to load jars to database can be found in PLSQLServiceConsumer_ReadMe.doc packaged with the generated zip file.
xmlparserv2-<version>.jar
dbwsa-<version>.jar
dbwsclientdb11-<version>.jar
dbwsclientws-<version>.jar
<WebServiceName>ServiceConsumer.jar
http_client-<version>.jar and ReadMe.doc packaged with the generated zip file
Note: The ojdbc7-<version>.jar should not be loaded, because it is used only for loading the other jars. If the jar is already loaded, drop the jar. If you get ORA-29533 while dropping the jar, drop the individual files.For example: dropjava -u <username>/<password>@<host>:<port>:<SID>packageName/SourceName |
Run the *Consumer_create.sql in the schema that will use this API. The schema owner is the user granted permission in Step 2.
Write a PL/SQL procedure to work as the client to call the Web service. A sample is provided below:
Note: The following sample code is written for the PayTerm Web service. Replace the service endpoint URL and the consumer class name according to the Web service for which the client is generated. |
create or replace PROCEDURE wstestClient IS BEGIN PayTermServiceConsumer.setEndpoint('http://example.com:7001/PayTermBean/PayTermService'); dbms_output.PUT_LINE(PayTermServiceConsumer.getEndPoint()); dbms_output.PUT_LINE(PayTermServiceConsumer.ping('TestMessage')); dbms_output.PUT_LINE('Done.'); END;
The distribution (.zip) file includes <appname>-service .ear file that contains all the generated code for the service; it is ready to be deployed to the application server. The business logic can be implemented in PL/SQL packages in Oracle. The distribution contains the specification and body scripts for the packages called by the deployed service.
To complete implementation, follow these steps:
Create the PL/SQL service provider distribution file using the RSE tool. The output of this process is the .zip file.
Extract the <service_name>.ProviderImplSpec.sql and <service_name>ProviderImplBody.sql files from the distribution zip file.
These files will be modified to provide a PL/SQL implementation for the service.
Extract the <service_name>-service.ear file from the distribution zip file. This file is the generated Web service that will be deployed.
Create the JDBC data source.
If not already deployed, deploy the Oracle Objects to the appropriate database user.
Note: See the Oracle Retail Functional Artifact Generator Guide. |
Modify the PL/SQL body file for the business logic implementation. The <service_name>ProviderImplBody.sql file contains comments about where to implement logic for each method on the service.
Install the modified PL/SQL packages to the database. They will be called by the Web service methods.
Deploy the <service_name>.ear file to the Oracle WebLogic Server.
The Java Web service consumer artifacts generated by this tool are based on the JAX-WS 2.1 specification. Services can be invoked in synchronous and asynchronous mode by using these artifacts.
To complete implementation, follow these steps:
Create a Web service client.
Create the application that uses the {WebServiceName}ServiceConsumer.jar and code your Web service client. The {WebServiceName}ServiceConsumer.jar contains all necessary code to invoke the {WebServiceName}Service WebService.
Additional JAX-WS library jars might be required.
Deploy the service in the server.
Invoke the Web service client to see the results.
The code below is an example of how to invoke Oracle Retail's PayTerm Web service. For each Web service, a specific WebServiceConsumer code/jar must be generated that can "talk to" the service.
Note: The following sample code is for invoking the PayTerm Web service. When you generate Java consumer for a Web service, the generated jar file will contain classes specific to that Web service. Use the appropriate classes in the client code. Service namespace and WSDL location also should be changed accordingly. |
import java.math.BigDecimal; import java.net.URL; import javax.xml.namespace.QName; import com.oracle.retail.integration.base.bo.paytermdesc.v1.PayTermDesc; import com.oracle.retail.integration.base.bo.paytermref.v1.PayTermRef; import com.oracle.retail.rms.integration.services.paytermservice.v1.PayTermPortType; import com.oracle.retail.rms.integration.services.paytermservice.v1.PayTermService; import junit.framework.TestCase; public class PayTermTest extends TestCase{ public void testCreatePayTerm(){ try{ //qname is the namespace of the web service QName qName = new QName("http://www.oracle.com/retail/rms/integration/services/PayTermService/v1", "PayTermService"); //wsdlLocation is the URL of the WSDL of the web service URL wsdlLocation = new URL("http://example.com:7001/PayTermBean/PayTermService?WSDL"); //get the web service instance PayTermService service = new PayTermService(wsdlLocation,qName); PayTermPortType port = service.getPayTermPort(); //populate input object for the web service method PayTermDesc desc = new PayTermDesc(); desc.setTerms("terms"); desc.setDiscdays("1"); desc.setDueDays("1"); desc.setEnabledFlag("t"); desc.setPercent(new BigDecimal("1")); desc.setRank("1"); desc.setTermsCode("code"); desc.setTermsDesc("desc"); desc.setTermsXrefKey("key"); //call the web service method. here ref is the response object of the web service. PayTermRef ref = port.createPayTermDesc(desc); }catch(Exception e){ e.printStackTrace(); } } }
The RSE tool creates the appropriate provider Web service end-points as well as a skeleton implementation layer where the developer implements business logic. All of this is packaged inside the provider distribution archive file.
The Java EE Provider distribution file provides a sample deployable application and all the libraries that can be used to create Web services using retail payloads. The distribution file follows the naming convention of <appname>_JavaEEServiceProvider.zip. For example, the distribution file for the RMS application is named rms_JavaEEServiceProvider.zip. The <rms> prefix must be replaced with the name of any other application being developed.
The Web services generated by the RSE tool can be implemented and deployed in a number of ways. This section includes three implementation use cases for reference.
Generate the distribution file using the RSE tool.
Extract the <service_name>-ejb-impl-src.jar file from the zip file.
Extract the <service_name>-service.ear file from the zip file.
Add business logic code where indicated in the Impl java files.
Use the java jar command to re-build the <service_name>-service-ejb-impl.jar file.
Use the jar command to update .ear file with the new implementation jar.
Deploy the .ear file to the server.
Create custom java classes that implement the <service_name>ServiceProvider interfaces contained in the <service_name>-service-ejb.jar file.
Extract the ServiceProviderImplLookupFactory.properties file from the .ear file.
Modify the properties file to point to your implementation classes for the services.
Use the jar command to create a jar containing your implementation classes, as well as the modified properties file.
Run the RSE tool again and provide the new custom implementation jar file.
Extract and deploy the generated .ear file to the server.
Generate the distribution file using the RSE tool.
The service interfaces are provided in the <appname>-service-ejb.jar file in the distribution file. This jar file should be included in the application classpath.
Source code of sample implementations for the service interfaces are provided in the <appname>-service-ejb-src.jar file in the distribution file. (If application developers want to use the same classes in their application, they can extract the java files from the jar file and include those in application source code. They also can add their own business logic in the method implementations. If they decide to write their own implementations, they should make sure that the appropriate service interfaces are implemented.)
After writing the Web service implementations, the java files should be compiled. The class files can be included in a new jar file or in the same jar file used for the rest of the classes of the application.
Modify the ServiceProviderImplLookupFactory.properties file to include appropriate class names of service implementations and include it in application classpath. A recommended approach is to include the properties file in the jar file that contains the service implementation classes.
Make sure that the following jar files are included in the application ear file:
<appname>-service-ejb.jar
Jar file containing the service implementation classes
jaxb-api.jar
retail-public-payload-java-beans-base-<version>.jar
retail-public-payload-java-beans-<version>.jar
retail-soa-enabler-<version>.jar
Include an ejb-module in the application.xml of the application. The module name should be same as the name of <appname>-service-ejb.jar file.
The .ear file is ready for deployment on the server.
This section applies to PL/SQL Web service implementations and Java EE Web service implementations.
A client can call a Web service as a remote EJB call to improve performance by avoiding marshalling and unmarshalling.
The following is a list of prerequisites to implementation.
Get the updated wlfullclient7-12.1.3 .jar (integration-lib/lib)& retail-soa-enabler-<version>.jar (/integration-lib/) from the Repository.
Run build.gradle for retail-soa-enabler.
Generate the .ear and deploy it to server.
Configure the data source in the server.
Complete the following steps.
Create a Java file containing the code below inside any package. (See code sample at the end of this section.)
Include the following jar files in the classpath:
retail-public-payload-java-beans-base-<version>.jar
retail-public-payload-java-beans-<version>.jar
oo-jaxb-bo-converter-<version>.jar
retail-soa-enabler-<version>.jar
<appname>-service-ejb.jar
Run code as a Java application.
Note: The sample code below obtains a context for accessing the WebLogic naming service and calls a lookup method to get the Object inside the container by providing a binding name. It then calls a corresponding Web service method. As an example, the code sample calls the PayTerm service. |
import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import com.oracle.retail.integration.base.bo.paytermdesc.v1.PayTermDesc; import com.oracle.retail.integration.base.bo.paytermref.v1.PayTermRef; import com.oracle.retail.integration.services.exception.v1.EntityNotFoundWSFaultException; import com.oracle.retail.integration.services.exception.v1.IllegalArgumentWSFaultException; import com.oracle.retail.integration.services.exception.v1.IllegalStateWSFaultException; import com.oracle.retail.rms.integration.services.paytermservice.v1.PayTermRemote; public class WebLogicEjbClient { public static void main(String[] args) throws NamingException, IllegalArgumentWSFaultException, EntityNotFoundWSFaultException, IllegalStateWSFaultException { Context ctx = getInitialContext("t3://localhost:7001", "<WLS user>","<WLS password>"); Object ref = ctx .lookup("PayTerm#com.oracle.retail.rms.integration.services. paytermservice.v1.PayTermRemote"); PayTermRemote remote = (PayTermRemote)(ref); PayTermRef ref = new PayTermRef(); PayTermDesc desc = remote.findPayTermDesc(ref); System.out.println("findPayTermDesc=" + desc); } static Context getInitialContext(String url, String user, String password) throws NamingException { Properties h = new Properties(); h.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); h.put(Context.PROVIDER_URL, url); h.put(Context.SECURITY_PRINCIPAL, user); h.put(Context.SECURITY_CREDENTIALS, password); return new InitialContext(h); } }
Code sample 1:
Context ctx = getInitialContext("t3://localhost:7001", "<WLS user>","<WLS password>");
Description: Gets Initial Context object by passing the URL (local WebLogic URL, if not configured to other), user name, and password of the server.
Code sample 2:
Object ref = ctx .lookup("PayTerm#com.oracle.retail.rms.integration.services. paytermservice.v1.PayTermRemote");
Description: Lookup method retrieves the name of Object. Throws naming exception if the binding name is missing from the server. Binding name can be found after deploying the .ear file to the server, at JNDI Tree Page. (Summary of Servers >examplesServer>view JNDI Tree).
Code sample 3:
PayTermRemote remote = (PayTermRemote)(ref);
Description: Create PayTermRemote object by casting ref object.
Code sample 4:
PayTermRef ref = new PayTermRef();PayTermDesc desc = remote.findPayTermDesc(ref);
Description: Invoked Web service method findPayTermDesc as a remote call. Depending on the requirement, the user can vary the binding name and create a different object to invoke the Web service deployed to the server as a remote EJB call using the above code.
This section applies to PL/SQL Web service implementations and Java EE Web service implementations.
If an application is a core Java application, it can still call the Web services classes, but as POJO classes. In this case, the Web service classes act as simple Java classes, and there is no marshalling of XML involved, nor a remote call as an EJB.
The PL/SQL provider services need a database connection to call PL/SQL packages. In the case of a Web service call or an EJB call, the service gets the connection from the data source supplied by the Java EE container through resource injection. But in the case of a Java application, the data source is not available through this mechanism. The connection must be passed to the Web service class before invoking any business methods on it. To achieve this, the caller application must create an instance of the Web service class using the non-default constructor available in the service bean class. An example of the signature of the constructor is below:
public PayTermBean(Connection conn,Map<String,String> serviceContext)
Note: The bean class is available in the <appname>-service-ejb.jar for each Web service generated. For example, if the service name is PayTerm in the service definition XML, the name of the generated bean class will be PayTermBean. This is the class that should be used to call a Web service as a POJO. |
In the constructor shown above, the first parameter is for database connection. The second parameter is for the calling application to provide any additional parameters to the bean passed on to the PL/SQL package. When the bean is called as a Web service, an instance of ServiceOpContext class is created by using properties available from an instance of javax.xml.ws.WebServiceContext, available through resource injection. When the bean is called as EJB, an instance of ServiceOpContext is created from the values in an instance of javax.ejb.EJBContext, available through resource injection. But when the bean is called as a POJO, none of these objects is available. Therefore, a map has been added in the constructor so that the calling application can set the required values. If a null object is passed to the constructor for the map, an empty instance of ServiceOpContext is created. If the map contains a key named "user," a Principal object is created with the value of that key, and it is set in the ServiceOpContext object.
Complete the following steps.
Generate the .ear file for Web services and extract the following jar files from it:
retail-public-payload-java-beans-base-<version>.jar
retail-public-payload-java-beans-<version>.jar
oo-jaxb-bo-converter-<version>.jar
retail-soa-enabler-<version>.jar
<appname>-service-ejb.jar
Include these jar files in the classpath of the Java application that is going to invoke the beans as POJO classes.
Write the code to call the bean classes. (Sample code is provided below in this section.)
Run the calling class.
Note: The connection must be committed or rolled back by the calling application. Because there is no Java EE container available in this case, the bean cannot start and end a transaction. Therefore, it is the responsibility of the calling application to manage the transaction and the connection. In the following sample code, the calling class is committing the connection in case of a successful response from the bean, and it is rolling back the connection in case of any exception thrown by the Web service. The calling application determines how it wants to handle exceptions. |
public class PayTermService extends TestCase{ public void testPayTerm(){ Connection conn = null; try{ //get the database connection Class.forName("oracle.jdbc.OracleDriver"); conn =DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl","<username>","<password>"); //create map for ServiceOpContext Map<String,String> ctxMap = new HashMap<String, String>(); ctxMap.put("<username>", "<password>"); //instantiate the web service bean class PayTermBean bean = new PayTermBean(conn,ctxMap); //populate the input object for web service method PayTermRef ref = new PayTermRef(); ref.setTerms("terms"); ref.setTermsXrefKey("key"); //call the web service.here desc is the response object PayTermDesc desc = bean.findPayTermDesc(ref); //print the response object value System.out.println("desc value="+desc.getTerms()); //commit the database connection conn.commit(); }catch(Exception e){ e.printStackTrace(); try{ conn.rollback(); }catch(SQLException se){ se.printStackTrace(); } }finally{ if(conn !=null){ try{ conn.close(); }catch(SQLException se){ se.printStackTrace(); } } } } }
This section applies to PL/SQL Web service implementations and Java EE Web service implementations.
Complete the following steps using the WebLogic Server Administration Console:
If necessary, click Lock and Edit on the left navigation bar to enable the Install button
Navigate to the Deployments page.
Click Install.
Note: If the service application has already been installed, see "Redeploy the Service Application". |
The Locate deployment to install and prepare for deployment screen is displayed. Follow the instructions to locate the <service-name>.ear file on the WebLogic Server host
If rib-home is located on a host other than the Oracle WebLogic Server, select Upload Files. On the Upload a Deployment to the admin server screen, use the browse button to locate the <service-name>.ear file in the Deployment Archive.
Select the <service-name>.ear.
Click Next to move to Choose targeting style.
Select Install this deployment as an application.
Click Next to move to Select deployment targets. Here select the server to which you want the ear file to be deployed.
Click Next to move to Optional Settings. Here in the Security section, select the option Custom Roles and Policies:Use only roles and policies that are defined in the Administration Console. This is required to be able to attach roles and policies to secure the web services.
Click Next to move to Review your choices and click Finish.
Select No, I will review the configuration later.
Click Finish to deploy the application.
Click Activate Changes to commit changes to server.
Go to Deployments page, select the service application and click on Start > Servicing all requests to start the application and change the status to Active.
If the <service-name> application has already been deployed, follow these steps:
If the <service-name> application is running, select Stop and When Work Completes or Force Stop Now, depending on the environment. The recommended option always is When Work Completes.
Select Delete.
The Summary of Deployments should now not include the <service-name>.ear.
Return to "Deploying the Web Service".
To verify the Service installations using the Oracle WebLogic Administration Console, follow these steps.
Note: See Oracle WebLogic Server 12c Release 1 (12.1.3) documentation about the Administration console. |
Navigate to the Deployments screen.
Locate the <service-name>.ear on the Summary of Deployments screen.
Click plus sign next to the <service-name>.ear to expand the tree.
Locate the Web services section.
Click any Web service to move to Settings for <service name>.ear Service screen.
Click the Testing tab.
Click plus sign next to the service name to expand the tree.
Click the Test Client link to move to the WebLogic Test Client screen.
Select Ping Operation.
The test page will show the request message and the response message.
This section applies to PL/SQL Web service implementations and to Java EE Web service implementations.
To create a JDBC Data Source, follow these steps:
Log in to the WebLogic administration console. Use the URL, http://<host>:<listen port>/console/login/LoginForm.jsp.
Navigate the domain structure tree to Services/Data Sources.
Click New to start creating the new Data Source. Enter the required information:
Name: Enter any name for the data source.
JNDI name: This field must be set to jdbc/RetailWebServiceDs. The generated code for the service will use this JNDI name to look up the data source.
Select the transaction options for your data source and click Next.
Enter the database name and user information for the data source. Click Next.
The screen includes the connection information for your data source. Click Test Configuration to ensure the connection information is correct. If it is correct, the following message is displayed: "Connect test succeeded."
Click Next and select a server to deploy the data source to. This is not necessary at this point if you want to deploy the data source to a server at a later time.
Click Finish to complete the data source setup. The new data source is displayed on the data sources screen.
Click the new data source to view the properties. A default connection pool is created for the data source. Click the Connection Pool tab to view the connection pool properties.
The generated JDBC connection URL for the data source is displayed. The Oracle URL is formatted as follows: jdbc:oracle:thin:@<hostname>:<port>:<sid> (jdbc:oracle:thin:@<hostname>:<port>/<sid> for service connections).
For example: jdbc:oracle:thin:@localhost:1521:orc
If the database is a RAC database, the URL should be in the following format
jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = <host>)(PORT = <port>))(ADDRESS = (PROTOCOL = TCP)(HOST = <host>)(PORT = <port>))(LOAD_BALANCE = yes))(CONNECT_DATA =(SERVICE_NAME = <sid>)))
For example:
jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = dbhost1.example.com)(PORT = 1521))(ADDRESS = (PROTOCOL = TCP)(HOST = dbhost1.example.com)(PORT = 1521))(LOAD_BALANCE = yes))(CONNECT_DATA =(SERVICE_NAME = orcl)))
Restart the WebLogic instance to apply the data source changes.