41 Developing Custom Transport Providers for JDeveloper

This chapter describes the best practices, design considerations, and packaging to develop custom Service Bus transports for use in JDeveloper. The Transport SDK interface provides a bridge between transport protocols and the Service Bus runtime.

Tip:

Before you begin this chapter, review Learning About Custom Transport Providers.

This chapter includes the following sections:

41.1 Introduction

Service Bus transports were originally designed to be deployed on Service Bus servers and configured through the Oracle Service Bus Console. With design environments like JDeveloper, some modifications to the SDK are necessary to ensure transport design-time features can be used on platforms other than the Oracle Service Bus Console.

The sample socket transport installed along with Service Bus was ported to JDeveloper and can be considered a best practice for JDeveloper integration. The sample socket resources are located at OSB_ORACLE_HOME/samples/servicebus/sample-transport. The Java source files are in the /src subdirectory. The sample also contains a build script that automatically packages the sample socket transport for both JDeveloper integration and Oracle Service Bus Console deployment. For information on building and deploying the sample socket transport, see Creating a Sample Socket Transport Provider.

41.2 Services Runtime and Services Configuration

When you develop a transport, distinguish the runtime aspects from the configuration aspects. The runtime aspects include proxy or business service deployment and service runtime invocation. The configuration aspects include proxy or service configuration and validation. The runtime aspects do not need to change since they are always exercised in the context of a running Service Bus server. However, the configuration aspects are dependent on the design environment.

Developers should consider three different deployment modes:

  1. Online mode: The services using the custom transport are configured with the Oracle Service Bus Console on a running Service Bus server.

  2. Offline mode: The services using the custom transport are configured with a design environment running outside the Service Bus server. No remote server is available.

  3. Offline mode with remote server: The services using the custom transport are configured with a design environment running outside the Service Bus server. However, a remote server is available and can be used for both validation and configuration purposes.

Transports running in JDeveloper must support offline mode and, optionally, offline mode with a remote server.

41.2.1 Offline Methods

When you deploy a transport in offline mode, the configuration framework creates a single session for all the resource configurations. This session is never activated. Since proxy or business services can only be deployed on a running Service Bus server, there is no need to activate the session. However, it is still important to detect conflicts and configuration errors, and the validation methods are still exercised.

Following is a list of the minimum set of classes and methods defined by the Transport SDK that must be implemented in offline mode. The exceptions were removed from the methods signature for better readability.

Note:

You do not need to completely re-implement your transport for offline mode. In most cases your transport will only need a few changes to existing methods to support both online and offline modes.

Classes and Methods You Must Implement for Offline Mode

  • public interface TransportProvider, specifically the following methods:

    • String getId()

    • void validateEndPointConfiguration(TransportValidationContext context)

    • SchemaType getEndPointConfigurationSchemaType()

    • SchemaType getRequestMetaDataSchemaType()

    • SchemaType getRequestHeadersSchemaType()

    • SchemaType getResponseMetaDataSchemaType()

    • SchemaType getResponseHeadersSchemaType()

    • TransportProviderConfiguration getProviderConfiguration()

    • TransportUIBinding getUIBinding(TransportUIContext context)

    • void shutdown()

    • Collection<NonQualifiedEnvValue> getEnvValues(Ref ref, EndPointConfiguration epConfig)

    • void setEnvValues(Ref ref, EndPointConfiguration epConfig, Collection<NonQualifiedEnvValue> envValues)

    • Collection<Ref> getExternalReferences(EndPointConfiguration epConfig)

    • void setExternalReferences(Map<Ref, Ref> mapRefs, EndPointConfiguration epConfig)

    • Map<String, String> getBusinessServicePropertiesForProxy(Ref ref)

    • XmlObject getProviderSpecificConfiguration(Ref ref, Map<String, String> props)

  • public interface TransportProviderFactory

    This interface registers transports in offline mode. For more information, see Packaging and Deploying a Custom Transport Provider.

  • public interface TransportUIBinding

    Implement all the methods in this interface and define the user interface used to configure a proxy or business service.

Helper Classes

  • public class TransportManagerHelper

    This class, which is typically used by TransportProvider developers, provides a boolean isOffline() method to help the provider implementor determine whether the code is running offline or not. Some of the methods that are not valid in offline mode will throw exceptions, which are described below. Other methods are meant only for runtime or deployment, such as public isAdmin().

    The following methods are also available when working in offline mode with remote server:

    • public Set<String> getDispatchPolicies(JMXConnector connector)

    • public DomainRuntimeServiceMBean getDomainRuntimeServiceMBean(JMXConnector connector)

      See Working Offline with a Remote Server for more information.

    Do not invoke the following methods in offline mode:

    • public static boolean isAdmin()

      This method throws a java.lang.IllegalStateException message.

    • public static boolean clusterExists()

      This method always returns false.

    Note:

    The preferred method for checking runtime status is to use isRuntimeEnabled() in conjunction with getRuntimeServers().

41.2.2 Restrictions when Working Offline

When you work offline, none of WebLogic Server services running on the server are available. Do not use these services inside the methods described in Offline Methods.

Following are examples of restrictions for working offline:

  • The Oracle WebLogic Server MBeans are not available.

  • The server Java properties are not available.

  • You cannot access the JNDI tree directly. However, if JNDI properties are defined in the service configuration, you can attempt to use them.

  • You can not determine if the service is going to run in a cluster or a standalone server.

  • You do not have access to the Oracle WebLogic Server security infrastructure.

  • You do not have access to any static singleton service located on the server.

Because some of the services are not available, it is necessary to evaluate how the transport user interface is affected. In general, the user interface should be more flexible to let users manually configure values instead of trying to retrieve values from the server environment.

For example, some transports retrieve the list of available Work Manager (dispatch policy) items by using the TransportManagerHelper and letting the user pick one through a list. However, in offline mode, the MBeans are not available so the list cannot be populated. The transport provider has two choices:

  1. Let the user type the correct Work Manager name. In that case, the user interface must be changed to be a text box and not a list when working offline.

  2. Another less flexible option is to populate the list with just the default Work Manager. When the service is pushed to a running Service Bus server, the Work Manager name can be switched using an environment value substitution.

41.2.3 Working Offline with a Remote Server

When you work offline, a remote server might be available. For instance, when you configure a service in JDeveloper, you can associate a remote Service Bus server to the current project. The transport provider can take advantage of the remote server by accessing the Oracle WebLogic Server MBeans and retrieving information. This mode is similar to working online; however, some restrictions still apply since the code is not running on the server and only the MBeans are available.

When you work offline with a remote server, the following restrictions apply:

  • The server Java properties are not available.

  • You cannot use many of TransportManagerHelper methods as described in Offline Methods.

  • You cannot access the JNDI tree directly. However if JNDI properties are defined in the service configuration, you can attempt to use them.

  • You do not have access to any static singleton service located on the server.

To access the MBeans, the framework provides an instance of JMXConnector when it requests the TransportUI object, or when it asks the provider to validate a configuration. The JMXConnector is available in the TransportUIContext or the TransportValidationContext:

JMXConnector connector = (JMXConnector)uiContext.get(TransportValidationContext.JMXCONNECTOR);

For more information, see the sample transport in Custom Transport Provider Reference for Offline Tools.

If the connector is not present, a remote server is not available. This connector object can then be used to access the MBeans. Helper methods have been added to the TransportManagerHelper to retrieve the list of WorkManager and WebLogic Server domain MBean.

Note:

This behavior is generalized for both online and offline modes. The public static Set<String> getDispatchPolicies() method defined in the TransactionManagerHelper will be deprecated and must be replaced by the same method with JMXConnector as a parameter. If you do not replace it, the following error appears: com.bea.wli.sb.transports.TransportException.

41.2.4 Bootstrapping Transports in Offline Mode

In online mode, transports must be packaged as EAR files and deployed on a Service Bus server. When the EAR is loaded at startup, the transport registers a callback on a startup event and registers an instance of the TransportProvider to the TransportManager.

In offline mode, the SDK provides an interface called com.bea.wli.sb.transports.TransportProviderFactory that registers transports. A transport developer must implement this interface and must make the default constructor public. The interface is provided in Custom Transport Provider Reference for Offline Tools, as well as a sample implementation.

If the TransportProvideFactory is instantiated, you can assume the transport needs to work in offline mode (with or without a remote server).

Note:

You can set a boolean operator in the TransportManagerHelper when the constructor is invoked to determine if the transport is running in offline mode. This information can also be passed in the TransportUIContext and the TransportValidationContext. Your engineering department can assist you in making this decision.

41.3 Packaging Transports for JDeveloper

In order to use your custom transport provider in JDeveloper, you must add the JAR file you generated when you created the transport provider to your Service Bus installation. Packaging your custom transport as a JDeveloper plug-in, in conjunction with your transport user interface implementation, lets service developers select and configure your transport in the development environment.

In offline mode, you can use transports in different design environments, including JDeveloper. In general, transports simply need to be available to external design time environments as a self-contained JAR file. A self-contained JAR file includes the transport config.xml file, the header, metadata schemas, XBeans classes, TransportProviderFactory implementation, and the compiled transport classes.

Figure 41-1 shows the service editor in JDeveloper—after a service has been created—with a configuration page for the sample socket transport.

Figure 41-1 Transport Configuration Page in JDeveloper

Description of Figure 41-1 follows
Description of "Figure 41-1 Transport Configuration Page in JDeveloper"

For information about packaging and deploying the custom transport provider, see Packaging and Deploying a Custom Transport Provider.

Note:

Your implementation of the TransportUIBinding interface determines the user interface for selecting and configuring your transport, both in JDeveloper and in the Oracle Service Bus Console.

41.4 Custom Transport Provider Reference for Offline Tools

This section provides reference information that you might need to know when developing a custom transport provider for offline use in JDeveloper.

41.4.1 Working in Different Modes

Dispatch policies are used by most transports and allow service throttling. This code distinguishes the three modes described in Services Runtime and Services Configuration:

  • Online mode

  • Offline mode

  • Offline mode with remote server

The connection to the remote server is retrieved from the context, as shown in the following example.

Example - Connection to the Remote Server

/**
 * Builds the dispatch policies in the ui object.
 *
 * @param curDispatchPolicy
 * @return TransportEditField containing existing dispatch policies.
 */
 public TransportEditField getDispatchPolicyEditField(StringcurDispatchPolicy {
     TransportUIFactory.TransportUIObject uiObject = null;
     Set<String> wmSet = null;
     
     if (SocketTransportManagerHelper.isOffline()) 
          { // if on JDeveloper try to get the MBeans from the UIContext
          JMXConnector connector =
                (JMXConnector)uiContext.get(TransportValidationContext.JMXCONNECTOR);
          if (connector != null) {
             try {
                  wmSet = TransportManagerHelper.getDispatchPolicies(connector);
                 } catch (Exception ex) {
                      wmSet = null;
                 }
          }
      } else { // if running on the server use the helper to get the policies
          try {
               wmSet = TransportManagerHelper.getDispatchPolicies();
          } catch (TransportException transexcept) {
               SocketTransportUtil.logger.error(SocketTransportMessagesLogger.noDispatchPolicies(), 
                   transexcept);
          }
      }

      if (wmSet == null) // if JMXConnector not available or impossible to connect provide a simple 
                            edit field
      {
          uiObject = TransportUIFactory.createTextBox(curDispatchPolicy);
      } else // create a drop down list
      {   // adding default work manager to the list.
         wmSet.add(DEFAULT_WORK_MANAGER);
         String[] values = wmSet.toArray(new String[wmSet.size()]);
         uiObject = TransportUIFactory.createSelectObject(values,values,curDispatchPolicy,
                    TransportUIFactory.SelectObject.DISPLAY_LIST,false);
      }
      return TransportUIFactory.createEditField(DISPATCH_POLICY,
             TextMessages.getMessage(TextMessages.DISPATCH_POLICY,locale),
             TextMessages.getMessage(TextMessages.DISPATCH_POLICY_INFO,locale), uiObject);
 }

41.4.2 TransportProviderFactory

TransportProviderFactory lets you provide design-time functionality in JDeveloper. It includes methods for registering the custom transport provider and retrieves the ID you define for the provider. For information about the methods provided in this interface, see the Java API Reference for Oracle Service Bus.

The following sample shows how the sample socket transport implements this interface.

Example - Example of the Socket Transport Implementing the Interface

package com.bea.alsb.transports.sock;
 
import com.bea.wli.sb.transports.TransportManager;
import com.bea.wli.sb.transports.TransportException;
import com.bea.wli.sb.transports.TransportProviderFactory;
 
public class SocketTransportProviderFactory implements TransportProviderFactory
  {
 
    public void registerProvider(TransportManager tm) throws TransportException 
     {
       SocketTransportProvider instance = SocketTransportProvider.getInstance();
       tm.registerProvider(instance, null);
     }
 
    public String getId() {
        return SocketTransportProvider.ID;
     }
  }

41.4.3 TransportManagerHelper Methods

The TransportManagerHelper class provides methods to retrieve the Work Managers (dispatch policies), among others. For a complete list of methods provided in this interface, see the Java API Reference for Oracle Service Bus.