Package com.sas.services.discovery

Discover a service based upon its service capabilities and optionally service attributes.

See:
          Description

Interface Summary
DiscoveryAdminInterface Interfaces used to manage the addition/removal of services to/from a discovery service and discovery delegates used to locate discoverable services.
DiscoveryServiceInterface Interface describing a discovery service in terms of its capability to act as a mechanism to find services based upon a desired service template and an administration interface that's used to add/remove services to the registry and to add/remove discovery delegates.
FindServiceInterface Interface describing how to find service(s) via the Discovery service.
LocalDiscoveryServiceInterface Interface describing a local discovery service that provides additional controls related to policy decisions peculiar to a local discovery service.
LookupPolicyInterface Interface describing service lookup policies that a local discovery service should observe: policy to retry to find services in the event that service(s) were not available at the time a request was submitted.
PassportInterface Passport interface.
ServiceDiscoveryConfigurationInterface Interface describing a service discovery configuration consisting of an ID used to uniquely identify a service across JVMs and optional service attributes which may be used to qualify a discovery lookup to distinguish among multiple services that satisfy the same service types.
 

Class Summary
AbstractDiscoveryService Abstract discovery service.
ActivatableDiscoveryService Remotely accessible discovery service.
DiscoveryLogger A logging service used to obtain loggers for the discovery subsystem.
DiscoveryService Discovery service used to store registered services and discovery delegates.
DiscoveryServiceConfiguration Configuration data for initializing or reconfiguring a Discovery service.
DiscoveryServiceFactory Factory used to manufacture a remotely accessible discovery service.
IdAttribute A foundation service discovery attribute representing an ID and ID type.
IsRemotelyAccessibleAttribute A foundation service discovery attribute which may be used to locate a service based on whether or not it can be accessed by remote clients.
LookupPolicyAttempts A service discovery policy that will re-attempt to lookup services for a specified number of attempts.
LookupPolicyTimeout A service discovery policy that will re-attempt to lookup services until the specified timeout occurs.
MetadataAttribute A service attribute that denotes membership in a group of software components.
RemoteDiscoveryServiceProxy Proxy to a discovery service that is capable of servicing remote clients.
ServiceDiscoveryConfiguration Service discovery configuration.
ServiceGroupAttribute A service attribute that denotes membership in a group of software components.
Services A collection of services that implement the RemoteServiceInterface interface.
ServicesCache Cache used to store foundation services.
ServiceTemplate A service request template that describes the type(s) of services expressed in terms of Java classes/interfaces representing the business interfaces and optional service attributes.
ServiceTypes Service capabilities expressed in terms of the Java interface(s) and/or class(es).
 

Exception Summary
ServiceNotAvailableException Service is not available exception.
 

Package com.sas.services.discovery Description

Discover a service based upon its service capabilities and optionally service attributes. The Discovery Service provides a mechanism to locate discoverable platform services.

Discovery Service

Overview

The Discovery service's purpose is to enable one to find a service implementation based upon desired service capabilities and optionally service attributes. A previously discovered service may also be re-discovered using its discovery service ID.

Service capabilities are specified in terms of the Java interface(s) implemented by a service. One may also specify the service instance's class or a superclass, but its recommended that one discovers a service using just its interfaces. Discovery occurs without requiring the client to have any knowledge of the underlying lookup mechanism(s) that are being used. Abstracting the lookup mechanism(s) enables us to minimize client code changes should we later decide to use an alternative service implementation.

Discovering a Service

Services are discovered based upon their service capabilities which represent the Java classes the service is, extends, or interfaces it implements. Typically one will discover a service based upon its service interface, for example a com.sas.services.logging.LoggingServiceInterface. Code snippets are provided below to illustrate the three ways one may discover a service.

Find a Service Based Upon Service Type(s)

This example illustrates how one finds a service based solely upon its service capabilities. In this example, we wish to locate a service that implements the LoggingServiceInterface.


// get default discovery service
DiscoveryServiceInterface discoveryService = DiscoveryService.defaultInstance();

// locate a logging service using the discovery service
LoggingServiceInterface loggingServiceIf = (LoggingServiceInterface)
   discoveryService.findService(
      new ServiceTemplate(new Class[] {
         com.sas.services.logging.LoggingServiceInterface.class}));

Find a Service Using its Discovery Service ID

This example illustrates how one initially discovers a service based upon its service capabilities and then later reacquires the same service using its service discovery ID.


// get default discovery service
DiscoveryServiceInterface discoveryService = DiscoveryService.defaultInstance();

// lookup a logging service using the discovery service
LoggingServiceInterface loggingService1 = (LoggingServiceInterface)
   discoveryService.findService(
      new ServiceTemplate(new Class[]
         {com.sas.services.logging.LoggingServiceInterface.class}));

// determine the service discovery ID which is part of an ancillary service
// discovery configuration available from the service's configuration.
//
// NOTE: ServiceConfigurationInterface.CONFIGURATION_SERVICE_DISCOVERY is
// the reserved lookup key used to obtain the service discovery configuration.

String serviceDiscoveryId = null;
final ServiceConfigurationInterface serviceConfig =
   loggingService1.getServiceConfiguration();
if (serviceConfig != null) {
   final ServiceConfigurationInterface serviceDiscoveryConfig =
      serviceConfig.getServiceConfiguration(
         ServiceConfigurationInterface.CONFIGURATION_SERVICE_DISCOVERY);
   if ((serviceDiscoveryConfig != null) &&
       (serviceDiscoveryConfig instanceof ServiceDiscoveryConfigurationInterface)) {
       serviceDiscoveryId = ((ServiceDiscoveryConfigurationInterface)
         serviceDiscoveryConfig).getDiscoveryId();
   }
}

// now if we wish to reacquire the same service at some later point,
// ask the discovery service to find it using its serviceDiscoveryId.

LoggingServiceInterface loggingService2 = (LoggingServiceInterface)
   discoveryService.findServiceUsingId(serviceDiscoveryId);

Find a Service Based Upon Service Capabilities and Attributes

This example illustrates how one can specify additional filtering criteria to distinguish among multiple services that satisfy the same service interface(s). Assume that multiple services are registered that implement the fictitious FakeServiceInterface service. We want to to find one that implements this interface, but also satisfies the following:

When we define our desired service template we now specify these additional attributes in addition to the service capabilities.


import com.sas.services.discovery.*;
import com.sas.services.discovery.IsRemotelyAccessibleAttribute;
import com.sas.services.discovery.rmi.sample.*;
...

// specify the desired service type(s)
final Class[] desiredServiceTypes = new Class[] {
   com.sas.services.fake.FakeServiceInterface.class};

// specify the optional attributes to be used to qualify a discovery lookup
final ServiceAttributeInterface[] serviceAttributes =
   new ServiceAttributeInterface[] {
      new IsRemotelyAccessibleAttribute(
         Boolean.FALSE),    // this service is not remotely accessible
      new StateParkAttribute(
         "jellystone park", // state park's name
         null,              // # of picnic shelters (don't care)
         Boolean.FALSE),    // allowed to feed the bears
      new BearAttribute(
         "yogi",            // bear's name
         null),             // bear's dispostion (don't care)
      new BearAttribute(
         "boo boo",         // bear's name
         "nice")};          // bear's disposition

final ServiceTemplate serviceTemplate = new ServiceTemplate(
   desiredServiceTypes,
   serviceAttributes);

final FakeServiceInterface fakeService = (FakeServiceInterface)
   DiscoveryService.defaultInstance().findService(serviceTemplate);

Model

The Discovery service employs a "Chain of Command" design pattern to find a service based upon a requested service template. This design pattern is explained in the table below.

Intent "Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it." Chain of Command design pattern - Gamma, Helm, Johnson, Vlissides, 1994, p. 223
Motivation
  • Decouple senders and receivers
  • The object that made the request has no explicit knowledge of who will handle it. (Implicit Receiver)
  • Give multiple objects a chance to handle the request 

In order to forward the event or message along the chain, each element or class in the chain must share a common interface for:

Applicability
  • More than one object may handle a request,
  • handler isn't known a priori,
  • the handler should be ascertained automatically,
  • it is desired to issue the request to one of several objects without specifying the receiver explicitly, and
  • the set of objects that can handle a request should be specified dynamically

In order to forward the event or message along the chain, each element or class in the chain must share a common interface for:

Participants FindServiceInterface defines a handler interface used to request a service.

A handler implmentation attempts to fulfill this request. It may also optionally implement the successor link to which it will delegate the request.

If the handler can fulfill the request, then it does so. If the handler cannot fulfill the request, then it passes the request on to it's successor if a successor exists.

How to Implement a Discoverable Service

Service implementations may be exposed via the Discovery Service if the following considerations are observed:

Examples

This section presents an example illustrating use of the Discovery Service.

Example: Service Lookup Using Local Discovery Service

This section first presents an example showing how to find a service using a local discovery service previously bootstrapped using the ServiceLoader. Service deployment using the ServiceLoader utility is discussed in the com.sas.services.deployment package's documentation.

import com.sas.services.discovery.DiscoveryService;
import com.sas.services.discovery.ServiceNotAvailableException;

...

   try {
      //
      // Discover a service implementation through its service
      // types, for example an LoggingServiceInterface...
      //
      final Class[] desiredServiceTypes = new Class[] {
         com.sas.services.logging.LoggingServiceInterface.class
      };

      //
      // DiscoveryService.defaultInstance() returns a local implementation
      // of the DiscoveryServiceInterface. The local discovery service may then
      // be used to find an object based upon its desired service capabilities.
      //
      // A ServiceNotAvailableException is thrown if the Discovery Service
      // can't find a service that satisfies the requested service capabilities.
      //
      final LoggingServiceInterface loggingService = (LoggingServiceInterface)
         DiscoveryService.defaultInstance().findService(
            new ServiceTemplate(desiredServiceTypes));

      //
      // Use the discovered Logging Service...
      //
      loggingService.debug("My debug message");
   }
   catch (ServiceNotAvailableException e) {
      // This exception will be thrown if you attempt to discover a
      // service that is not accessible by the Discovery Service
      System.out.println(e.getMessage());
   }

Example: Distributed Deployment and Service Lookup From Another Process

A sample application has been created to demonstrate use of the Discovery Service.

  1. Start a process responsible for deploying a distributable implementation of Foundation Services
  2. Start a process that will attempt to locate a remotely accessible Discovery Service, locate a service based upon desired service capabilities, and then use the remotely discovered service.
This sample employs the com.sas.services.deployment.ServiceLoader class. Refer to its main method for specifics.


//
// Startup a process that will deploy services belonging to the service
// deployment "ID Portal - distributed core services":
//
// This process may be exited by keying the Enter key in the console window.
//
// NOTE:
// -Dcom.sas.services.logging.configurationURL=<alternate log configuration>
// Omit this item to accept the log default. Refer to the Logging Service
// API for additional details.
//

C:\sample>java
-Djava.security.policy=C:/sample/policy
-Djava.rmi.server.codebase="
   file:/c:/jars/sas.svc.core.jar
   file:/c:/jars/sas.oma.joma.jar
   file:/c:/jars/sas.oma.joma.rmt.jar
   file:/c:/jars/sas.core.jar
   file:/c:/jars/sas.text.jar"
-Dlog4j.configuration=file:/C:/sample/log4j.properties
-Djava.security.auth.policy=C:/sample/auth.policy
-Djava.security.auth.login.config=C:/sample/login.config
-Dcache.auth.policy=true
-Dcom.sas.services.logging.configurationURL=file:C:\sample\LoggingConfig.xml

com.sas.services.deployment.ServiceLoader

0
"ID Portal - distributed core services"
"file:/C:/sample/sas_service_deployment_export_idportal_2.xml"


//
// Startup a process that will bootstrap the local discovery service with
// remote discovery service(s) that have been previously deployed and
// available via an RMI naming lookup.
//
// Look for services that are in the "BIP Software Components" SoftwareComponent
// hierarchy that are associated with a deployment group named
// "Core Platform Services":
//
// This sample application will first initialize its local discovery service
// with remotely available discovery services. Upon completion of this bootstrap
// it will then attempt to discover a Logging Service which should be
// accessible via the remote discovery service.
//
// NOTE:
// -Dcom.sas.services.logging.configurationURL=<alternate log configuration>
// Omit this item to accept the log default. Refer to the Logging Service
// API for additional details.
//

C:\sample>java
-Djava.security.policy=C:/sample/policy
-Dlog4j.configuration=file:/C:/sample/log4j.properties
-Djava.security.auth.policy=C:/sample/auth.policy
-Djava.security.auth.login.config=C:/sample/login.config
-Dcache.auth.policy=true
-Dcom.sas.services.logging.configurationURL=file:C:\sample\LoggingConfig.xml

com.sas.services.deployment.ServiceLoader

1
"ID Portal - distributed core services"
"file:/C:/sample/sas_service_deployment_export_idportal_2.xml"




Copyright © 2006 SAS Institute Inc. All Rights Reserved.
javadoc generated Fri, 10 Feb 2006 17:28:50