39 Developing a Transport Provider

This chapter describes the basic steps involved in developing a custom transport provider.

The Transport SDK provides a layer of abstraction between transport protocols and the Oracle Service Bus runtime system. This layer of abstraction makes it possible to develop and plug in new transport providers to Oracle Service Bus. The Transport SDK interfaces provide this bridge between transport protocols, such as HTTP, and the Oracle Service Bus runtime.

Tip:

Before beginning this chapter, be sure to review Chapter 38, "Design Considerations," first.

This chapter includes the following sections:

39.1 Development Road Map

The process of designing and building a custom transport provider is complex. This section offers a recommended path to follow as you develop your transport provider. Development of a custom transport provider breaks down into these basic stages:

39.1.1 Planning

Review the following planning steps before developing a custom transport provider.

  1. Decide if you really need to develop a custom transport provider. See Section 38.3, "Do You Need to Develop a Custom Transport Provider?"

  2. Run and study the example socket transport provider. The source code for this provider is installed with Oracle Service Bus and is publicly available for you to examine and reuse. See Chapter 42, "Sample Socket Transport Provider."

  3. Review Chapter 38, "Design Considerations." This chapter discusses the architecture of a transport provider and many aspects of transporter provider design, such as the security model and the threading model employed by transport providers.

  4. Review Section 39.2, "Before You Begin."

39.1.2 Developing

Section 39.3, "Basic Development Steps" outlines the steps you need to take to develop a transport provider, including schema configurations and interface implementations.

Section 39.4, "Important Development Topics" discusses in detail several topics that you might need to refer to during the development cycle. This section includes detailed information on topics such as Section 39.5, "Handling Messages," Section 39.6, "Transforming Messages," Section 39.8, "Handling Errors," and others.

39.1.3 Packaging and Deploying

For detailed information on packaging and deploying a transport provider, see Chapter 43, "Deploying a Transport Provider."

39.2 Before You Begin

Before you begin to develop a custom transport provider, you need to consider and review a number of design issues, which include:

39.3 Basic Development Steps

The basic steps to follow when developing a custom transport provider include:

Section 39.3.1, "1. Review the Transport Framework Components"

Section 39.3.2, "2. Create a Directory Structure for Your Transport Project"

Section 39.3.3, "3. Create an XML Schema File for Transport-Specific Artifacts"

Section 39.3.4, "4. Define Transport-Specific Artifacts"

Section 39.3.5, "5. Define the XMLBean TransportProviderConfiguration"

Section 39.3.6, "6. Implement the Transport Provider User Interface"

Section 39.3.7, "7. Implement the Runtime Interfaces"

Section 39.3.8, "8. Deploy the Transport Provider"

39.3.1 1. Review the Transport Framework Components

Figure 39-1 illustrates the components that you must implement and configure to create a custom transport provider. The transport manager controls and manages the registration of transport providers and handles communication with Oracle Service Bus. A transport provider manages the life cycle and runtime behavior of transport endpoints (resources where messages originate or are targeted). You use the Transport SDK to develop custom transport providers. Using the Transport SDK to develop a custom transport provider is the subject of this chapter.

Figure 39-1 Transport Subsystem Overview

Description of Figure 39-1 follows
Description of "Figure 39-1 Transport Subsystem Overview"

The parts of the transport subsystem that you must implement and configure include:

39.3.2 2. Create a Directory Structure for Your Transport Project

Before developing a new transport provider, take time to set up an appropriate directory structure for your project. The recommended approach is to copy the directory structure used for the sample socket transport provider. For a detailed description of this structure, see Section 42.2, "Sample Location and Directory Structure."

39.3.3 3. Create an XML Schema File for Transport-Specific Artifacts

Create an XML schema (xsd) file for transport-specific definitions. You can base this file on the schema file developed for the sample socket transport provider: OSB_ORACLE_HOME/samples/servicebus/sample-transport/schemas/SocketTransport.xsd

Note:

The SocketTransport.xsd file imports the file TransportCommon.xsd. This file is the base schema definition file for service endpoint configurations. This file is located in OSB_ORACLE_HOME/lib/sb-schemas.jar. You might want to review the contents of this file before continuing.

39.3.4 4. Define Transport-Specific Artifacts

Define XML schema for the following transport-specific artifacts in the XML schema file described in the previous section, Section 39.3.3, "3. Create an XML Schema File for Transport-Specific Artifacts."

  • EndpointConfiguration

  • RequestMetaDataXML

  • ResponseMetaDataXML

    Note:

    Only simple XML types are supported when defining transport provider-specific metadata and headers. For example, complex types with nested elements are not supported. Furthermore, an additional restriction is that there can be at most one header with a given name.

    Tip:

    Each of these schema definitions is converted into a corresponding Java file and compiled. You will find these converted Java source files for the sample socket transport provider in the directory: sample-transport/build/classes/com/bea/alsb/transports/sock/impl

39.3.4.1 EndPointConfiguration

EndPointConfiguration is the base type for endpoint configuration, and describes the complete set of parameters necessary for the deployment and operation of an inbound or outbound endpoint. This configuration consists of generic and provider-specific parts. For more information on the EndPointConfiguration schema definition, refer to the documentation elements in the TransportCommon.xsd file.

You need to specify a provider-specific endpoint configuration in the schema file. Example 39-1 shows an excerpt from the SocketTransport.xsd.

Example 39-1 Sample SocketEndPointConfiguration Definition

<xs:complexType name="SocketEndpointConfiguration">
    <xs:annotation>
      <xs:documentation>
        SocketTransport - specific configuration
      </xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:choice>
        <xs:element name="outbound-properties"
                    type="SocketOutboundPropertiesType"/>
        <xs:element name="inbound-properties"
                    type="SocketInboundPropertiesType"/>
      </xs:choice>
      <xs:element name="request-response" type="xs:boolean">
        <xs:annotation>
          <xs:documentation>
            Whether the message pattern is synchronous
            request-response or one-way.
          </xs:documentation>
        </xs:annotation>
      </xs:element>
...

39.3.4.2 RequestMetaDataXML

It is required that each transport provider store metadata (message headers) in a Plain Old Java Object (POJO) and pass that to the pipeline. Examples of information that might be transmitted in the metadata are the Content-Type header, security information, or locale information. A RequestMetaData POJO is a generic object that extends the RequestMetaData abstract class and describes the message metadata of the incoming or outgoing request. The transport provider has to deliver the message metadata to Oracle Service Bus runtime in a RequestMetaData POJO. See also Section 39.5.3, "Request and Response Metadata Handling."

RequestMetaDataXML is an XML representation of the same RequestMetaData POJO. This XML representation uses Apache XML Bean technology. It is only needed by Oracle Service Bus runtime if or when processing of the message involves any actions in the pipeline that need an XML representation of the metadata, such as setting the entire metadata to a specified XML fragment on the outbound request.

You need to specify request metadata configuration in the schema file. Example 39-2 shows an excerpt from the SocketTransport.xsd.

Example 39-2 Sample SocketRequestMetaDataXML Definition

<xs:complexType name="SocketRequestMetaDataXML">
    <xs:annotation>
      <xs:documentation/>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="ts:RequestMetaDataXML">
        <xs:sequence>
          <xs:element name="client-host"
                      type="xs:string" minOccurs="0">
            <xs:annotation>
              <xs:documentation>
                Client host name
              </xs:documentation>
            </xs:annotation>
          </xs:element>
          <xs:element name="client-port" type="xs:int" minOccurs="0">
            <xs:annotation>
              <xs:documentation>Client port</xs:documentation>
            </xs:annotation>
          </xs:element>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

39.3.4.3 RequestHeadersXML

RequestHeadersXML is the base type for a set of inbound or outbound request headers. You need to specify the RequestHeadersXML configuration in the schema file. Example 39-2 shows an excerpt from the SocketTransport.xsd.

Example 39-3 Sample SocketRequestHeadersXML Definition

<xs:complexType name="SocketRequestHeadersXML">
    <xs:annotation>
      <xs:documentation/>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="ts:RequestHeadersXML">
        <xs:sequence>
          <xs:element name="message-count" type="xs:long" minOccurs="0">
            <xs:annotation>
              <xs:documentation>
                Number of messages passed till now.
              </xs:documentation>
            </xs:annotation>
          </xs:element>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

39.3.4.4 ResponseMetaDataXML

ResponseMetaDataXML is the base type for metadata for a response to an inbound or outbound message. You need to specify the ResponseMetaDataXML configuration in the schema file. Example 39-2 shows an excerpt from the SocketTransport.xsd.

Example 39-4 Sample SocketResponseMetaDataXML Definition

<xs:complexType name="SocketResponseMetaDataXML">
    <xs:complexContent>
      <xs:extension base="ts:ResponseMetaDataXML">
        <xs:sequence>
          <xs:element name="service-endpoint-host"
                      type="xs:string" minOccurs="0">
            <xs:annotation>
              <xs:documentation>
                Host name of the service end point connection.
              </xs:documentation>
            </xs:annotation>
          </xs:element>
          <xs:element name="service-endpoint-ip"
                      type="xs:string" minOccurs="0">
            <xs:annotation>
              <xs:documentation>
                IP address of the service end point connection.
              </xs:documentation>
            </xs:annotation>
          </xs:element>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

39.3.4.5 ResponseHeadersXML

ResponseHeadersXML is the base type for a set of response headers. You need to specify the ResponseHeadersXML configuration in the schema file. Example 39-2 shows an excerpt from the SocketTransport.xsd.

Example 39-5 Sample SocketResponseHeadersXML Definition

<xs:complexType name="SocketResponseHeadersXML">
    <xs:annotation>
      <xs:documentation/>
    </xs:annotation>
    <xs:complexContent>
      <xs:extension base="ts:ResponseHeadersXML"/>
    </xs:complexContent>
  </xs:complexType>

39.3.5 5. Define the XMLBean TransportProviderConfiguration

To configure the TransportProviderConfiguration XML bean, edit the transport provider configuration file. This XML file is located in the config directory in the transport provider root directory. See Section 42.2, "Sample Location and Directory Structure," for the location of this file (SocketConfig.xml) in the sample socket transport provider implementation.

  • If proxy services can use your transport, set the inbound-direction-supported element to true.

  • If business services use your transport, set the outbound-direction-supported element to true.

  • If your transport is self-described, include an element self-described with the value set to true. A self-described transport is one whose services are responsible for describing their shape (schema or WSDL) based on their endpoint configuration.

  • To publish a tModel for your transport to UDDI, include an element UDDI. See Section 39.10, "Publishing Proxy Services to a UDDI Registry" for more info.

    Tip:

    The schema for TransportProviderConfiguration is defined in TransportCommon.xsd, which is located in OSB_ORACLE_HOME/lib/sb-schemas.jar. Refer to the schema file for more information.

39.3.6 6. Implement the Transport Provider User Interface

When you add a business or proxy service using the Oracle Service Bus Administration Console, you select a transport provider in the service creation wizard. The wizard includes the transport providers that are provided with Oracle Service Bus and any custom transport providers that were developed with the Transport SDK.

This section discusses the Transport SDK API components that bind your custom transport provider to the Oracle Service Bus Administration Console user interface. You must implement these APIs to connect your provider to the user interface.

Tip:

This section assumes that you are familiar with the service creation wizard. See Section 42.5, "Configuring the Socket Transport Sample," for a detailed, illustrated example.

Creating the Custom Transport User Interface 

  1. After users create a new service and choose the Service Type in the service creation wizard, they must then select an appropriate transport provider for the Service Type. To validate the selection, the wizard calls the following method of the TransportUIBinding interface:

    public boolean isServiceTypeSupported(BindingTypeInfo binding)
    

    This method determines if the transport provider is suitable for the selected Service Type.

  2. After users select a valid transport provider, they enter an endpoint URI. To validate this URI, the wizard calls the following method of the TransportUIBinding interface:

    public TransportUIError[] validateMainForm(TransportEditField[] fields)
    
  3. Next, the wizard displays the transport-specific configuration page. To render this page, the wizard calls the following method of the TransportUIBinding interface:

    public TransportEditField[] getEditPage(EndPointConfiguration config, BindingTypeInfo binding) throws TransportException 
    

    The Transport SDK offers a set of TransportUIObjects that represent fields in the configuration page. For example, you can add text boxes, check boxes, and other types of UI elements. Use the TransportUIFactory to create them. After creation use the same factory to specify additional properties and obtain TransportEditField objects that can be displayed by the service creation wizard.

    Tip:

    You can associate events with most of the UI fields. An event acts like a callback mechanism for the TransportUIBinding class and lets you refresh, validate, and update the configuration page. When an event is triggered, the wizard calls the method:

    updateEditPage(TransportEditField[] fields, String name) throws TransportException 
    
  4. When users finishes the transport configuration, the wizard calls the validation method:

    TransportUIError[] validateProviderSpecificForm(TransportEditField[] fields)
    
  5. After the service is saved, the transport manager calls the following method of the TransportProvider class:

    void validateEndPointConfiguration(TransportValidationContext context)
    

    If no error is reported, a new endpoint is created. The Transport Manager then calls the method:

    TransportEndPoint createEndPoint(EndPointOperations.Create context) throws TransportException
    

    If this method returns successfully, the new service is listed in the Oracle Service Bus Administration Console and the underlying transport configuration is associated with an endpoint on the TransportProvider.

    Note:

    The endpoint configuration is saved in the Oracle Service Bus session and does not need to be persisted or recovered in case of a server restart by the transport provider.

  6. Once the session is activated, you must deploy the endpoint to start processing requests. See Section 39.11, "When to Implement TransportWLSArtifactDeployer" and Section 43.4, "Deploying to a Cluster," to learn more about deploying an endpoint and processing requests.

    Tip:

    For the sample socket transport provider, you can find the implementations of these interfaces in the sample-transport/src directory.

39.3.7 7. Implement the Runtime Interfaces

A new custom transport provider must implement the following runtime interfaces. For a summary of the Transport SDK interfaces and related classes, see Chapter 41, "Transport SDK Interfaces and Classes." For detailed information on interfaces and classes, see the Oracle Fusion Middleware Java API Reference for Oracle Service Bus.

Tip:

For the sample socket transport provider, you can find the implementations of these interfaces in the sample-transport/src directory.

Implement the Following Runtime Interfaces 

  • TransportProvider

  • TransportWLSArtifactDeployer

    Note:

    Only implement the TransportWLSArtifactDeployer interface if the transport provider needs to deploy Oracle WebLogic Server-related artifacts, such as EAR/WAR/JAR files, that go into an Oracle WebLogic Server change list at the time of endpoint creation. For more information, see Section 39.11, "When to Implement TransportWLSArtifactDeployer."

  • TransportEndPoint

  • InboundTransportMessageContext

  • OutboundTransportMessageContext

  • Transformer

    Note:

    Only implement the Transformer interface if the transport provider needs to work with non-standard payload bindings, for example, anything other than Stream, DOM, SAX, or XMLBean. For more information, see Section 39.6, "Transforming Messages."

39.3.8 8. Deploy the Transport Provider

For detailed information on deployment, see Chapter 43, "Deploying a Transport Provider."

39.5 Handling Messages

This section discusses message handling in transport providers and includes these topics:

39.5.1 Overview

The Transport SDK features a flexible representation of message payloads. All Transport SDK APIs dealing with payload use the Source interface to represent message content.

The Source-derived message types provided with the Transport SDK include:

  • StreamSource

  • ByteArraySource

  • StringSource

  • XmlObjectSource

  • DOMSource

  • MFLSource

  • SAAJSource

  • MimeSource

    Note:

    StreamSource is a single use source; that is, it implements the marker interface SingleUseSource. With the other Sources, you can get the input stream from the source multiple times. Each time the Source object gets the input stream from the beginning. With a SingleUseSource, you can only get the input stream once. Once the input is consumed, it is gone (for example, a stream from a network socket); however, Oracle Service Bus buffers the input from a SingleUseSource, essentially keeping a copy of all of its data.

    If you implement a Source class for your transport provider, you need to determine whether you can re-get the input stream from the beginning. If the nature of the input stream is that it can only be consumed once, your Source class should implement the marker interface SingleUseStream.

The Transport SDK provides a set of Transformers to convert between Source objects. You can implement new transformations, as needed, as long as they support transformations to/from a set of canonical representations. See Section 39.6, "Transforming Messages" for more information. See also Section 38.8, "Designing for Message Content."

39.5.2 Sending and Receiving Message Data

When implementing inbound endpoints to deliver the inbound message to Oracle Service Bus runtime, you need to call TransportManager.receiveMessage(). The transport provider is free to expose the incoming message payload in either one of the standard Source-derived objects, such as stream, DOM or SAX, or a custom one.

If Oracle Service Bus needs to send a response message back to the client that sent the request, it will call methods setResponseMetaData() and setResponsePayload() followed by close() on InboundTransportMessageContext to indicate that the response is ready to be sent back. When Oracle Service Bus runtime calls the inbound transport message context close() method, this will be done from a different thread than that on which the inbound request message was received. The transport provider should be aware of this as it may affect the semantics of transactions. Also, the transport provider cannot attempt to access the response payload and/or metadata until close() method has been called.

39.5.3 Request and Response Metadata Handling

It is required that each transport provider store metadata and headers in a Plain Old Java Object (POJO) and pass that to the pipeline. There are some cases where Oracle Service Bus requires an XMLBean. In these cases, you need to implement a conversion from POJO to XMLBean using the API.

The following are the methods you must provide to convert from a POJO to XML:

RequestHeaders.toXML()

RequestMetaData<T>.toXML()

ResponseHeaders.toXML()

ResponseMetaData<T>.toXML()

For the reverse direction (XML to POJO) you need to implement:

TransportEndPoint.createRequestMetaData(RequestMetaDataXML)

InboundTransportMessageContext.createResponseMetaData(ResponseMetaDataXML)

39.5.4 Character Set Encoding

Each transport provider is responsible for specifying the character set encoding of the incoming message payload to Oracle Service Bus. For outgoing messages (outbound request and inbound response), the transport provider is responsible for telling Oracle Service Bus what character set encoding to use for the outgoing payload. The character-set encoding is specified in request and response metadata.

In virtually every case, the character-set encoding that the transport is responsible for inserting into the metadata is exactly the encoding that is statically specified in the service configuration. One of the few exceptions to this is HTTP transport, which inspects Content-Type for any "charset" parameters and overrides any encoding configured in the service. This is necessary in order to conform to HTTP specifications. Other transport protocols may need to handle similar issues.

Tip:

In general, the encoding for a service is fixed. If someone sends an UTF-16 encoded message to a proxy that is specified to be SHIFT_JIS, then that is generally considered to be an error. Transport providers should not need to inspect the message simply to determine encoding.

For outgoing messages, the transport provider tells Oracle Service Bus what encoding it requires for the outbound request, and Oracle Service Bus performs the conversion if necessary.

Transports should always rely on this encoding for outgoing messages and should not assume that it is the same as the encoding specified in the service configuration. If there is a discrepancy, the transport can choose to allow it, but others could consider it an error and throw an exception. Also the transport has the additional option of leaving the encoding element blank. That leaves the pipeline free to specify the encoding (for example, through pass-through).

39.5.5 Co-Located Calls

If a given transport provider supports proxy service endpoints, it is possible to configure the request pipeline such that there is a routing step that routes to that provider's proxy service. Furthermore there could be a Publish or a Service Callout action that sends a message to a proxy service instead of a business service. This use case is referred to as co-located calls.

The transport provider needs to be aware of co-located calls, and handle them accordingly. Depending on the nature of the proxy service endpoint implementation, the transport provider may choose to optimize the invocation such that this call bypasses the entire transport communication stack and any inbound authentication/authorization, and instead is a direct call that effectively calls TransportManager.receiveMessage() immediately.

Tip:

Oracle Service Bus has implemented this optimization with the HTTP, File, Email and FTP transport providers. The JMS provider does not use this optimization due to the desire to separate the transactional semantics of send operation versus receive operations.

To use this optimization in a custom transport provider, you need to extend the CoLocatedTransportMessageContext class and call its send() method when TransportProvider.sendMessageAsync() is invoked.

39.5.6 Returning Outbound Responses to Oracle Service Bus Runtime

When Oracle Service Bus runtime sends a message to an outbound endpoint and there is a response message to be returned, the transport provider must return this response asynchronously. That means TransportSendListener.onReceiveResponse() or TransportSendListener.onError() methods need to be called from a different thread than the one on which TransportProvider.sendMessageAsync() was called.

If the transport provider has a built-in mechanism by which the response arrives asynchronously, such as responses to JMS requests or HTTP requests when the async response option is used, it happens naturally. However, if the transport provider has no built-in mechanism for retrieving responses asynchronously, it can execute the outbound request in a blocking fashion and then schedule a new worker thread using the TransportManagerHelper.schedule() method, in which the response is posted to the TransportSendListener.

39.6 Transforming Messages

When Oracle Service Bus needs to set either the request payload to an outbound message or the response payload to an inbound message, it asks the transport provider to do so through an object derived from the Source interface. The transport provider then needs to decide what representation the underlying transport layer requires and use the Transformer.transform() method to translate the Source object into the desired source.

Tip:

For more information on message transformation, see Section 38.8, "Designing for Message Content." For a list of built-in transformations, see Section 38.8.4, "Built-In Transformations," and Section 41.4, "Source and Transformer Classes and Interfaces."

A custom transport provider can support new kinds of transformations. Suppose a transport provider needs to work with a DOM object in order to send the outbound message. When called with setRequestPayload(Source src), the transport provider needs to call the method:

TransportManagerHelper.getTransportManager().getTransformer().
transform(src, DOMSource.class, transformOptions)

The return value of the method gives a DOMSource, which can then be used to retrieve the DOM node.

Note:

If the transport provider requires a stream, there is a shortcut: each Source object supports transformation to stream natively.

You can add new transformations to a custom transport provider. For example, suppose you want to add a new kind of Source-derived class, called XYZSource. For performance reasons, transport providers are encouraged to provide conversions from XYZSource to one of the two canonical Source objects, XmlObjectSource and StreamSource when applicable. Without such transformation, generic transformers will be used, which rely on the StreamSource representation of XYZSource. Of course, if XYZSource is a simple byte-based Source with no internal structure, then relying on the generic transformers is usually sufficient. Note that any custom transformer that is registered with TransportManager is assumed to be thread-safe and stateless.

To support attachments, the transport provider has three options:

  • The Source returned by TransportMessageContext must be an instance of MessageContextSource. A limitation of this option is that MessageContextSource requires that the content has already been partitioned into a core-message Source and an attachments Source.

  • The Source is an instance of MimeSource and the Headers objects contain a multipart Content-Type header.

  • The Content-Type is a pre-defined header for the transport provider with the specific value multipart/related. Both HTTP(S) and Email transports rely on this third option for supporting attachments.

39.7 Working with TransportOptions

A TransportOptions object is used to supply options for sending or receiving a message. A TransportOptions object is passed from the transport provider to the transport manager on inbound messages. On outbound messages, a TransportOptions object is passed from the Oracle Service Bus runtime to the transport manager, and finally to the transport provider.

This section includes these topics:

39.7.1 Inbound Processing

The transport provider supplies these parameters to TransportManager.receiveMessage():

  • QOS – Specifies exactly-once or best-effort quality of service. Exactly-once quality of service is specified when the incoming message is transactional.

  • Throw On Error – If this flag is set, an exception is thrown to the callee of method TransportManager.receiveMessage() when an error occurs during the Oracle Service Bus pipeline processing. The options for throwing the exception include: throw the exception back to the inbound message or create a response message from the error and notify the inbound message with the response message. Typically, you set Throw On Error to true when QOS is exactly-once (for transactional messages).

    For example, JMS/XA sets this flag to true to throw the exception in the same request thread, so it can mark the exception for rollback. HTTP sets the flag to false, because there is no retry mechanism. The error is converted to a status code and a response message is returned.

  • Any transport-specific opaque data – Opaque data can be any data that is set by the transport provider and passed through the pipeline to the outbound call. This technique provides optimizes performance when the same transport is used on inbound and outbound. The opaque data is passed directly through the pipeline from the inbound transport to the outbound transport. For example, the HTTP/S transport provider can pass the username and password directly from the inbound to the outbound to efficiently support identity pass-through propagation.

39.7.2 Outbound Processing

For outbound processing, the Oracle Service Bus runtime supplies these parameters to the transport manager, which uses some of the parameters internally and propagates some parameters to TransportProvider.sendMessageAsync(). These parameters include:

  • QOS – Specifies whether or not "exactly-once" quality of service can be achieved. For example, for HTTP, if quality of service is set to exactly once, the HTTP call is blocking. If it is set to best effort, it is a non-blocking HTTP call.

  • Mode – Specifies one-way or request response. See also Section 38.2.3, "Transport Provider Modes."

  • URI, Retry Interval, and Count – The transport provider uses the URI to initialize the outbound transport connection. For example, the HTTP transport provider uses the URI when instantiating a new HttpURLConnection. The transport provider is not required to use Retry Interval and Count.

  • OperationName – The transport provider can use OperationName if it needs to know what outbound Web Service is being used. The transport manager uses this parameter to keep track of monitoring statistics.

  • Any transport-specific opaque data – An example of transport-specific opaque data is the value of the "Authorization" header for HTTP/S.

39.7.3 Request Mode

The request mode is defined as an enumeration with two values: REQUEST_ONLY (also called "one-way") and REQUEST_RESPONSE. These modes are interpreted as follows for requests and responses:

  • On outbound requests, the pipeline indicates the mode through TransportOptions and the transport provider must honor the mode.

  • On inbound requests, the pipeline knows the mode and closes the inbound request and does not send a response if it computes the mode REQUEST_ONLY.

  • If a response is sent by the pipeline, then there is a response even if the response is empty.

  • For transports that are inherently one-way, the transport must not specify response metadata.

39.8 Handling Errors

There are three different use cases to consider with respect to the effect runtime exceptions have on the transactional model. These cases include:

39.8.1 Case 1

The exception occurs somewhere in the request pipeline but before the outbound call to the business service, as shown in Figure 39-2. For example, executing a specific XQuery against the contents of the request message raises an exception.

If there is a user-configured error handler configured for the request pipeline, the error will be handled according to the user configuration. Otherwise, the proxy service will either catch an exception when calling TransportManager.receiveMessage() or will be notified in the InboundTransportMessageContext.close() method of the error through response metadata, based on the transport options passed as an argument to the receiveMessage() call. If the proxy service indicates that the exception should be thrown, surround receiveMessage() with a try/catch clause and mark the transaction for rollback.

39.8.2 Case 2

The exception occurs during the business service call, as shown in Figure 39-3. The outbound transport provider either:

  • Throws an exception from TransportProvider.sendMessageAsync(). For example, the outbound provider throws an exception if there was an error while establishing a socket connection to external service. This situation could occur if the business service cannot be called because of an incorrect URL, a faulty connection, or other reasons. In these cases, the transport provider must raise an exception.

  • Notifies the listener through TransportSendListener.onError(). For example, if the business service was called, but the call resulted in an error (such as a SOAP fault), the transport provider needs to call TransportSendListener.onError() instead of raising an exception.

In the first instance, the exception handling is the same as that described in Section 39.8.1, "Case 1". In the second instance, if there is an error handler configured for the response pipeline, the error is handled according to the user configuration. Otherwise, the exception is propagated back to the proxy service endpoint in InboundTransportMessageContext.close() through the response metadata.

39.8.3 Case 3

The exception occurs sometime after the business service call in the response pipeline, as shown in Figure 39-4. Again, in the absence of a user-defined error handler for the response pipeline, the proxy service endpoint is notified of the error with the InboundTransportMessageContext.close() method with appropriate response metadata. If the inbound transport endpoint is a synchronous transactional endpoint, it is guaranteed that the transaction that was active at the time request was received is still active and it may be rolled back. If the inbound endpoint is not transactional or not synchronous, there is not an inbound transactional context to roll back, so some other action might need to be performed.

39.8.4 Catching Application Errors

When business services try to access an external service and an error occurs in the external service application, such as a SOAP fault, subsequent retries by the services are likely to produce errors until the application is fixed.

Oracle Service Bus lets you identify application errors, giving you the option of preventing retries on application errors when your transport is used.

This section describes how to catch application errors in your transport and configure your transport to prevent application error retries.

39.8.4.1 Identifying Application Errors

In your transport provider code you must identify the conditions under which an application error occurs.

For example, in the Oracle Service Bus HTTP transport, an application error is one in which the HTTP response has a 500 status code, has a non-empty payload, and has a content type that is consistent with the service type, such as XML for SOAP.

When an error meets the application error conditions you define, return a TRANSPORT_ERROR_APPLICATION type using one of the following methods:

  • Errors in the request – Throw a TransportException with the error code TRANSPORT_ERROR_APPLICATION in TransportProvider.sendMessageAsync().

  • Errors in the response – Schedule TransportSendListener.onError() with the error code TRANSPORT_ERROR_APPLICATION.

The transport SDK can then identify application errors when they occur and handle them accordingly.

The transport SDK also sends application errors to the pipeline $fault variable.

39.8.4.2 Configuring Application Error Retries

In your <Transport>Config.xml file, enter the following element as a child of the <ProviderConfiguration> element, according to the TransportCommon.xsd schema in /osb_10.3/lib/sb-schemas.jar:

<declare-application-errors>true</declare-application-errors>

This entry provides a Retry Application Errors option on the business service's main transport configuration page when a user selects your transport. If you do not provide this element, the default value is false, application errors are not caught, and no option is provided to retry application errors.

39.8.5 Catching Connection Errors

Oracle Service Bus lets you identify connection errors in your transport, which triggers the transport SDK to take inaccessible endpoint URIs offline automatically. For example, in a cluster with Oracle Service Bus running on Managed Servers, a Managed Server that experiences a connection error on a service request can automatically mark the endpoint URI as offline.

You can re-enable endpoint URIs in the following ways:

  • On configuring the business service, an you can set a Retry Count and Retry Iteration Interval to determine the frequency and number of retries after connection errors. A successful connection to the service after a retry automatically reactivates the endpoint URI.

    A Retry Iteration Interval of zero (0) takes the endpoint URI offline indefinitely and requires you to manually re-enable the endpoint URI.

  • You can manually re-enable offline endpoint URIs in the Oracle Service Bus Administration Console, on the Operational Settings page for the business service.

The automated connection error functionality does not apply to the following situations:

  • If a service pipeline dynamically sets an endpoint URI in $outbound/ctx:transport/ctx:uri, the transport SDK cannot take the URI offline, because the endpoint URI is not defined in the service configuration.

  • The transport SDK does not persist connection status. After a server restart, all endpoint URIs are considered online.

For more information, see "Managing Endpoint URIs for Business Services" in the Oracle Fusion Middleware Administrator's Guide for Oracle Service Bus.

39.8.5.1 Identifying Connection Errors

This section describes how to identify connection errors in your transport. Once caught, a connection error triggers the transport SDK to take the affected endpoint URI offline automatically.

In your transport provider code, you must identify the conditions under which a connection error occurs.

For example, in the Oracle Service Bus HTTP transport, a connection error is one in which the HTTP response has a 404 status code or there is an IOException when a connection is attempted on the endpoint URI.

When an exception meets the connection error conditions you define, return a TRANSPORT_ERROR_CONNECTION type using one of the following methods:

  • Errors in the request – Throw a TransportException with the error code TRANSPORT_ERROR_CONNECTION in TransportProvider.sendMessageAsync().

  • Errors in the response – Schedule TransportSendListener.onError() with the error code TRANSPORT_ERROR_CONNECTION.

The transport SDK can then identify connection errors when they occur and handle them accordingly.

The transport SDK also sends connection errors to the pipeline $fault variable and adds them to the response.

39.9 Defining Custom Environment Value Types

This section describes how to define custom environment value types that you want to use in your transport implementation. When you use the TransportProvider.getEnvValues() method to return environment values for an endpoint, you will be able to declare environment values of these custom types.

When your transport is used, custom environment value types can be used in the same ways that standard environment value types are used in Oracle Service Bus, such as for customization, find and replace, and preservation of values on configuration import. For example, you may want to be able to define and preserve references to a service account or a JMS queue in your transport configuration.

Environment value types can be any of the following categories: environment, operational, and security.

Add custom variables to your <Transport>Config.xml file. The schema that determines the XML structure is TransportCommon.xsd, located in /osb_10.3/lib/sb-schemas.jar.

Following is an example of a custom security variable in the JMS transport's JmsConfig.xml:

<env-value-type>
    <name>JMS Service Accounts</name>
    <localized-display-name>
        <localizer-class>com.bea.wli.sb.transports.messages.
         TransportsTextLocalizer</localizer-class>
        <message-id>JMS_SERVICE_ACCOUNTS</message-id>
    </localized-display-name>
    <localized-description>
        <localizer-class>com.bea.wli.sb.transports.messages.
          TransportsTextLocalizer</localizer-class>
        <message-id>JMS_SERVICE_ACCOUNTS</message-id>
    </localized-description>
    <simple-value>true</simple-value>
    <category>security</category>
</env-value-type>

Following are descriptions of key elements for custom environment value types:

  • name – The variable name used by the transport SDK.

  • display-name – The name for the variable that appears in the Oracle Service Bus user interface. Following is the localization alternative:

    • localized-display-name – Alternative, localized version of display-name.

    • localizer-class – The localization properties text file containing the localized display-name. The .properties extension is not required.

    • message-id – The property in the localization properties file that provides the value of the display name.

  • description – Description of the environment value type. For localization, use the localized-description element instead with the localizer-class and message-id child elements as described in display-name.

  • simple-value – If the environment value type is of the category "environment," simple-value determines whether or not this type is searchable with find and replace functionality in Oracle Service Bus (value of true or false).

  • category – The category of the environment value type: "environment," "security," or "operational." When the category is "security" or "operational," you can decide whether or not to preserve the environment value type during configuration import. When the category is "environment," the environment value type is available for find and replace.

39.10 Publishing Proxy Services to a UDDI Registry

Universal Description, Discovery, and Integration (UDDI) is a standard mechanism for describing and locating Web services across the internet. You might want to publish proxy services based on a custom transport provider to a UDDI registry. This allows proxy services to be imported into another Oracle Service Bus server in a different domain as the one hosting the business service.

To publish a proxy service, the transport provider needs to define a tModel that represents the transport type in the "UDDI" section of TransportProviderConfiguration XML schema definition. (For more information on the schema-generated interfaces, see Section 41.2, "Schema-Generated Interfaces.")

This tModel must contain a CategoryBag with a keyedReference whose tModelKey is set to the UDDI Types Category System and keyValue is "transport." You are required to provide only the UDDI V3 tModel key for this tModel.

If UDDI already defines a tModel for this transport type, you should copy and paste the definition into the UDDI section.

An example of such a tModel is provided in Example 39-6.

Example 39-6 Example tModel

<?xml version="1.0" encoding="UTF-8"?>
<ProviderConfiguration xmlns="http://www.bea.com/wli/sb/transports">
   . . .
   . . .
  <UDDI>
    <TModelDefinition>
      <tModel tModelKey="uddi:bea.uddi.org:transport:socket">
        <name>uddi-org:socket</name>
        <description>Socket transport based webservice</description>
        <overviewDoc>
          <overviewURL useType="text">
            http://www.bea.com/wli/sb/UDDIMapping#socket
          </overviewURL>
        </overviewDoc>
        <categoryBag>
          <keyedReference keyName="uddi-org:types:transport"
                          keyValue="transport"
                          tModelKey="uddi:uddi.org:categorization:types"/>
        </categoryBag>
      </tModel>
    </TModelDefinition>
  </UDDI>
</ProviderConfiguration>

If UDDI does not already define a tModel for this transport type, Oracle Service Bus can publish the tModel you define here to configured registries. When a UDDI registry is configured to Oracle Service Bus, the "Load tModels into Registry" option can be specified. That option causes all of the tModels of Oracle Service Bus, including the tModels for custom transport providers, to be published to the UDDI registry. After deploying your transport provider, you can update your UDDI registry configuration to publish your tModel.

During UDDI export, TransportProvider.getBusinessServicePropertiesForProxy(Ref) is called and the resulting map is published to the UDDI registry. The provider is responsible for making sure to preserve all important properties of the business service in the map so that during the UDDI import process the business service definition can be correctly constructed without loss of information.

During UDDI import, TransportProvider.getProviderSpecificConfiguration(Map) is called and the result is an XmlObject that conforms to the provider-specific endpoint configuration schema, which goes into the service definition.

Tip:

OASIS, the Organization for the Advancement of Structured Information Standards, is responsible for creating the UDDI standard. To read more about UDDI, including the full technical specification, go to: http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=uddi-spec

39.11 When to Implement TransportWLSArtifactDeployer

Two sets of transport provider interfaces are provided that deal with individual service registration. TransportProvider has methods like create/update/delete/suspend/resume and TransportWLSArtifactDeployer has the same methods. This section discusses these two implementations and explains when you need to implement TransportWLSArtifactDeployer.

Only implement TransportWLSArtifactDeployer if your provider needs to make changes to Oracle WebLogic Server artifacts in the Oracle Service Bus domain. The methods on TransportWLSArtifactDeployer are only called on an Admin Server. In this case, changes are made through the DomainMBean argument that is passed in, and then the changes are propagated to the entire cluster.

The TransportProvider methods are called on all servers (Administration and Managed Servers) in the domain. Because you cannot make changes to Oracle Service Bus domain artifacts on a Managed Server, the purpose of the method calls on TransportProvider is to update its internal data structures only.

When a given Transport provider implements the TransportWLSArtifactDeployer interface, the methods on TransportWLSArtifactDeployer are called before the corresponding methods on TransportProvider. For example, TransportWLSArtifactDeployer.onCreate() is called before TransportProvider.createEndPoint().

For more information on TransportWLSArtifactDeployer, see Section 41.3.2, "Summary of General Interfaces."

39.12 Creating Help for Custom Transports

You can provide online help for your custom transports in the design environment (Eclipse) and the runtime environment (Oracle Service Bus Administration Console). Providing help is optional, but it can be extremely useful in guiding service creators through the transport configuration process.

Figure 39-5 shows help included with a custom transport in the development and runtime environments.

Figure 39-5 Custom Transport Help in the Development and Runtime Environments

Description of Figure 39-5 follows
Description of "Figure 39-5 Custom Transport Help in the Development and Runtime Environments"

This section includes the following topics:

39.12.1 Custom Transport Help Overview

This section describes the different options available for providing custom transport help in Eclipse and the Oracle Service Bus Administration Console.

Note:

Because of potential user interface and functionality differences between transport configuration in Eclipse and the Oracle Service Bus Administration Console, consider creating separate help topics for both environments.

39.12.1.1 Eclipse Help

Eclipse help is based on the Eclipse help framework. You have choices for your custom transport help implementation in Eclipse.

39.12.1.1.1 Context-Sensitive Help (F1)

Context-sensitive help, launched by pressing F1 in Eclipse, shows help topics within Eclipse instead of launching a separate help window that displays the entire help system. Figure 39-6 shows how context-sensitive help appears in Eclipse.

Figure 39-6 Pressing F1 on a Transport Configuration Page to Display Help for the Transport

Description of Figure 39-6 follows
Description of "Figure 39-6 Pressing F1 on a Transport Configuration Page to Display Help for the Transport"

All of the native Oracle Service Bus transports provide context-sensitive help from their respective transport configuration editors.

The benefit of context-sensitive help is quick user access to targeted help topics without leaving Eclipse, which is particularly useful for help with custom transports.

39.12.1.1.2 Eclipse Help Table of Contents

You can provide help content for your custom transport in the Eclipse help system, accessible from the Eclipse Help menu. When you launch Eclipse help, a separate window displays the contents of the entire help system.

Figure 39-7 shows online help for transports in the Eclipse help system.

Figure 39-7 Custom Transport Help in Eclipse

Description of Figure 39-7 follows
Description of "Figure 39-7 Custom Transport Help in Eclipse"

Your help topic(s) can appear in different locations of the help system table of contents, as shown in Figure 39-7, depending on how you package and configure your custom transport. For example, you can merge your transport help with the transport section of the Oracle Service Bus help topics, or you can provide your transport help at the top level of the help system.

39.12.1.2 Oracle Service Bus Administration Console Help

You can also provide transport configuration help at runtime in the Oracle Service Bus Administration Console. The Oracle Service Bus Administration Console provides its own integrated help system, but Oracle Service Bus displays custom transport help stand-alone in its own browser window, as shown in Figure 39-8. Custom transport help is displayed when you click Help on the transport configuration page.

Figure 39-8 Custom Transport Help from the Oracle Service Bus Administration Console

Description of Figure 39-8 follows
Description of "Figure 39-8 Custom Transport Help from the Oracle Service Bus Administration Console"

The following sections show you how to provide online help for your custom transport in both Eclipse and in the Oracle Service Bus Administration Console.

39.12.2 Providing Custom Transport Help in Eclipse

If you make your custom transport available for service configuration in the Eclipse, you can provide help content that appears as context-sensitive help in Eclipse, in the Eclipse help system, or both. This section shows you how.

The sample socket transport and the Oracle Service Bus native transports provide a best-practice reference implementation for Eclipse help and are used as examples in this section.

Transport help is part of the Eclipse plug-in you create for your transport. For details on plug-in creation, see Chapter 40, "Developing Oracle Service Bus Transports for Eclipse."

39.12.2.1 Providing Context-Sensitive Help in Eclipse

Providing context-sensitive help gives users information about transport configuration directly in Eclipse, where they are configuring the transport.

You can provide context-sensitive help on the transport configuration pages in the service editor in Eclipse.

The following steps are required for providing context-sensitive help:

  1. In plugin.xml, add an extension for org.eclipse.help.contexts that points to a context.xml file. See the org.eclipse.help.contexts example in Example 39-7.

    This entry tells the plug-in where to find the context.xml file. The path to context.xml is relative to the plug-in root.

  2. Create a context.xml file that maps the transport configuration user interface context IDs to help files. Oracle Service Bus provides context IDs for custom transports automatically. See Section 39.12.2.3.3, "context.xml."

  3. Create your help topics. See Section 39.12.2.3.4, "Help Content and Resources."

  4. Package all the help files. See Section 39.12.2.4, "Packaging Help for the Transport Plug-in."

39.12.2.2 Providing Help in the Eclipse Help System

You can add your transport help to the main Eclipse help system. Your help topics appear in the table of contents, as shown in Figure 39-7.

  1. In plugin.xml, add an extension for org.eclipse.help.toc that points to a toc.xml file. See the org.eclipse.help.contexts example in Example 39-7. Use the following guidance for setting the primary attribute.

    • If you are packaging your plug-in as a JAR file, or if you want your transport help to appear in the top level of the help table of contents, as shown in the "Sample Transport" entry in Figure 39-7, set primary="true".

    • If you want your transport help to be merged with the Oracle Service Bus help topics, as shown in Figure 39-7, set primary="false".

      To merge your transport help with the main Oracle Service Bus help, your transport plug-in must be packaged as an exploded directory.

    For details on plug-in packaging, see Chapter 40, "Developing Oracle Service Bus Transports for Eclipse."

  2. Create a toc.xml file that provides the table of contents structure for your transport help. See the examples in Section 39.12.2.3.2, "toc.xml."

  3. Create your help topics. See Section 39.12.2.3.4, "Help Content and Resources."

  4. Package all the help files. See Section 39.12.2.4, "Packaging Help for the Transport Plug-in."

39.12.2.3 Help Implementation Reference

Eclipse help, which is based on the Eclipse help framework, requires the resources described in this section.

Use this reference section in conjunction with the previous procedures for implementing transport help in Eclipse.

Note:

Oracle Service Bus provides a sample help implementation in its sample socket transport, located at OSB_ORACLE_HOME/samples/servicebus/sample-transport. The sample transport is a good reference implementation for developing your own custom transports and help. The sample plugin.xml is in the /eclipse subdirectory, and the help resources are in the /help subdirectory.

This section describes the following Eclipse help resources:

39.12.2.3.1 plugin.xml

The plugin.xml file is the key to adding your transport and transport help files to the Eclipse environment. You must add entries in plugin.xml for your help table of contents (toc.xml) and for context-sensitive help (context.xml).

Example 39-7 shows the toc.xml and context.xml (contexts_socketTransport.xml) entries in the sample socket transport's plugin.xml file, located in the OSB_ORACLE_HOME/samples/servicebus/sample-transport/eclipse directory.

Example 39-7 Sample transport plugin.xml

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
...
   <extension
         point="org.eclipse.help.toc">
      <toc file="/help/en/toc.xml" primary="true"/>
   </extension>
   <extension
         point="org.eclipse.help.contexts">
      <contexts
            file="/help/en/contexts_socketTransport.xml"
            plugin="Socket_Transport"/>
   </extension>
</plugin>

Key Parts of plugin.xml 

  • All paths are relative to the plug-in root directory.

  • The org.eclipse.help.toc extension point makes the connection to the Eclipse help system left navigation area.

    The <toc file...> entry references the toc.xml file containing the help topic hierarchy you create for your transport help.

  • The primary="true" attribute is important. If set to true, your transport table of contents appears at the top level of the Eclipse help system. Set it to true if you are packaging your custom transport plug-in as a JAR file.

    If set to false, Eclipse expects your toc.xml to be merged into an existing toc.xml hierarchy, such as the main Oracle Service Bus help system. See the following toc.xml section for more information.

  • The entry for the org.eclipse.help.contexts lets you implement Eclipse-based context-sensitive (F1) help for your transport. Context-sensitive help topic links appear in the Related Topics area of the Help view in Eclipse.

For details on plug-in packaging, see Chapter 40, "Developing Oracle Service Bus Transports for Eclipse."

39.12.2.3.2 toc.xml

The toc.xml file determines how your custom transport help appears in the left navigation area of the Eclipse help system. Example 39-8 shows how you provide your transport help at the top level of the Eclipse help system table of contents.

Example 39-8 Sample Socket Transport toc.xml for a Top-Level Entry in the Eclipse Help System

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<?NLS TYPE="org.eclipse.help.toc"?>
<toc label="Socket Transport Sample">
    <topic label="Socket Transport Configuration Page (Business Services)"
        href="help/en/tpSOCKETTransportBizService.html"/>
    <topic label="Socket Transport Configuration Page (Proxy Services)"
        href="help/en/tpSOCKETTransportProxyService.html"/>
    <topic label="Configuring the Socket Transport Sample (Service Bus Console)"
        href="help/en/example.html"/>
</toc>

When including your transport help as a top-level entry in the Eclipse help system, be sure to set primary="true" in the org.eclipse.help.toc extension point in plugin.xml.

39.12.2.3.3 context.xml

The context.xml file, shown in Example 39-9, maps the context IDs of your transport editor page to help topics. When users press F1 on your transport configuration pages, Eclipse displays your help links in the Help view, as shown in Figure 39-6.

Example 39-9 Sample context.xml (contexts_socketTransport.xml) for the sample socket transport

<?xml version="1.0" encoding="UTF-8"?>
<?NLS TYPE="org.eclipse.help.contexts"?>
<contexts> 
    <!-- Default Socket Transport help -->
<context id="tpSOCKETTransportBizService" 
    title="Socket Transport Configuration page (Business Service)">
    <description>The Sample socket transport illustrates Transport SDK
        concepts.</description>
    <topic href="help/en/tpSOCKETTransportBizService.html" 
        label="Socket Transport Configuration Page (Business Services)"/>
</context>
<context id="tpSOCKETTransportProxyService" 
        title="Socket Transport Configuration page (Proxy Service)">
    <description>The Sample socket transport illustrates Transport SDK
        concepts.</description>
    <topic href="help/en/tpSOCKETTransportProxyService.html" 
        label="Socket Transport Configuration Page (Proxy Services)"/>
</context>
</contexts>

Key Points About context.xml 

  • The context id attribute value is the context ID of the editor user interface.

  • The topic href attribute tells Eclipse which help topic to link to when the user presses F1.

  • The topic label attribute determines the link text that appears in the Related Topics area of the Eclipse Help view.

  • The description element provides the text above the displayed link when the user presses F1.

  • Context IDs for your transport user interfaces are available automatically. Use the patterns in Table 39-1 for the context id attribute, following the exact text and case sensitivity. If your id values are incorrect, context-sensitive help will not work for your transport.

Table 39-1 Context IDs for Transport Configuration Pages

User Interface Component Value for Id Attribute

Transport configuration page in the business service editor

tp<TRANSPORT_ID>TransportBizService – For example:

tpSOCKETTransportBizService

Transport configuration page in the proxy service editor

tp<TRANSPORT_ID>TransportProxyService – For example:

tpSOCKETTransportProxyService


The <TRANSPORT_ID> value comes from your implementation of the TransportProvider class, where you set the String ID of the transport. Notice that the <TRANSPORT_ID> must be all uppercase letters even if you named the transport ID with lowercase letters.

  • You can give your context.xml a unique name (with an .xml extension) and put it anywhere within the plug-in directory as long as you provide the correct path to it in plugin.xml.

  • All paths in context.xml are relative to the plug-in root directory.

39.12.2.3.4 Help Content and Resources

You have a lot of flexibility in deciding what type of help content to provide, from a simple page of text with no graphics to multiple pages with many graphics, PDF files, embedded video and so on.

For example, you could create a single HTML file and reference it from the toc.xml and context.xml files; or you could create separate help files that describe the transport configuration fields for business services and proxy services and also provide a high-level overview, pointing at the three help files in different combinations from toc.xml and context.xml.

You can store your help topics and resources anywhere in your transport plug-in, as long as you reference them correctly in toc.xml and/or context.xml.

Because of potential user interface and functionality differences between transport configuration in Eclipse and the Oracle Service Bus Administration Console, consider creating separate help topics for Eclipse and for the Oracle Service Bus Administration Console.

39.12.2.4 Packaging Help for the Transport Plug-in

Your transport plug-in should contain the following:

  • The plugin.xml file

  • A transport JAR containing your transport classes and supporting files

  • A help directory containing the toc.xml, context.xml, and help files

Whether you package your transport plug-in as a JAR or as an exploded directory, following is a recommended packaging structure for your transport help with relation to other resources:

/plugin_root

plugin.xml

transport.jar

/help

/en (locale)

toc.xml

context.xml

/html

<help files and resources>

Notice that with the /en directory the help is packaged to support localization. To provide localization, you must create a plug-in for each locale, as described in the Eclipse documentation.

Note:

You can also package your help files in a doc.zip file. For more information, see "Help server and file locations" in the Eclipse Platform Plug-In Developer Guide at http://help.eclipse.org/galileo/topic/org.eclipse.platform.doc.isv/guide/ua_help_content_files.htm.

39.12.2.5 Related Topics

For complete information on the Eclipse help framework, see the Eclipse help system at http://help.eclipse.org/galileo/topic/org.eclipse.platform.doc.isv/guide/ua_help.htm.

For information on plug-in packaging, see Chapter 40, "Developing Oracle Service Bus Transports for Eclipse."

39.12.3 Providing Custom Transport Help in the Oracle Service Bus Administration Console

This section shows you how to provide help for your custom transport at runtime in the Oracle Service Bus Administration Console. Oracle Service Bus displays custom transport help as a stand-alone help page in a browser, as shown in Figure 39-8.

Figure 39-9 provides a high-level view of the Oracle Service Bus Administration Console help framework for custom transports.

Figure 39-9 Oracle Service Bus Administration Console Help Framework

Description of Figure 39-9 follows
Description of "Figure 39-9 Oracle Service Bus Administration Console Help Framework"

By implementing a specific Oracle Service Bus interface, you use the getHelpPage() method to launch a single HTML page when the user clicks Help in the Oracle Service Bus Administration Console when your user interface has focus. The HTML file can contain the following:

  • Text, inline CSS definitions, inline JavaScript functions

  • References to graphics and other resources, as long as those resources are hosted in a Web application or an external Web site

In most situations, you should be able to provide all the help for your custom transport with text and inline formatting.

However, if you want to provide full-featured Web-based help that includes graphics and other external resources, those resources must be hosted in a Web application or an external Web site. You must either reference those external resources in the HTML file or provide a link from the HTML file to an external location. For example, the sample socket transport help provides a link from the starting HTML file to a help topic with graphics that is running in a custom Web application. Using an embedded JavaScript call, you could also set up your HTML file to automatically redirect to the expanded help URL you want.

Following are the tasks involved in creating custom transport help in the Oracle Service Bus Administration Console:

39.12.3.1 Implementing the CustomHelpProvider Interface

To develop the configuration user interface for your custom transport, you implement the TransportUIBinding interface in a custom class. To provide help for your transport configuration user interface in the Oracle Service Bus Administration Console, you must also implement the CustomHelpProvider interface. CustomHelpProvider contains the getHelpPage() method you need to launch help for your transport configuration page in the Oracle Service Bus Administration Console.

The sample socket transport implements CustomHelpProvider in its SocketTransportUIBinding.java class, located at OSB_ORACLE_HOME/samples/servicebus/sample-transport/src/com/bea/alsb/transports/sock.

Example 39-10 contains snippets that illustrate the implementation of CustomHelpProvider.

Example 39-10 Implementing CustomHelpProvider to provide help for your transport in the Oracle Service Bus Administration Console

public class SocketTransportUIBinding
    implements TransportUIBinding, CustomHelpProvider {
.
.
.
  public Reader getHelpPage() {
    String helpFile = "help/en/contexts_socketTransport.html";
    ClassLoader clLoader = Thread.currentThread().getContextClassLoader();
    InputStream is = clLoader.getResourceAsStream(helpFile);
    InputStreamReader helpReader = null;
    if(is!=null)
      helpReader = new InputStreamReader(is);
    else
      SocketTransportUtil.logger
        .warning(SocketTransportMessagesLogger.noHelpPageAvailableLoggable().
                getMessage(uiContext.getLocale()));
    return helpReader;
  }
}

In Example 39-10, Reader getHelpPage() returns a Reader stream that the Oracle Service Bus Administration Console uses to send the HTML page to the browser. The helpFile path is relative to the root within the transport JAR.

If you are providing help in multiple languages, use TransportUIContext.getLocale() to help provide the appropriate path to the localized content; in this case, providing the locale value for /help/<locale>/your.html.

39.12.3.2 Creating an HTML File to Launch

Create an HTML file for the getHelpPage() method to launch, as illustrated by help/en/contexts_socketTransport.html in Example 39-10.

If you want to keep your help implementation simple, create the HTML file to use text, inline CSS definitions, and inline JavaScript functions. If you do this, you do not need to create a separate Web application to host graphics or other external resources.

However, if you want to provide more expanded help with graphics and other resources, reference those external resources in your HTML file, such as

img src="/help_socket/help/en/wwimages/addProject.gif"

or

a href="http://www.yoursite.com"

You can also set the HTML file up to automatically redirect to the expanded help with an embedded JavaScript call, as shown in Example 39-11, which redirects from the sample socket transport HTML page to the expanded help_socket Web application help content.

Example 39-11 JavaScript function that provides a redirect

<script language="JavaScript" type="text/javascript">
<!-- Begin
window.location="/help_socket/help/en/example.html";
// End -->
</script>

The sample socket transport HTML file provides a link to its expanded help. The HTML file, contexts_socketTransport.html, is located at OSB_ORACLE_HOME/samples/servicebus/sample-transport/resources/help/en/.

39.12.3.3 Creating a Simple Web Application to Display Expanded Help (Optional)

If you want to go beyond a basic text HTML file for your transport help, you can provide expanded help with graphics and other resources in various ways:

  • Link from the self-contained HTML file to an existing URL; for example, if you have an existing Web site that contains your transport documentation. All that is required is that you provide a link to the URL from the self-contained HTML file. You can also insert references to graphics and other resources hosted on an external site.

  • Create a Web application for the expanded help, bundle it with your transport, and link to it or reference graphics and other resources from the HTML file. This topic provides instructions on creating a Web application that is bundled in your transport EAR to display your expanded transport help.

Create the following files for your Web application:

39.12.3.3.1 META-INF/application.xml

In application.xml, give your Web application a context root that is used for the Web application's root URL. For example, Example 39-12 shows the context root for the sample socket transport Web application.

Example 39-12 application.xml for the sample socket transport Web application

<application>
    <display-name>Socket Transport</display-name>
    <description>Socket Transport</description>
    <module>
        <web>
            <web-uri>webapp</web-uri>
            <context-root>help_socket</context-root>
        </web>
    </module>
</application>

The sample socket transport application.xml file is located at OSB_ORACLE_HOME/samples/servicebus/sample-transport/META-INF/.

This entry maps the file system directory /webapp to an alias Web application root URL:

http://server:port/help_socket/ 

With your help files inside the Web application in a directory such as /help/en/, the full URL to your expanded help would be:

http://server:port/help_socket/help/en/index.html

But your internal links to it only need to be

/help_socket/help/en/index.html

where index.html is the landing HTML page.

39.12.3.3.2 WEB-INF/web.xml

In web.xml, enter a display name and description for the Web application. This is standard deployment descriptor information. For example, Example 39-13 shows the name and description of the sample socket transport Web application.

Example 39-13 web.xml for the sample socket transport Web application

<web-app>
    <display-name>Sample Socket Transport Help WebApp</display-name>
    <description>
        This webapp implements the help webapp for the socket transport.
    </description>
</web-app>

The sample socket transport web.xml file is located at OSB_ORACLE_HOME/samples/servicebus/sample-transport/webapp/WEB-INF/.

39.12.3.3.3 Help Content and Resources

Create and package your expanded help files inside the Web application directory. In the sample socket transport, the help files are stored in OSB_ORACLE_HOME/samples/servicebus/sample-transport/resources/help/en.

Note:

The reason the socket transport help files are not stored in the /webapp directory is because the help directory contains help files and resources for both the Eclipse plug-in and the Oracle Service Bus Administration Console. When the sample socket ANT build creates the transport JAR, transport EAR, and Eclipse plug-in, it packages the help in different ways. For the transport EAR build, it moves the help files under the /webapp directory.

Because of potential user interface and functionality differences between transport configuration in Eclipse and the Oracle Service Bus Administration Console, consider creating separate help topics for Eclipse and for the Oracle Service Bus Administration Console.

39.12.3.4 Packaging Transport Help for the Oracle Service Bus Administration Console

Your transport EAR should contain the following:

  • A transport JAR stored in APP-INF/lib containing:

    • Your transport classes and supporting files

    • The HTML file for your transport help, ideally in a directory such as help/en/ for localization support

  • Optionally, a Web application containing expanded help for your transport