This chapter describes how to use the spring framework to integrate components that use Java interfaces into SOA composite applications. Oracle SOA Suite uses the spring framework functionality provided by the WebLogic Service Component Architecture (SCA) of Oracle WebLogic Server. This chapter also describes how to integrate components that use Java interfaces with components that use WSDL files in the same SOA composite application.
This chapter includes the following sections:
Section 49.1, "Introduction to the Spring Service Component"
Section 49.2, "Integration of Java and WSDL-Based Components in the Same SOA Composite Application"
Section 49.3, "Creating a Spring Service Component in Oracle JDeveloper"
Section 49.4, "Defining Custom Spring Beans Through a Global Spring Context"
Section 49.6, "Spring Service Component Integration in the Fusion Order Demo"
For more information about the WebLogic SCA functionality used by Oracle SOA Suite, see Oracle Fusion Middleware Developing WebLogic SCA Applications for Oracle WebLogic Server.
The spring framework is a lightweight container that makes it easy to use different types of services. Lightweight containers can accept any JavaBean, instead of specific types of components.
WebLogic SCA enables you to use the spring framework to create Java applications using plain old Java objects (POJOs) and expose components as SCA services and references. In SCA terms, a WebLogic spring framework SCA application is a collection of POJOs plus a spring SCA context file that wires the classes together with SCA services and references.
You can use the spring framework to create service components and wire them within a SOA composite application using its dependency injection capabilities. SCA can extend spring framework capabilities as follows:
Publish spring beans as SCA component services that can be accessed by other SCA components or by remote clients
Provide spring beans for service references wired to services of other components
Like all service components, spring components have a componentType
file. The interfaces defined in the componentType
file use the interface.java
definition to identify their service and reference interfaces.
Services are implemented by beans and are targeted in the spring context file. References are supplied by the runtime as implicit (or virtual) beans in the spring context file.
You can also integrate Enterprise JavaBeans with SOA composite applications through use of Java interfaces (with no requirement for SDO parameters). For information, see Chapter 36, "Integrating Enterprise JavaBeans with SOA Composite Applications."
For more information about the spring framework, visit the following URL:
http://www.osoa.org/display/Main/SCA+and+Spring+Framework
In releases before 11g Release 1 11.1.1.3, components in SOA composite applications were entirely WSDL-based. Starting with 11g Release 1 11.1.1.3, you can integrate components using Java interfaces and WSDL files in a SOA composite application in the SOA Composite Editor. As an example, this integration enables a spring service component to invoke an Oracle BPEL Process Manager or an Oracle Mediator service component to invoke an Enterprise JavaBean, and so on.
The following types of component integrations are supported:
Java components to WSDL components
If you drag a wire from a Java interface (for example, Enterprise JavaBeans service or spring service component) to a component that does not support Java interfaces (for example, Oracle Mediator, Oracle BPEL Process Manager, or others) a compatible WSDL is generated for the component interfaces.
WSDL components to Java components
If you drag a wire from a WSDL interface to a component that does not support WSDL files (for example, a spring service component), a compatible Java interface is automatically generated. It is also possible to wire an existing WSDL interface to an existing Java interface. In this case, there is no checking of the compatibility between the WSDL and Java interfaces. You must ensure that it is correct.
Java components to Java components
If you create a spring service component, you can automatically configure it with Java interface-based EJB service and reference binding components. No WSDL files are required.
When wiring any two service components (or a service component with a binding component), each end of the wire has an interface defined. With XML, those interfaces must have the same WSDL definition, and are defined with interface.wsdl
in the composite.xml
file or component
.componentType
file.
From the JAX-WS point of view, when wiring a Java interface (which is defined by interface.java
) to a WSDL interface, it is assumed that the two interfaces are compatible. This is typically enforced and automated by Oracle JDeveloper.
Note:
Only use Oracle JDeveloper to create and modify thecomposite.xml
, componentType
, and spring context files described in this section. Do not directly edit these files in Source view. These examples are provided to show you how Java interfaces and WSDL files are integrated in a SOA composite application. Use of Oracle JDeveloper to achieve this functionality is described in subsequent sections of this chapter.For example, assume you have a Java interface for a service, as shown in Example 49-1.
Example 49-1 Java Interface for a Service
public interface PortfolioService { public double getPorfolioValue(String portfolioId); }
Assume the implementation can use an additional StockQuote
service that is implemented by another component that may be a BPEL process, an external web service, or an EJB. Example 49-2 provides details.
Example 49-2 Additional Java Interface for a Service
public interface StockQuote { public double getQuote (String symbol); }
The componentType
file for the spring framework lists the PortfolioService
service and the StockQuote
service with the interface.java
definitions. Example 49-3 provides details.
Example 49-3 componentType File
<componentType xmlns="http://xmlns.oracle.com/sca/1.0"> <service name="PortfolioService "> <interface.java interface="com.bigbank.PortfolioService"/> </service> <reference name="StockService"> <interface.java interface="com.bigbank.StockQuote"/> </reference> </componentType>
The implementation class implements the service interface and provides a setter for the reference interface. Example 49-4 provides details.
Example 49-4 Implementation of the Service Interface
public class PortfolioServiceImpl implements PortfolioService { StockQuote stockQuoteRef; public void setStockService (StockQuote ref) { stockQuoteRef = ref; } public double getPorfolioValue(String portfolioId) { //-- use stock service //-- return value } }
The spring context file calls out the services and references and binds them to the implementation. Example 49-5 provides details.
Example 49-5 Callout of Services and References by the Spring Context
<beans ...> <sca:service name="PortfolioService" type="com.bigbank.PortfolioService" target="impl"> </sca:service> <sca:reference name="StockService" type="com.bigbank.StockQuote"> </sca:reference> <bean id ="impl" class ="com.bigbank.PortfolioServiceImpl"> <property name="stockService" ref="StockService"/> </bean> </beans>
The composite.xml
file of the composite defines the components and references. Example 49-6 provides details.
Example 49-6 Definition of Components and References in the composite.xml File
<composite ...> <import location="PortfolioService.wsdl" /> <service name="PortfolioService"> <interface.wsdl interface="http://bigbank.com/#wsdl.interface(PortfolioService)" /> <binding.ws port="http://bigbank.com/#wsdl.endpoint(PortfolioService/PortfolioServicePort)"/> </service> <wire> <source.uri>PortfolioService</source.uri> <target.uri>PortfolioComp/PortfolioService</target.uri> </wire> <component name="PortfolioComp"> <implementation.spring src="spring-context.xml"/> </component> <wire> <source.uri>PortfolioService/StockService</source.uri> <target.uri>StockService</target.uri> </wire> <reference name="StockService"> <interface.java interface="com.bigbank.StockQuote"/> <binding.ejb uri="StockService#com.bigbank.StockQuote"/> </reference> </composite>
Oracle SOA Suite uses callbacks for both interface.wsdl
and interface.java
. However, the concept of callbacks does not exist in the spring framework. For Oracle SOA Suite services and references, a callback is specified (in the metadata) as a second port type for interface.wsdl
or a second Java name for interface.java
. The spring metadata has only sca:services
and sca:references
and no way to specify a callback.
To design a callback with spring, you must provide sca:services
and sca:references
with a specific name. If you create both a sca:service
and sca:reference
using the naming conventions of some
Service
and some
ServiceCallback
, Oracle SOA Suite recognizes this convention and creates a single service or reference with a callback.
For example, assume you create the syntax shown in Example 49-7 in the spring context file with the spring editor in Oracle JDeveloper:
Example 49-7 Callbacks with the Spring Service Component
<sca:service name="StockService" type="oracle.integration.platform.blocks.java.callback.StockService" target="impl" /> <sca:reference name="StockServiceCallback" type="oracle.integration.platform.blocks.java.callback.StockServiceReply" />
Oracle SOA Suite automatically creates a single service (in the spring componentType
file) as shown in Example 49-8:
<service name="StockService">
<interface.java
interface="oracle.integration.platform.blocks.java.callback.StockService"
callbackInterface="oracle.integration.platform.blocks.java.callback.StockServiceRe
ply"/>
</service>
In the SOA Composite Editor, if a spring interface.java
with a callback interface is dragged to a WSDL component (for example, Oracle BPEL Process Manager, Oracle Mediator, or others), a WSDL with two port types is generated (technically, a wrapper WSDL, which is a WSDL that imports two other WSDLs, each having a single port type).
If you drag a WSDL or Java interface that has a callback to a spring service component, a single interface is displayed in the SOA Composite Editor. However, inside the spring editor, you find both a sca:service
and sca:reference
that have the same naming conventions (some
Service
and some
ServiceCallback
).
This section describes how to create a spring service component and wire the component as follows in Oracle JDeveloper:
To Java interface-based EJB services and references (Java-to-Java integration)
To an Oracle Mediator service component (Java-to-WSDL integration)
For an overview of spring service component integration in the Fusion Order Demo, see Section 49.6, "Spring Service Component Integration in the Fusion Order Demo."
To create a spring service component in Oracle JDeveloper:
From the Component Palette, drag a Spring Context service component into the SOA Composite Editor, as shown in Figure 49-1.
Figure 49-1 Spring Context Service Component
The Create Spring dialog is displayed.
In the Name field, enter a name for the spring service component. The name becomes both the component name and the spring context file name. Figure 49-2 provides details.
You can also select Use Existing Context and click Browse to select an existing spring file. For example, you may want to import a spring context that was created in Oracle JDeveloper, but outside of Oracle SOA Suite. If you browse and select a spring context from another project, it is copied to the SOA project.
Note:
A standalone spring version of WebLogic SCA is also available for use. This version is typically used outside of Oracle SOA Suite. This version is accessible by selecting Spring 2.5 JEE from the Component Palette while inside the spring editor.Click OK.
A spring icon is displayed in the SOA Composite Editor.
Double-click the icon to display the contents of the spring context in the spring editor.
<?xml version="1.0" encoding="windows-1252" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sca="http://xmlns.oracle.com/weblogic/weblogic-sca" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-2.5.xsd http://xmlns.oracle.com/weblogic/weblogic-sca META-INF/weblogic-sca.xsd"> <!--Spring Bean defintions go here--> </beans>
From the Component Palette, select Weblogic SCA from the dropdown list.
The list is refreshed to display the selections shown in Figure 49-3.
Drag a Service icon into the spring editor.
The Insert Service dialog appears.
Complete the fields shown in Table 49-1 to define the target bean and Java interface.
Table 49-1 Insert Service Dialog
Field | Description |
---|---|
name |
Enter a name. |
target |
Enter the target bean. This action enables you to expose the bean as a service. Note: Ensure that this target exists. There is no validation support that checks for the existence of this target. |
type |
Enter the Java interface. |
When complete, the Insert Service dialog looks as shown in Figure 49-4.
Click OK.
The target bean becomes the service interface in the spring context.
<?xml version="1.0" encoding="windows-1252" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:sca="http://xmlns.oracle.com/weblogic/weblogic-sca"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/lang
http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/tool
http://www.springframework.org/schema/tool/spring-tool-2.5.xsd
http://xmlns.oracle.com/weblogic/weblogic-sca META-INF/weblogic-sca.xsd">
<!--Spring Bean defintions go here-->
<sca:service name="scaserv1" target="ep" type="oracle.mypackage.myinterface"/>
</beans>
Note that if you close the spring editor and return to the SOA Composite Editor, you see that a handle has been added to the left side of the spring service component, as shown in Figure 49-5.
Return to the spring editor.
Drag a Reference icon from the list shown in Figure 49-3 into the spring editor.
The Insert Reference dialog is displayed.
Complete the dialog, as shown in Table 49-2, and click OK.
Table 49-2 Insert Reference Dialog
Field | Description |
---|---|
name |
Enter a name. |
type |
Enter the Java interface. |
When complete, the spring context displays the service and reference in the spring editor.
<?xml version="1.0" encoding="windows-1252" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sca="http://xmlns.oracle.com/weblogic/weblogic-sca" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-2.5.xsd http://xmlns.oracle.com/weblogic/weblogic-sca META-INF/weblogic-sca.xsd"> <!--Spring Bean defintions go here--> <sca:service name="scaserv1" target="ep" type="oracle.mypackage.myinterface"/> <sca:reference name="scaref1" type="external.bean.myInterface"/> </beans>
Close the spring context file, as shown in Figure 49-6.
Note that a handle is added to the right side of the spring service component, as shown in Figure 49-7.
Drag the left handle into the Exposed Services swimlane to create a service binding component, as shown in Figure 49-8.
You are prompted to select to expose the service as either a web service or as an EJB service, as shown in Figure 49-9.
EJB: This exposes the EJB service through a Java interface; this selection does not require the use of a WSDL file.
Web Service: This exposes the web service through a SOAP WSDL interface. If you select this option, a WSDL is generated from the Java Interface for compatibility with the spring service component.
Select to expose this service as either an EJB or Web service. A service is automatically created in the Exposed Services swimlane and wired to the spring service component (for this example, EJB was selected). Figure 49-10 provides details.
Figure 49-10 EJB Service Binding Component Wired to the Spring Service Component
Double-click the EJB service to display the automatically completed configuration, as shown in Figure 49-11. The configuration details were created from the values you entered in the Insert Service dialog in Step 7.
Figure 49-11 EJB Service Dialog in Exposed Services Swimlane
Replace the default JNDI name that was automatically generated with the name applicable to your environment.
Close the dialog.
Drag the right handle of the spring service component into the External References swimlane to create a reference binding component.
You are prompted with the same spring type option message as shown in Step 13.
Select an option to expose this reference. A reference is automatically created in the External References swimlane and wired to the spring service component (for this example, EJB was selected). Figure 49-12 provides details.
Figure 49-12 EJB Reference Binding Component Wired to the Spring Service Component
Double-click the EJB reference to display the automatically completed configuration, as shown in Figure 49-13. The configuration details were created from the values you entered in the Insert Reference dialog in Step 11.
Figure 49-13 EJB Reference Dialog in External References Swimlane
Close the dialog and return to the SOA Composite Editor, as shown in Figure 49-14.
Figure 49-14 Java Interface-Based EJB Service and Reference Binding Components
Place the cursor over both the right handle of the service (as shown in Figure 49-15) and the left handle of the spring service component (as shown in Figure 49-16). The Java interface is displayed.
Figure 49-16 Java Interface of Spring Service Component
Perform the same action on the right handle of the spring service component and the left handle of the reference binding component to display its Java interface.
If you want to view the interfaces for the spring service component in the componentType
file, select this file in the Application Navigator. The interfaces for both components are defined by interface.java
.
<?xml version="1.0" encoding="UTF-8" ?> <!-- Generated by Oracle SOA Modeler version 1.0 at [2/27/10 1:13 PM]. --> <componentType xmlns="http://xmlns.oracle.com/sca/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ui="http://xmlns.oracle.com/soa/designer/"> <service name="scaserv1"> <interface.java interface="oracle.mypackage.myinterface"/> </service> <reference name="scaref1"> <interface.java interface="external.bean.myInterface"/> </reference> </componentType>
In the Application Navigator, select the composite.xml
file to display similar details.
<service name="scaserv1"> <interface.java interface="oracle.mypackage.myinterface"/> <binding.ejb uri="scaserv1_ejb_ep" ejb-version="EJB3"/> </service> <component name="MySpring"> <implementation.spring src="MySpring.xml"/> </component> <reference name="scaref1"> <interface.java interface="external.bean.myInterface"/> <binding.ejb uri="scaref1_ejb_ep" ejb-version="EJB3"/> </reference> <wire> <source.uri>orderprocessor_client_ep</source.uri> <target.uri>OrderProcessor/orderprocessor_client</target.uri> </wire> <wire> <source.uri>scaserv1</source.uri> <target.uri>MySpring/scaserv1</target.uri> </wire> <wire> <source.uri>MySpring/scaref1</source.uri> <target.uri>scaref1</target.uri> </wire> </composite>
If you wire the right handle of the spring service component to an XML-based component such as Oracle Mediator instead of the Java interface-based EJB reference, a compatible WSDL file is generated. The following steps provide details.
Drag the right handle of the spring service component to the Oracle Mediator, as shown in Figure 49-17.
Figure 49-17 Integration of Spring Service Component and Oracle Mediator
Click OK when prompted to acknowledge that a compatible interface was created from the Oracle Mediator WSDL file.
Figure 49-18 Java File Creation from the Oracle Mediator WSDL File
If you drag a wire between a Java interface and a WSDL-based component, and the WSDL file with the default name (based on the Java Interface name) already exists, you are prompted with four options. Click Cancel to cancel creation of the wire. Figure 49-19 provides details.
Place the cursor over both the right handle of the spring service component (as shown in Figure 49-20) and the left handle of the Oracle Mediator (as shown in Figure 49-21) to display the compatible interface.
Figure 49-20 Spring Service Component Interface
Double-click the spring service component to display the contents of the spring context file in the spring editor.
<?xml version="1.0" encoding="windows-1252" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sca="http://xmlns.oracle.com/weblogic/weblogic-sca" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/tool http://www.springframework.org/schema/tool/spring-tool-2.5.xsd http://xmlns.oracle.com/weblogic/weblogic-sca META-INF/weblogic-sca.xsd"> <!--Spring Bean defintions go here--> <sca:service name="scaserv1" target="ep" type="oracle.mypackage.myinterface"/> <sca:reference type="mediator1.project1.application4.com.oracle.xmlns.Execute_ ptt" name="Mediator1.Mediator1"/> </beans>
For more information about integrating components that use Java interfaces with components that use WSDL files in the same SOA composite application, see Section 49.6, "Spring Service Component Integration in the Fusion Order Demo."
Notes:
When integrating a component that uses a Java interface with a component that uses a WSDL file in the SOA Composite Editor, if a specific interface class is not found in the classpath, but the source file does exist in the SOA project, the JAR files in the SCA-INF/lib
directory of the current loader are automatically refreshed to discover the interface class.
You can also create BPEL process partner links with services that uses Java interfaces. You select this type of service in the Service Explorer dialog when creating a partner link. For more information, see Section 4.3, "Introduction to Partner Links."
When a Java-to-WSDL conversion fails because of a bad Java class and you modify the Java code to correct the problem, you must restart Oracle JDeveloper. Not doing so results in a Java-to-WSDL conversion failure because the new class does not get reloaded.
You can define custom spring beans through a global spring context definition. This configuration enables you to define these beans only once, at the global level.
To define custom spring beans through a global spring context:
Add the custom spring bean definitions into the following file:
SOA_HOME/soa/modules/oracle.soa.ext_11.1.1/classes/
springse-extension-global-beans.xml
Add the corresponding classes in either the lib
directory (as a JAR file) or the classes directory (as extracted files of the JAR file).
SOA_HOME/soa/modules/oracle.soa.ext_11.1.1/lib | classes
For more information, see the readme.txt
file located in the following directory:
SOA_HOME/soa/modules/oracle.soa.ext_11.1.1
Note:
A server restart is required to pick up newly added spring beans.Oracle SOA Suite provides the following predefined spring beans:
headerHelperBean
: For getting and setting header properties.
instanceHelperBean
: For getting the following information:
The instance ID of the composite instance currently running.
The instance ID of the component instance currently running.
The composite distinguished name (DN) containing the component.
The name of the spring service component.
loggerBean
: For providing context-aware logging messages.
The predefined spring beans are automatically injected into the spring service component. However, you must explicitly integrate the predefined spring beans into a SOA composite application by providing a reference to the bean in the spring context file.
For an example of how to reference loggerBean
and headerHelperBean
in a spring context file, see Section 49.5.4, "How to Reference Predefined Spring Beans in the Spring Context File."
Example 49-9 shows the IHeaderHelperBean.java
interface for the headerHelperBean
bean.
Example 49-9 IHeaderHelperBean.java Interface
package oracle.soa.platform.component.spring.beans; /** * Interface for getting and setting header properties. * These properties will be set on the normalized message - and passed on * to the respective reference that the local reference is wired to on * composite level. * <br/> * In order to use this bean from within your context, declare property * with ref="headerHelperBean". E.g. * <property name="headerHelper" ref="<b>headerHelperBean</b>"/> */ public interface IHeaderHelperBean { /** * Get a property from the normalized message header. Note that these * properties are defined, and are the same ones, one can get/set via * mediator or bpel process * @param pKey the property key, case sensitive * @return the value, or null in case not found */ public String getHeaderProperty (String pKey); /** * Set a property on the normalized message header. Note that these * properties are defined, and are the same ones, one can get/set via * mediator or bpel process * @param pKey the property key, case sensitive * @param pValue the value to be set */ public void setHeaderProperty (String pKey, String pValue); }
Example 49-10 shows the IInstanceHelperBean.java
interface for the instanceHelperBean
bean.
Example 49-10 IInstanceHelperBean.java Interface
package oracle.soa.platform.component.spring.beans; import oracle.integration.platform.instance.engine.ComponentInstanceContext; /** * Instancehelper Bean, gives access to composite / component + instance information * <br/> * In order to use this bean from within your context, declare property * with ref="instanceHelperBean". E.g. * <property name="instanceHelper" ref="<b>instanceHelperBean</b>"/> */ public interface IInstanceHelperBean { /** * Returns the instance id of the composite instance currently running * @return the composite instance id */ public String getCompositeInstanceId (); /** * Returns the instance id of the component instance currently running * @return the component instance id */ public String getComponentInstanceId (); /** * Returns the composite dn containing this component * @return the composite dn */ public String getCompositeDN (); /** * Returns the name of this spring component * @return the component name */ public String getComponentName (); }
Example 49-11 shows the ILoggerBean.java
interface for the loggerBean
bean.
Example 49-11 ILoggerBean.java Interface
package oracle.soa.platform.component.spring.beans; import java.util.logging.Level; /** * Logger bean interface, messages will be logged as * [<composite instance id>/<component instance id>] <message> * <br/> * In order to use this bean from within your context, declare property * with ref="loggerBean". E.g. * <property name="logger" ref="<b>loggerBean</b>"/> * @author clemens utschig */ public interface ILoggerBean { /** * Log a message, with Level.INFO * @param message */ public void log (String message); /** * Log a message with desired level * @param pLevel the log level * @param message the message to log */ public void log (Level pLevel, String message); /** * Log a throwable with the desired level * @param level the level to log with * @param message the message * @param th the exception (throwable) to log */ public void log (Level level, String message, Throwable th); }
You create references to the predefined beans in the spring context file.
To reference predefined spring beans in the spring context file:
Open the spring context file in Source view in Oracle JDeveloper.
Add references to the loggerBean
and headerHelperBean
predefined beans.
<?xml version="1.0" encoding="windows-1252" ?> . . . . . . <!-- The below sca:service(s) corresponds to the services exposed by the component type file: SpringPartnerSupplierMediator.componentType --> <!-- expose the InternalPartnerSupplierMediator + EJB as service <service name="IInternalPartnerSupplier"> <interface.java interface="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> </service> --> <sca:service name="IInternalPartnerSupplier" target="InternalPartnerSupplierMediator" type="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> <!-- expose the InternalPartnerSupplierMediator + Mock as service <service name="IInternalPartnerSupplierSimple"> <interface.java interface="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> </service> --> <sca:service name="IInternalPartnerSupplierSimple" target="InternalPartnerSupplierMediatorSimple" type="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> <!-- the partner supplier mediator bean with the mock ep --> <bean id="InternalPartnerSupplierMediatorSimple" class="com.otn.sample.fod.soa.internalsupplier.InternalSupplierMediator" scope="prototype"> <!-- inject the external partner supplier bean --> <property name="externalPartnerSupplier" ref="IExternalPartnerSupplierServiceMock"/> <!-- inject the quoteWriter --> <property name="quoteWriter" ref="WriteQuoteRequest"/> <!-- context aware logger, globally available bean [ps3] --> <property name="logger" ref="loggerBean"/> <!-- headerHelper bean --> <property name="headerHelper" ref="headerHelperBean"/> </bean> <!-- the partner supplier mediator bean with the ejb --> <bean id="InternalPartnerSupplierMediator" class="com.otn.sample.fod.soa.internalsupplier.InternalSupplierMediator" scope="prototype"> <!-- inject the external partner supplier bean --> <property name="externalPartnerSupplier" ref="IExternalPartnerSupplierService"/> <!-- inject the quoteWriter --> <property name="quoteWriter" ref="WriteQuoteRequest"/> <!-- context aware logger, globally available bean [ps3] --> <property name="logger" ref="loggerBean"/> <!-- headerHelper bean --> <property name="headerHelper" ref="headerHelperBean"/> </bean> . . . . . .
This syntax is included in the spring context file of the Partner Supplier Composite application of the Fusion Order Demo. For more information about the Fusion Order Demo, see Section 49.6, "Spring Service Component Integration in the Fusion Order Demo."
The Partner Supplier Composite application of the Fusion Order Demo demonstrates how the spring service component obtains a price quote from a partner warehouse. Figure 49-22 shows the SOA Composite Editor for this composite application.
Figure 49-22 Partner Supplier Composite with Spring Service Component
IInternalPartnerSupplier is exposed as an external client service in the Exposed Services swimlane.
The Oracle Mediator service component PartnerSupplierMediator routes client requests differently based on the amount of the quote:
Quotes below $2000 are routed to Oracle BPEL Process Manager.
Requests that are more than $2000 and less than $3000 are routed to the SpringPartnerSupplierMediator spring service component. An external EJB reference binding component IExternalPartnerSupplierService is invoked to obtain a quote. An external file adapter WriteQuoteRequest is invoked for writing the quote results to a file.
Requests greater than $3000 are routed to the SpringPartnerSupplierMediator spring service component. However, these requests are not routed to the external EJB reference binding component. Instead they are handled internally by implementing the EJB interface. The external file adapter WriteQuoteRequest is also invoked for writing the quote results to a file.
Figure 49-23 provides an overview of this behavior.
For requests that are more than $2000 and less than $3000, the target bean InternalPartnerSupplierMediator is exposed as a service. The Java interface IInternalPartnerSupplier is used. In the External References swimlane, the Java interface IExternalPartnerSupplierService is exposed as an external EJB for obtaining a quote.
For requests that are more than $3000, the target bean InternalPartnerSupplierMediatorSimple is exposed as a service. The Java interface IInternalPartnerSupplier is used. The internal Java Interface IExternalPartnerSupplierServiceMock is used to obtain a quote. The IExternalPartnerSupplierService reference in the External References swimlane is not invoked.
In the External References swimlane, since the WriteQuoteRequest reference uses a WSDL-based file adapter and does not support Java interfaces, a compatible WSDL file is generated.
Figure 49-23 Spring Architecture in Fusion Order Demo
Example 49-12 shows the IInternalPartnerSupplier.java
file. IInternalPartnerSupplier
is implemented by InternalSupplierMediator
.
Example 49-12 IInternalPartnerSupplier.java
package com.otn.sample.fod.soa.internalsupplier;
import
com.otn.sample.fod.soa.internalsupplier.exception.InternalSupplierException;
import java.util.List;
/**
* The interface for the spring based service, with a typed list.
*
* !!! ATTENTION !!!
* This interface was used to generate the wsdl
* (IInternalPartnerSupplierService.wsdl) - DO NOT MODIFY!
*
*/
public interface
IInternalPartnerSupplier
{
/**
* Get a price for a list of orderItems
* @param pOrderItems the list of orderitems
* @return the price
*/
public double getPriceForOrderItemList(List<Orderitem> pOrderItems)
throws InternalSupplierException;
}
The SpringPartnerSupplierMediator.componentType
file in Example 49-13 shows the services and references defined for the spring service component shown in Figure 49-23.
Example 49-13 SpringPartnerSupplierMediator.componentType File
<?xml version="1.0" encoding="UTF-8" ?> <!-- Generated by Oracle SOA Modeler version 1.0 at [7/16/09 2:36 PM]. --> <componentType xmlns="http://xmlns.oracle.com/sca/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ui="http://xmlns.oracle.com/soa/designer/"> <service name="IInternalPartnerSupplier"> <interface.java interface="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> </service> <service name="IInternalPartnerSupplierSimple"> <interface.java interface="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> </service> <reference name="IExternalPartnerSupplierService"> <interface.java interface="com.otn.sample.fod.soa.externalps.IExternalPartnerSupplierService"/> </reference> <reference name="WriteQuoteRequest"> <interface.java interface="writequoterequest.partnersuppliercomposite.weblogicfusionorderdemo.file .adapter.pcbpel.com.oracle.xmlns.Write_ptt"/> </reference> </componentType>
Example 49-14 shows the SpringPartnerSupplierMediator.xml
spring context file.
Example 49-14 SpringPartnerSupplierMediator.xml spring context File
<?xml version="1.0" encoding="windows-1252" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:sca="http://xmlns.oracle.com/weblogic/weblogic-sca"> <!-- The below sca:service(s) corresponds to the services exposed by the component type file: SpringPartnerSupplierMediator.componentType --> <!-- expose the InternalPartnerSupplierMediator + EJB as service <service name="IInternalPartnerSupplier"> <interface.java interface="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> </service> --> <sca:service name="IInternalPartnerSupplier" target="InternalPartnerSupplierMediator" type="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> <!-- expose the InternalPartnerSupplierMediator + Mock as service <service name="IInternalPartnerSupplierSimple"> <interface.java interface="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> </service> --> <sca:service name="IInternalPartnerSupplierSimple" target="InternalPartnerSupplierMediatorSimple" type="com.otn.sample.fod.soa.internalsupplier.IInternalPartnerSupplier"/> <!-- the partner supplier mediator bean with the mock ep --> <bean id="InternalPartnerSupplierMediatorSimple" class="com.otn.sample.fod.soa.internalsupplier.InternalSupplierMediator" scope="prototype"> <!-- inject the external partner supplier bean --> <property name="externalPartnerSupplier" ref="IExternalPartnerSupplierServiceMock"/> <!-- inject the quoteWriter --> <property name="quoteWriter" ref="WriteQuoteRequest"/> <!-- context aware logger, globally available bean [ps3] --> <property name="logger" ref="loggerBean"/> <!-- headerHelper bean --> <property name="headerHelper" ref="headerHelperBean"/> </bean> <!-- the partner supplier mediator bean with the ejb --> <bean id="InternalPartnerSupplierMediator" class="com.otn.sample.fod.soa.internalsupplier.InternalSupplierMediator" scope="prototype"> <!-- inject the external partner supplier bean --> <property name="externalPartnerSupplier" ref="IExternalPartnerSupplierService"/> <!-- inject the quoteWriter --> <property name="quoteWriter" ref="WriteQuoteRequest"/> <!-- context aware logger, globally available bean [ps3] --> <property name="logger" ref="loggerBean"/> <!-- headerHelper bean --> <property name="headerHelper" ref="headerHelperBean"/> </bean> <!-- mock bean for the IExternalPartnerSupplierService --> <bean id="IExternalPartnerSupplierServiceMock" class="com.otn.sample.fod.soa.externalps.test.MockExternalPartnerSupplierTest"/> <!-- Use a reference from the outside world based on the IExternalPartnerSupplierService interface. The below is specified on the SpringPartnerSupplierMediator.componentType - and wired to an external EJB binding. <reference name="IExternalPartnerSupplierService"> <interface.java interface="com.otn.sample.fod.soa.externalps.IExternalPartnerSupplierService"/> </reference> --> <sca:reference name="IExternalPartnerSupplierService" type="com.otn.sample.fod.soa.externalps.IExternalPartnerSupplierService"/> <!-- <reference name="WriteQuoteRequest"> <interface.java interface="writequoterequest.partnersuppliercomposite.weblogicfusionorderdemo.file .adapter.pcbpel.com.oracle.xmlns.Write_ptt"/> </reference> --> <sca:reference type="writequoterequest.partnersuppliercomposite.weblogicfusionorderdemo.file.adap ter.pcbpel.com.oracle.xmlns.Write_ptt" name="WriteQuoteRequest"/> </beans>
For information on downloading and installing the Fusion Order Demo and using the Partner Supplier Composite, see Section 3.2, "Setting Up the Fusion Order Demo Application."
After download, see the following Fusion Order Demo directory for Java code samples used by the Partner Supplier Composite:
CompositeServices\PartnerSupplierComposite\src\com\otn\sample\fod\soa
Your Java code may include vectors. However, vectors cannot be serialized to XML without declaring the content POJOs. The following example provides an overview of how to resolve this issue and uses code samples from the Fusion Order Demo.
To use EJBs with Java vector type parameters:
Assume your Java code includes vectors, as shown in Figure 49-24.
Create an EJB binding reference based on the Java interface class and the JNDI name. Figure 49-25 provides an example.
Figure 49-25 EJB Binding Reference Creation
Wire the EJB reference to the spring service component, as shown in Figure 49-26.
Figure 49-26 EJB Reference Wired to Spring Service Component
A new reference is created in the spring context file. Figure 49-27 provides details.
Figure 49-27 Reference Addition to Spring Context File
Enable spring to inject the reference into the class by declaring a public member of type IExternalPartnerSupplierService
. Figure 49-28 provides details.
Add a property with the name of the member to IExternalPartnerSupplierService
and refer to the ExternalPartnerSupplier
reference bean. Figure 49-29 provides details.
Figure 49-29 Property Added with Name of the Member
This converts the vectors to EJB parameters.
Oracle Fusion Middleware provides support for using Java Architecture for XML Binding (JAXB) and the EclipseLink O/X-Mapper (OXM) to map Java classes to XML data. You can store and retrieve data in memory in any XML format without implementing a specific set of XML routines for the program's class structure. This support enables you to perform the following:
Map Java objects to XML data
Map XML data back to Java objects
For design information about external metadata for JAXB mappings, visit the following URL:
http://wiki.eclipse.org/EclipseLink/DesignDocs/277920
For information about JAXB OXM and the OXM mapping file (eclipselink-oxm.xsd
), visit the following URLs:
http://wiki.eclipse.org/EclipseLink/FAQ/WhatIsMOXy http://wiki.eclipse.org/EclipseLink/Examples/MOXy http://wiki.eclipse.org/Category:XML
You can also map Java classes to XML data when integrating Enterprise JavaBeans with SOA composite applications. For more information, see Chapter 36, "Integrating Enterprise JavaBeans with SOA Composite Applications."
Oracle SOA Suite extends JAXB and OXM file support through use of an extended mapping (EXM) file. If an EXM file is present in the class path of the design time project, then it can be used for Java-to-WSDL conversions. The EXM file provides data binding metadata in the following situations:
When you cannot add the JAXB annotations into the Java source and must specify them separately
When scenarios are not covered by JAXB (for example, with top level elements like method return types or parameter types)
The external JAXB annotations can be specified either directly in the EXM file or included in the separate TopLink JAXB mapping OXM file that can be referred to from the EXM file.
Oracle SOA Suite design time supports placing the EXM file in either the source path (SCA-INF/src
) or the class path (SCA-INF/classes
or a JAR in SCA-INF/lib
).
Placing the EXM file in the source path (SCA-INF/src
) enables you to edit the EXM using Oracle JDeveloper (files in the class path do not appear in the Application Navigator in Oracle JDeveloper). When project compilation is complete, the EXM file (and any XML files that it imports) is copied to the class path (SCA-INF/classes
) for deployment.If the EXM file is in the source path, it must still be in the same corresponding directory structure.
Example 49-15 and Example 49-16 provide examples of EXM files.
<java-web-service-endpoint xmlns="http://xmlns.oracle.com/weblogic/weblogic-wsee-databinding" xmlns:oxm="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" databinding="toplink.jaxb"> <xml-schema-mapping> <toplink-oxm-file java-package="weblogic.wsee.databinding.internal.test.toplink" file-path="./person-oxm.xml"/> </xml-schema-mapping> <!-- <web-service name="hello-ws" target-namespace="hello-ns"/> <java-methods> <java-method name="hello" oxm:xml-mixed="false"> <oxm:xml-elements> <oxm:xml-element type="java.lang.Integer"/> </oxm:xml-elements> <web-result name="result"/> <java-params> <java-param oxm:xml-mixed="false"> <oxm:xml-elements> <oxm:xml-element type="java.lang.String"/> </oxm:xml-elements> <web-param name="request"/> </java-param> </java-params> </java-method> </java-methods> --> </java-web-service-endpoint>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <java-wsdl-mapping name="weblogic.wsee.databinding.internal.test.toplink.CollectionMapExtTypeArg" xmlns="http://xmlns.oracle.com/weblogic/weblogic-wsee-databinding" xmlns:oxm="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" databinding="toplink.jaxb"> <soap-binding parameter-style="BARE"/> <java-methods> <java-method name="testListOfCustomer"> <java-params> <java-param> <oxm:xml-element type="weblogic.wsee.databinding.internal.test.toplink.Customer"/> </java-param> </java-params> </java-method> <!-- Not implemented by EclipseLink yet <java-method name="testMapOfCustomer"> <java-params> <java-param> <oxm:xml-element xmlns='http://www.eclipse.org/eclipselink/xsds/persistence/oxm'> <xml-map> <key type='java.lang.String'/> <value type='weblogic.wsee.databinding.internal.test.toplink.Customer'/> </xml-map> </oxm:xml-element> </java-param> </java-params> </java-method> --> <java-method name="testMapOfCustomerAdapters"> <oxm:xml-element xmlns='http://www.eclipse.org/eclipselink/xsds/persistence/oxm'> <oxm:xml-java-type-adapter value='weblogic.wsee.databinding.internal.test.toplink.MapStringIntegerAdapter'/> </oxm:xml-element> <java-params> <java-param> <oxm:xml-element xmlns='http://www.eclipse.org/eclipselink/xsds/persistence/oxm'> <oxm:xml-java-type-adapter value='weblogic.wsee.databinding.internal.test.toplink.MapStringCustomerAdapter'/> </oxm:xml-element> </java-param> </java-params> </java-method> <!-- Not implemented: Bare Multi-part --> <java-method name="test3Lists"> <web-method exclude="true"/> </java-method> </java-methods> </java-wsdl-mapping>
The EXM schema file for external mapping metadata for the data binding framework is available at the following URL:
http://www.oracle.com/technology/weblogic/weblogic-wsee-databinding/1.1/weblogic-wsee-databinding.xsd
The data defines the attributes of a particular Java web service endpoint. This schema defines three types of XML constructs:
Constructs that are analogous to JAX-WS or JSR-181that override or define attributes on the service endpoint interface (SEI) and JAXB annotations for the value types utilized in the interfaces of the SEI.
Additional mapping specifications not available using standard JAX-WS or JAXB annotations, primarily for use with the java.util.Collections
API.
References to external JAXB mapping metadata from a Toplink OXM file.
When a construct is the direct analog of a JAX-WS, JSR-181, or JAXB annotation, the comment in the schema contains a notation such as:
Corresponding Java annotation: javax.jws.WebParam.Mode