*** This package contains classes that are subject to change. ***
Note:
Extension of the classes in this package is prohibited unless otherwise documented. Similarly, extension or implementation of the interfaces in this package is prohibited except as documented.Package com.sas.services.discovery
Discover a service based upon its service capabilities and optionally service attributes. The Discovery Service provides a mechanism to locate 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.information.InformationServiceInterface. Code snippets are
provided below to illustrate the three ways one may discover a service.
- Based upon its service capabilities
- A previously discovered service can be re-discovered using its service's discovery ID
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 com.sas.services.information.InformationServiceInterface.
import com.sas.services.information.InformationServiceInterface;
// get default discovery service
DiscoveryServiceInterface discoveryService = DiscoveryService.defaultInstance();
// locate a logging service using the discovery service
InformationServiceInterface infoServiceIf = (InformationServiceInterface)
discoveryService.findService(
new ServiceTemplate(new Class[] {
InformationServiceInterface.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 get the same service using its service discovery ID.
import com.sas.services.information.InformationServiceInterface;
// get default discovery service
DiscoveryServiceInterface discoveryService = DiscoveryService.defaultInstance();
// lookup a logging service using the discovery service
InformationServiceInterface loggingService1 = (InformationServiceInterface)
discoveryService.findService(
new ServiceTemplate(new Class[]
{InformationServiceInterface.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 =
infoService1.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 get the same service at some later point,
// ask the discovery service to find it using its serviceDiscoveryId.
InformationServiceInterface infoService2 = (InformationServiceInterface)
discoveryService.findServiceUsingId(serviceDiscoveryId);
|
Find a Service Based Upon Service Capabilities and Attributes
An application may desire to find a service that not only satisfies a particular business interface, but also attributes which may be used to differentiate a service from other services satisfying the same interface. When a service is deployed, attributes are added to its service discovery configuration that enable one to locate it based upon the following considerations:
- accessibility to remote clients
- host on which a service was deployed
- JVM in which a service was deployed
- application's service deployment
- service's component
- name/value attributes which a user may have associated to a service deployment, service deployment group, or service
Refer to the documentation for the ServiceTemplate class for code examples.
Using JMX to View Registered Services
One may inspect the services that are registered with the Discovery Service as well as their configured service templates using a JMX console if one has enabled JMX for SAS Foundation Services.
The following snapshot shows the services that are registered with the Discovery Service when viewed with the jManage JMX console.
![]() |
The following snapshot shows a service template configuration for an Information Service when viewed with the jManage JMX console. One may discover this service using the service interface(s) and optionally attribute(s) defined in this template.
![]() |
![]() |
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 |
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 |
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:
- Implement a Service
- Your service must implement one of the following two interfaces:
com.sas.services.ServiceInterfacecom.sas.services.RemoteServiceInterface
RemoteServiceInterfaceis the base service interface. Its methods declare that they throwRemoteExceptionwhich is a requirement for remote interfaces. This interface must be used for a service implementation that is intended for use in a distributed environment.ServiceInterfaceextendsRemoteServiceInterface. This interface is identical to its super interface except that its methods do not throwRemoteExceptions. Use this interface if your service will only be used in a local JVM (i.e. no remote interfaces). The best way to satisfy this interface requirement is to have your service implementation extend eithercom.sas.services.AbstractServiceorcom.sas.services.AbstractRemoteService(local and distributed versions respectively). - Implement one or more Java interfaces that specify the methods that your service will support (i.e. the the "InformationService" implements "InformationServiceInterface"). These interfaces will define the capabilities of your service that you wish to expose to your consumer.
- If your service is to be used in a distributed deployment,
it must serializable. Explicitly specify a
serialVersionUID, so that you will have control over whether or not your service is backward compatible with previous versions.Note: Each serializable class should have an attribute that specifies its serial version UID. For example, use
long serialVersionUID = 2153634929598531287L;for an interface orpublic static final long serialVersionUID = -1428994704601244397L;for a class.To generate a serial version UID, compile your .java file and then use the
serialver.exelocated in the JRE\bin directory to generate an ID.For example,
C:\classes>set classpath=%classpath%anyJarFilesYourStuffUses.jar; C:\classes>serialver -show A "Serial Version Inspector" dialog will appear. Enter a qualified class name in the "Full Class Name" text field and then activate the "Show" button. Cut/paste the "Serial Version" into your code.
- Your service must implement one of the following two interfaces:
- Implement a Service Factory
- The
com.sas.services.deployment.ServiceLoaderwill be used to instantiate and initialize your service. TheServiceLoaderwill invoke the the default constructor of the service factory specified in your service's deployment configuration. Your service factory must implement thecom.sas.services.ServiceFactoryInterfacewhich specifies one method:RemoteServiceInterface getService( final ServiceConfigurationInterface serviceConfiguration) throws ServiceException;A typical implementation will overload thegetService()method to accept other types of initialization objects. Note thatRemoteServiceInterfaceis the base service interface, so the service returned by this method may be either a local or distributable service. We have adopted a Java class naming convention of "XxxServiceFactory.java" where "Xxx" is the name of your service. For example, the service factory for "InformationServiceInterface.java" would be "InformationServiceFactory.java" - The
ServiceConfigurationInterfacewill provide your service with an initialization object derived from the service deployment configuration. The initialization object that theServiceLoaderwill provide will be of typecom.sas.services.ServiceInitializationObjectwhosegetInitializationObject()method will return an object of typeStringrepresenting the XML fragment containing your service's initialization data. - Most of the current service implementations translate this XML initialization
configuration into an initialization object that is ultimately used
to initialize their service. This has the advantage of being able to use
the same initialization code whether your service is being instantiated
by the
ServiceLoaderwhich provides XML data or directly using your service initialization object (i.e. "com.sas.services.logging.LoggingServiceInitObject");
- The
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 InformationServiceInterface...
//
final Class[] desiredServiceTypes = new Class[] {
com.sas.services.infomration.InformationServiceInterface.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 InformationServiceInterface informationService = (InformationServiceInterface)
DiscoveryService.defaultInstance().findService(
new ServiceTemplate(desiredServiceTypes));
//
// Use the discovered Information Service...
//
}
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.
- Start a process responsible for deploying a distributable implementation of Foundation Services
- 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.config
-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 -Dlog4j2.configurationFile=file:///C:/sample/log4j2.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" |
-
ClassDescriptionAbstract discovery service.Remotely accessible discovery service.Interfaces used to manage the addition/removal of services to/from a discovery service and discovery delegates used to locate services.Discovery service used to store registered services and discovery delegates.Configuration data for initializing or reconfiguring a Discovery service.Factory used to manufacture a remotely accessible discovery service.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.Interface describing how to find service(s) via the Discovery service.A foundation service discovery attribute which may be used to locate a service which has been deployed on a particular host by using the host's name and/or IP address.A foundation service discovery attribute representing an ID and ID type.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.A foundation service discovery attribute which may be used to locate a service which has been instantiated in the local JVM or the same JVM as another previously discovered service.Interface describing a local discovery service that provides additional controls related to policy decisions peculiar to a local discovery service.A service discovery policy that will re-attempt to lookup services for a specified number of attempts.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.A service discovery policy that will re-attempt to lookup services until the specified timeout occurs.A service attribute that denotes membership in a group of software components.A foundation service discovery attribute which may be used to find a service based upon a name/value.Passport interface.A discovery service which can be used to locate foundation services which have been bound to an RMI registry.Marker interface used to denote a discovery service that is capable of servicing remote clients.Proxy to a discovery service that is capable of servicing remote clients.A foundation service discovery attribute which represents an foundation service.A foundation service discovery attribute which represents an application's service deployment which may be used to discover a foundation service that belongs to a particular service deployment.Service discovery configuration.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.A service attribute that denotes membership in a group of software components.Service is not available exception.A type-safe collection of services which implement the
RemoteServiceInterfaceinterface.Cache used to store foundation services.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.Service capabilities expressed in terms of the Java interface(s) and/or classes.


