Oracle® Application Server Advanced Web Services Developer's Guide 10g (10.1.3.1.0) Part Number B28975-02 |
|
|
View PDF |
This chapter describes how to use the Oracle Application Server Web Services Provider API. The Provider API lets you define custom processing logic for a Web services endpoint that is not tied to any particular service endpoint implementation strategy, such as JAX-RPC. The Provider model can be used to provide common functionality to a number of endpoints. Rather than incorporating the same functions into many Web services, the Provider model enables you to add the logic into the runtime directly.
A Provider lets you bypass the JAX-RPC tie-based framework and enables you the flexibility of choosing your own mechanism for traversing and interpreting the message payload. Since it runs in the OC4J container, a Provider can take advantage of the container's services such as schema validation, security, and reliability.
When to Use a Provider
You can choose to employ a Provider as your endpoint implementation if you find that your performance is lacking when using a standard JAX-RPC endpoint implementation. Because a Provider does not use the JAX-RPC framework, marshalling and unmarshalling of data is not performed. Therefore, based on your message traversal and interpretation mechanism, there may be less parsing and serialization effort before the message is processed.
Also, because a Provider enables you to process the SOAP message directly, you can perform much more sophisticated processing such as content-based routing. For example, inbound messages could be routed to a number of intermediate destinations (perhaps for some intermediate level of processing) before routing to a final destination.
The interfaces and classes in the oracle.webservices.provider
package allow you to implement and use your own Provider to process SOAP messages.
Provider Interface—your application must implement this interface to create your Provider.
ProviderConfig Class—configuration class that is passed to the Provider during its initialization. This represents the information related to the Provider configuration. The Provider also uses this class to interact with the container.
MessageContext Class—context class that is passed to the Provider's processMessage
method when an invocation is to be serviced by the Provider. The Provider instance can use this class to obtain transport protocol-related information.
HTTPConstants Class—provides a set of well-defined properties for the HTTP protocol that the container will set on the MessageContext
.
Your Provider class must implement the oracle.webservices.provider.Provider
interface. The following sections provide more information on the methods in the Provider
interface that must be implemented.
public void init(ProviderConfig config) throws ProviderException;
The init
method is called when the Provider is loaded and initialized. The method can be called only once during the lifecycle of the Provider. In response to the init
method, the container passes an instance of ProviderConfig
to the Provider. This instance provides configuration information related to the Provider. The ProviderConfig
instance provides mechanisms to set and get properties and the ServletContext
. The init
and destroy
methods provide the lifecycle mechanisms for the Provider much like the ServiceLifecycle
interface provides the lifecycle mechanisms for JAX-RPC service endpoint implementation (SEI) classes.
The Provider uses the ProviderConfig
instance to set or retrieve properties. If a property is set on the context, it will overwrite the corresponding static property set in the deployment descriptors. For example, the Provider can set the boolean VALIDATION_SOAP_SCHEMA
property to true
to let the container perform schema validation. Schema validation can be performed only if the WSDL is available; it cannot be performed in pass-through mode. In passthrough mode, the provider itself is not exposed as an endpoint. The default value of the VALIDATION_SOAP_SCHEMA
property is false
. Schema validation is based on the QName
value of the child element of the SOAP Body.
If the appropriate load-on-startup directive is provided (for example, by using the web.xml
file in the Provider application WAR file), then the init
method will be called on application startup.
public SOAPMessage processMessage(SOAPMessage request, MessageContext messageContext) throws ProviderException;
The processMessage
method is the Provider's main access method: it is invoked every time a SOAP request is dispatched to the Provider instance. The processMessage
method is where you provide the processing logic for the SOAP message. For the SOAP protocol, this method takes a SOAPMessage
instance as an argument. From this SOAPMessage
instance, the Provider can obtain access to other parts of the message payload, such as the SOAP body, headers, and attachments.
The processMessage
method also takes a MessageContext
object. The message context defines the properties that are valid for the particular message.
This method returns a SOAPMessage
instance. If the instance is not null, then the Provider intends to return a response to the sender, assuming the underlying transport supports it. If the underlying transport is a one-way protocol, such as JMS, then an attempt to send a response will cause an error to be thrown in the server logs. The return must be null for pure one-way calls and must not be null for request-response calls.
This class contains the configuration-related information for the Provider instance. The information includes details that are also listed in the proprietary deployment descriptors.
The properties of the ProviderConfig
are used to communicate with the container. For example, a policy object reference can be set as a ProviderConfig
property inside processMessage
(assuming the Provider implementation maintains a reference to the ProviderConfig
instance as an attribute initialized during the init
method invocation) or the init
method of the Provider instance. The container can read this policy object and apply the appropriate management functions to the Provider instance.
The following section provides more information on the methods and properties in the ProviderConfig
class.
These methods allow the Provider instance to dynamically provide or remove services to or from the container. The container can perform a variety of tasks on the services, such as test-page presentation, request message schema validation, and Web service management processing. The service registration process also allows the container to perform Web service management processing for the registered services.
public void addService(String pathInfo, URL wsdlURL, QName wsdlPort, QName serviceName, Object policy) throws ProviderException; public void addService(String pathInfo, InputStream wsdlStream, String wsdlBaseURI, QName wsdlPort, QName serviceName, Object policy) throws ProviderException; public void addService(String pathInfo, Definition wsdl, QName wsdlPort, QName serviceName, Object policy) throws ProviderException; public void removeService(String pathInfo);
The addService
and removeService
methods of the ProviderConfig
class can be invoked in the Provider's init
and processMessage
methods to dynamically add and remove manageable service endpoints, each with a unique URI. Internally, the container maintains a repository of WSDLs and a map of the WSDLs with the URIs of the incoming requests. In addition, these dynamic endpoints can be managed by using the Application Server Control tool, allowing you to apply security, reliability, auditing, and logging features. The Provider can make processing decisions for incoming requests based on the URI available from the Provider's MessageContext
.
The addService
and removeService
methods both take a pathInfo
parameter. This parameter contains the extra path information associated with the URL sent by the client when it invokes the endpoint. The extra path information follows the servlet path format, however, it precedes the query string and starts with a forward slash (/
) character. While the pathInfo
parameter cannot be null, it can be set to an empty string.
Three forms of the addService
method are available; they differ only in how you provide the WSDL location for the service.
Providing the WSDL as a URL—This form of the addService
method enables you to provide the WSDL as a URL (URL wsdlURL
).
Reading the WSDL From an Input Stream—This form of the method enables the WSDL to be read from an input stream (InputStream wsdlStream
). This method also provides a parameter where you can specify a URI for the WSDL file (String wsdlBaseURI
). The value of this parameter is used to resolve relative imports in the Provider WSDL input stream.
Providing the WSDL as a Definition
Object—This form of the method enables you to provide the WSDL as a javax.wsdl.Definition
object. Use this signature if you are constructing endpoints dynamically and already have a Definition
object instantiated. For example, you may have created the Definition
object in memory and it does not represent a WSDL in the file system.
The addService
method can also take a policy
parameter that defines the management features for the dynamic endpoint. The policy
parameter must be an org.w3c.dom.Element
that is compliant with the structure listed in Example 10-1. The definition of this element is listed as a type in the oracle-webservices-10_0.xsd
schema.
Example 10-1 Definition of Provider-Policy-Type
<xsd:complexType name="provider-policy-type"> <xsd:all> <xsd:element name="runtime" type="serverPortRuntimeType" minOccurs="0"/> <xsd:element name="operations" type="serverOperationsType" minOccurs="0"/> </xsd:all> </xsd:complexType>
Example 10-2 illustrates a structure defined by this type, as it would appear in an oracle-webservices.xml
deployment descriptor.
Example 10-2 XML Structure of the Policy Element
<policy> <runtime enabled="logging,auditing,security,reliability"> <logging>…</logging> <security>…</security> <reliability>…</reliability> </runtime> <operations> <operation name="…" inputName="..." outputName="..."> <runtime> <logging>…</logging> <auditing>…<auditing> <reliability>…</reliability> </runtime> </operation> </operations> </policy>
To support clustered environments, the ProviderConfig
class provides the boolean constant PROPAGATE_DYNAMIC_ENDPOINTS
. This constant represents the following property:
oracle.webservices.provider.propagateDynamicEndpoints
This property enables a Provider to make a dynamic endpoint accessible from all instances of an application across a configuration group or cluster. For more information on how to use this property, see "How to Make Dynamic Endpoints Accessible in a Clustered Environment".
This class contains the definitions of the transport-agnostic message properties. These properties are updated on each call to processMessage
. A standard set of constants is defined for the HTTP transport. Properties of the same name are available from the MessageContext
class. The MessageContext
class also contains the definitions of constants defined for non-HTTP transports.
This class provides a set of well-defined properties for the HTTP protocol that the container will set on the MessageContext
. The Provider instance should ensure that these properties are not overwritten.
The ProviderServlet
(oracle.j2ee.ws.server.provider.ProviderServlet
) handles the routing of requests to the Provider instance. Once deployed, a ProviderServlet
listens to a URL for incoming SOAP over HTTP requests. When the servlet receives a SOAP message, ProviderServlet
dispatches it to the processMessage
method of the Provider instance.
If you are hosting the Provider in the servlet container, then specify this servlet in the <servlet-class>
subelement of <servlet>
in your Provider application's web.xml
deployment descriptor. The servlet URL is specified in the <url-pattern>
element.
Example 10-3 illustrates a fragment of a web.xml
file. In the file, ProviderServlet
is specified in the <servlet-class>
element and the URL to which it listens, /LoggerService
, is specified in the <url-pattern>
element. This URL pattern is relative to the Web application's context root.
The <servlet-name>
element provides the link between this entry and the Provider-specific information in oracle-webservices.xml
illustrated in Example 10-5.
Example 10-3 web.xml Fragment, with ProviderServlet and the URL to Which it Listens
... <servlet> <servlet-name>LoggerProviderPort</servlet-name> <display-name>LoggerProviderPort</display-name> <description>JAX-RPC endpoint Provider Port</description> <servlet-class>oracle.j2ee.ws.server.provider.ProviderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>LoggerProviderPort</servlet-name> <url-pattern>/LoggerService</url-pattern> </servlet-mapping> ...
You can extend ProviderServlet
to tailor its functionality to a particular use case. Example 10-4 illustrates how you can extend the servlet's doGet
method to allow for the retrieval of specific resources based on the HTTP query string. Note that in this case, if the query string is not processed by the extended servlet, the request should be passed to the parent servlet's doGet
method. Note the call to super
if the incoming GET request is not processed.
Example 10-4 Extension of a ProviderServlet Method with a Call to super
public class ExtendedProviderServlet extends ProviderServlet{ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String queryString = request.getQueryString(); if ((queryString != null) && (queryString.equalsIgnoreCase("someotherquery"))) { response.setContentType("text/html; charset=UTF-8"); response.setStatus(HttpServletResponse.SC_OK); OutputStream outputStream = response.getOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(outputStream); writer.write( "<HTML><BODY>TEST RESPONSE</BODY></HTML>" ); writer.close(); } else { super.doGet(request, response); ... }
You can also extend ProviderServlet
to use your own test-page generation mechanism instead of using the default test page provided by the servlet.
For the Web service to recognize a Provider, you must edit the oracle-webservices.xml
and web.xml
deployment descriptors to add information about your Provider. The Oracle JDeveloper and Application Server Control tools do not provide support for adding this information; you must edit the files by hand.
To make the Web service Provider-aware, add the <provider-description>
clause to the oracle-webservices.xml
deployment descriptor. Example 10-5 illustrates a fragment of an oracle-webservices.xml
deployment descriptor with this clause. "Provider Elements in oracle-webservices.xml" describes the elements that can appear in the <provider-description>
clause.
Example 10-5 oracle-webservices.xml Fragment, with a <provider-description> Clause
<oracle-webservices> <provider-description> <provider-description-name> some name</provider-description-name> <wsdl-file>/file location</wsdl-file> <wsdl-service-name xmlns:ns_="urn:oracle-ws">ns_:PhotoService </ wsdl-service-name> <provider-port> <provider-name>LoggerProviderPort</provider-name> <wsdl-port xmlns:ns_="urn:oracle-ws">ns_:PhotoIFPort</wsdl-port> <implementation-class>oracle.myprovider.JmsRetriever </ implementation-class > <servlet-link>LoggerProviderPort</servlet-link> <property name="connection-factory-name"> jms/ws/mdb/theQueueConnectionFactory</property> <property name="queue-name">jms/ws/mdb/theQueue</property> <policy> <runtime enabled="logging,auditing,security,reliability"> <logging>…</logging> <security>…</security> <reliability>…</reliability> </runtime> <operations> <operation name="..." inputName="..." outputName="..."> <runtime> <logging>…</logging> <auditing>…<auditing> <reliability>…</reliability> </runtime> </operation> </operations> </policy> </provider-port> </provider-description> </oracle-webservices>
The top-level Provider element is <provider-description>
. This element identifies a collection of Provider ports. Table 10-1 describes the subelements of <provider-description>
. The <provider-port>
subelement is required; all others are optional.
Table 10-1 Subelements of the <provider-description> Element
Element Name | Description |
---|---|
Specifies globally-defined properties; that is, properties that are available to all of the defined Provider ports. This element recognizes a |
|
A name for the Provider description. |
|
(required) Associates a WSDL port with a Web service interface and implementation. It defines the name of the port as a component. It also associates the port with a servlet endpoint. If a |
|
Specifies the location of an associated WSDL for the Provider. |
|
Associates the WSDL's service name with the name of a Provider. This element should be provided if a WSDL has more than one service. This element is not required if the WSDL has only one service. |
The <provider-port>
element associates a WSDL port with a Web service interface and implementation. Table 10-2 describes the subelements of <provider-port>
. The <provider-name>
, <implementation-class>
, and <servlet-links>
subelements are required; all others are optional.
Table 10-2 Subelements of the <provider-port> Element
Element Name | Description |
---|---|
Indicates whether the test page should be exposed. Default is |
|
Indicates whether the WSDL should be exposed. Default is |
|
(required) Specifies the name of the class implementing the |
|
When a positive value is specified, the service will limit the size of requests to that value (in bytes). Any request that exceeds the maximum length will generate an error. Default is |
|
Defines the Web service management policies for the Provider. Table 10-3 describes the subelements of |
|
A locally defined property. If a property with a particular name is defined both locally and globally, then the property defined locally overrides the one defined globally. |
|
(required) The name of the Provider. The |
|
(required) Associates a |
|
Associates the Provider with a particular port of the WSDL defined by the |
The <policy>
element defines the Web service management policies for the Provider. Example 10-2 illustrates the structure of the element as it would appear in an oracle-webservices.xml
deployment descriptor. Table 10-3 describes the subelements of the <policy>
element.
Table 10-3 Subelements of the <policy> Element
Element Name | Description |
---|---|
Contains a sequence of elements, one for each operation. The |
|
Contains server-side quality of service runtime information (security, reliability, auditing, and logging) applicable to all the operations provided by the referenced Web service. Each child element contains configuration for a specific feature. |
Table 10-4 describes the <operation>
element, where you can define management policies for specific Provider operations.
Table 10-4 Subelement of the <operations> Element
Element Name | Description |
---|---|
Specifies client-side quality of service configuration for a particular operation provided by the referenced Web service. The configuration appears within this element's This |
See Also:
The following resources provide more information on Web service management policies:
security—Oracle Application Server Web Services Security Guide
reliability—Chapter 5, "Ensuring Web Service Reliability"
auditing and logging—Chapter 6, "Auditing and Tracing Messages"
To make the Web service Provider-aware, add the <servlet-class>
element to the <servlet>
clause and the <url-pattern>
element to the <servlet-mapping>
clause. Example 10-6 illustrates a web.xml
deployment descriptor with these elements. They are described in Table 10-5.
Example 10-6 Provider Elements in the web.xml Deployment Descriptor
<web-app><display-name/> <description/> <servlet> <servlet-name>LoggerProviderPort</servlet-name> <display-name>LoggerProviderPort</display-name> <description>JAX-RPC endpoint Provider Port</description> <servlet-class>oracle.j2ee.ws.server.provider.ProviderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>LoggerProviderPort</servlet-name> <url-pattern>/LoggerService</url-pattern> </servlet-mapping> </web-app>
Table 10-5 describes the elements which you must add to web.xml
to make it Provider-aware.
Table 10-5 Provider Elements in web.xml
Element Name | Description |
---|---|
Specifies the name of the Provider servlet. The value can be either |
|
Specifies the URL pattern to use for the Web service. The Provider servlet will listen to URLs whose prefix is specified by this element. The URL pattern should be relative to the Provider servlet context for the Web module. For dynamic pass through mode, the |
The following sections describe how to register a Provider-managed endpoint for your Web service.
The following steps provide a general outline of how to register a static Provider-managed endpoint for your Web service. Follow the links for more detailed information on each step.
Write your Provider application so that it implements the Provider
interface.
The Provider
methods init
, processMessage
, and destroy
must be implemented. See "Provider Interface" for more information on this interface and its methods.
Edit the oracle-webservices.xml
and web.xml
deployment descriptors.
"How to Make a Web Service Provider-Aware" provides more information on editing these descriptors.
(optional) Provide a management configuration.
The configuration is specified as a policy
clause in the oracle-webservices.xml
deployment descriptor. Example 10-2 provides an example of the policy
clause structure in the deployment descriptor.
Package the service.
"How to Package Provider Web Application Provider Classes" provides more information on packaging a service which includes Provider classes.
You can use the ProviderConfig.addService
method to register additional Provider-managed endpoints and configure management features for them. For example, a Business Process Execution Language (BPEL) process manager might use this mechanism to register its processes.
The generation, packaging, and deployment of a dynamic Provider-managed endpoint follows the same steps outlined in "How to Register a Static Provider-Managed Endpoint". To register the endpoint, you must perform the following additional step:
Register the service by invoking the addService
method on the providerConfig
reference. The implementation also has the option of passing the policy configuration by using the method's policy
parameter.
Example 10-7 illustrates how a Provider can dynamically add an endpoint. In this example, the ADD_SERVICE_POLICY
property declares the Web service management features for the dynamically-added endpoint (in this case, security auditing and reliability).
The addService
invocation is made on the providerConfig
reference (config
) passed to the init
method of the Provider. The policy
parameter of the addService
method uses the XMLUtil.elementFromString(ADD_SERVICE_POLICY)
to pass the management features to the service. Note the WSDL is packaged as part of the WAR file and retrieved as a resource using the servletContext
.
Example 10-7 Dynamically Registering a Provider-Managed Endpoint
... private static final String ADD_SERVICE_POLICY = "<policy>\n" + " <runtime enabled=\"security,auditing,reliability\">\n" + " <security>\n" + " <inbound>\n" + " <verify-username-token password-type=\"PLAINTEXT\" require-nonce=\"false\" " + " require-created=\"false\"/>\n" + " </inbound>\n" + " </security>\n" + " </runtime>\n" + " </policy>"; ... public void init(ProviderConfig config) throws ProviderException { ... URL wsdlURL1 = ((ServletContext)config.getContainerContext()). getResource("/WEB-INF/wsdl/HelloService.wsdl"); ... config.addService("/loanservice",wsdlURL1,new QName("http://hello.demo.oracle/","HttpSoap11"),null, XMLUtil.elementFromString( ADD_SERVICE_POLICY )); ... }
To support clustered environments, the ProviderConfig
class provides the boolean constant PROPAGATE_DYNAMIC_ENDPOINTS
. This constant represents the following property:
oracle.webservices.provider.propagateDynamicEndpoints
This property enables you to make a dynamic endpoint accessible from all instances of an application across a configuration group or cluster.
If the property is set to true
, then any addService
invocation made after the dynamic endpoint is initialized at one OC4J instance causes the endpoint to be accessible to all instances of the application across the cluster or configuration group.
PROPAGATE_DYNAMIC_ENDPOINTS
is an optional property that can be set as a <property>
subelement of <provider-port>
in the oracle-webservices.xml
deployment descriptor. Example 10-8 illustrates how the property is used.
Provider Web applications are packaged like any standard Web application. If the Provider application has a WSDL file, store it in the /WEB-INF/wsdl
directory in the WAR file. Store the Provider classes in the /classes
directory which is a child of /WEB-INF
. Example 10-9 illustrates the contents of an EAR file for a Provider Web application.
A Provider Web application is deployed (using standard deployment mechanisms) in a J2EE servlet container. The container must have the Provider system classes and the supporting classes available in its runtime.
See Also:
Oracle Containers for J2EE Deployment Guide for more information on deploying Provider Web applications.
The endpoints of a Provider Web application can be exposed by using a statically configured endpoint or by adding one dynamically. If the endpoint provides an associated WSDL file, then you can invoke the Web Service Test Page to see whether deployment was successful. If the endpoint does not provide a WSDL file, a Test Page will not be available.
See Also:
"Testing Web Service Deployment" in the Oracle Application Server Web Services Developer's Guide for more information on the Web Service Home page.
If a static or a dynamically-added Provider endpoint provides an associated WSDL file, then it can be configured through the Web Services interface in Application Server Control. For more information see the topic "Web Service Home Page" in the Application Server Control on-line help.
A Provider Web Service application can be accessed by standard J2SE or J2EE static stub or DII clients.
See Also:
The following chapters provide more information on assembling Web service clients:
"Assembling a J2EE Web Service Client" in the Oracle Application Server Web Services Developer's Guide for information on assembling J2EE Web Service clients.
"Assembling a J2SE Web Service Client" in the Oracle Application Server Web Services Developer's Guide for information on assembling J2SE Web service clients.
For more information on:
assembling a J2EE Web Service client, see "Assembling a J2EE Web Service Client" in the Oracle Application Server Web Services Developer's Guide.
assembling a J2SE Web service client, see "Assembling a J2SE Web Service Client" in the Oracle Application Server Web Services Developer's Guide.
testing whether the Provider Web service application deployed successfully, see "Testing Web Service Deployment" in the Oracle Application Server Web Services Developer's Guide.
using WebServicesAssembler commands to assemble Web service artifacts, see "Using WebServicesAssembler" in the Oracle Application Server Web Services Developer's Guide.