Go to primary content
Oracle® Retail Integration Bus Service-Oriented Architecture Enabler Tool Guide
Release 16.0.023
E89674-01
  Go To Table Of Contents
Contents

Previous
Previous
 
Next
Next
 

9 Implementation Guidelines

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:

Important Note About this Chapter

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.

PL/SQL Service Consumer Implementation Notes

To set up the Web service consumer side proxies, complete the following steps:


Note:

See the section, "Important Note About this Chapter".

  1. loadjava -u <username>/<password>@<host>:<port>:<SID> -r -v -f -genmissing dbwsclientws.jar dbwsclientdb102.jar


    Note:

    loadjava is a utility available in Oracle Database.

  2. Edit and run *_grant.sql script as sysdba to give the user proper permission.

  3. 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
    

  4. Run the *Consumer_create.sql in the schema that will use this API. The schema owner is the user granted permission in Step 2.

  5. 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;
    

PL/SQL Provider Service Implementation Notes

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:


Note:

See the section, "Important Note About this Chapter".

  1. Create the PL/SQL service provider distribution file using the RSE tool. The output of this process is the .zip file.


    Note:

    See Chapter 4,"User Interface Usage".

  2. Extract the <service_name>.ProviderImplSpec.sql and <service_name>ProviderImplBody.sql files from the distribution zip file.

  3. These files will be modified to provide a PL/SQL implementation for the service.

  4. Extract the <service_name>-service.ear file from the distribution zip file. This file is the generated Web service that will be deployed.

  5. Create the JDBC data source.

  6. If not already deployed, deploy the Oracle Objects to the appropriate database user.


    Note:

    See the Oracle Retail Functional Artifact Generator Guide.

  7. 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.

  8. Install the modified PL/SQL packages to the database. They will be called by the Web service methods.

  9. Deploy the <service_name>.ear file to the Oracle WebLogic Server.

Java EE Service Consumer Implementation Notes

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:


Note:

See the section, "Important Note About this Chapter".

  1. Create a Web service client.

  2. 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.

  3. Additional JAX-WS library jars might be required.

  4. Deploy the service in the server.

  5. Invoke the Web service client to see the results.

Sample Client Code

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();
           }
       }
}

Java EE Service Provider Implementation Notes

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.


Note:

See the section, "Important Note About this Chapter".

Use Case 1: Complete the Generator Provided Stub Code Implementation

  1. Generate the distribution file using the RSE tool.

  2. Extract the <service_name>-ejb-impl-src.jar file from the zip file.

  3. Extract the <service_name>-service.ear file from the zip file.

  4. Add business logic code where indicated in the Impl java files.

  5. Use the java jar command to re-build the <service_name>-service-ejb-impl.jar file.

  6. Use the jar command to update .ear file with the new implementation jar.

  7. Deploy the .ear file to the server.

Use Case 2: Provide a Custom impl jar to the RSE Tool

  1. Create custom java classes that implement the <service_name>ServiceProvider interfaces contained in the <service_name>-service-ejb.jar file.

  2. Extract the ServiceProviderImplLookupFactory.properties file from the .ear file.

  3. Modify the properties file to point to your implementation classes for the services.

  4. Use the jar command to create a jar containing your implementation classes, as well as the modified properties file.

  5. Run the RSE tool again and provide the new custom implementation jar file.

  6. Extract and deploy the generated .ear file to the server.

Use Case 3: Package the Generated Service Classes in an Existing Application

  1. Generate the distribution file using the RSE tool.

  2. 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.

  3. 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.)

  4. 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.

  5. 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.

  6. 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

  7. 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.

  8. The .ear file is ready for deployment on the server.

Web Service Call as a Remote EJB Call

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.


Note:

See the section, "Important Note About this Chapter".

Prerequisites

The following is a list of prerequisites to implementation.

  1. Get the updated wlfullclient7-12.2.1.jar (integration-lib/lib)& retail-soa-enabler-<version>.jar (/integration-lib/) from the Repository.

  2. Run build.gradle for retail-soa-enabler.

  3. Generate the .ear and deploy it to server.

  4. Configure the data source in the server.

Procedure

Complete the following steps.

  1. Create a Java file containing the code below inside any package. (See code sample at the end of this section.)

  2. 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

  3. 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 Description

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.

Web Service Call as a POJO Call

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.

Procedure

Complete the following steps.


Note:

See the section, "Important Note About this Chapter".

  1. 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

  2. Include these jar files in the classpath of the Java application that is going to invoke the beans as POJO classes.

  3. Write the code to call the bean classes. (Sample code is provided below in this section.)

  4. 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.

Sample Code for POJO Invocation

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();
                            }
                      }
               }
       }
}

Deploying the Web Service

This section applies to PL/SQL Web service implementations and Java EE Web service implementations.


Note:

See the section, "Important Note About this Chapter".

Complete the following steps using the WebLogic Server Administration Console:

  1. If necessary, click Lock and Edit on the left navigation bar to enable the Install button

  2. Navigate to the Deployments page.

  3. Click Install.


    Note:

    If the service application has already been installed, see "Redeploy the Service Application".

  4. 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.

  5. Select the <service-name>.ear.

  6. Click Next to move to Choose targeting style.

  7. Select Install this deployment as an application.

  8. Click Next to move to Select deployment targets. Here select the server to which you want the ear file to be deployed.

  9. 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.

  10. Click Next to move to Review your choices and click Finish.

  11. Select No, I will review the configuration later.

  12. Click Finish to deploy the application.

  13. Click Activate Changes to commit changes to server.

  14. 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.

Redeploy the Service Application

If the <service-name> application has already been deployed, follow these steps:

  1. 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.

  2. Select Delete.

  3. The Summary of Deployments should now not include the <service-name>.ear.

  4. Return to "Deploying the Web Service".

Verify the Service Application Installation Using the Administration Console

To verify the Service installations using the Oracle WebLogic Administration Console, follow these steps.


Note:

See Oracle WebLogic Server 12c Release 1 (12.2.1.2) documentation about the Administration console.

  1. Navigate to the Deployments screen.

  2. Locate the <service-name>.ear on the Summary of Deployments screen.

  3. Click plus sign next to the <service-name>.ear to expand the tree.

  4. Locate the Web services section.

  5. Click any Web service to move to Settings for <service name>.ear Service screen.

  6. Click the Testing tab.

  7. Click plus sign next to the service name to expand the tree.

  8. Click the Test Client link to move to the WebLogic Test Client screen.

  9. Select Ping Operation.

  10. The test page will show the request message and the response message.

Creating a JDBC Data Source

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:


Note:

See the section, "Important Note About this Chapter".

  1. Log in to the WebLogic administration console. Use the URL, http://<host>:<listen port>/console/login/LoginForm.jsp.

  2. Navigate the domain structure tree to Services/Data Sources.

  3. 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.

  4. Select the transaction options for your data source and click Next.

  5. Enter the database name and user information for the data source. Click Next.

  6. 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."

  7. 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.

  8. Click Finish to complete the data source setup. The new data source is displayed on the data sources screen.

  9. 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.

  10. 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

  11. 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)))
    
  12. Restart the WebLogic instance to apply the data source changes.