Class DynamicServiceRegistration<K,​S extends ADEPT2Service>

  • Type Parameters:
    K - The key identifying a service type, i. e. a list of service instances.
    S - The type of dynamically registered services handled by this class.

    public class DynamicServiceRegistration<K,​S extends ADEPT2Service>
    extends Object
    This class provides the means for handling dynamically registered services including registering and unregistering. The services are indexed by a key of arbitrary type, each key may have one or more registered services. The services are identified via their URI (URI[]). When registering, services can be appended to this list, or a service can replace the existing list. Only one service from the list is used at a time. This service is being held as object, i. e. the service instance or a proxy for it. This service is used until it is replaced by a newly registered one or until it does not respond any more. When not responding, the used service will be replaced by another one from the list (of the same key). All services from a list will be contacted concurrently, and the first responding service will be chosen. Previous services will be preferred over later services in the list. The index of a service within the list is used within the API to identify a service, i. .e. the key and the index in the corresponding list identify a service uniquely.
    For each service the last time of contact is tracked (this needs to be signalled by the users of this class). This time is respected for unresponsive services. The service will only be removed if it has not responded for a longer time. This allows for short outages having no consequences.

    A used service which is not responding, can easily be exchanged with a registered one that is responding. This has to be signalled by the users since they detect the service not responding.

    For synchronising access to the services and their details (e. g. contact timestamps), a read/write lock is used. This is provided by the users so that synchronisation can incorporate data structures of the users. Also there is a callback interface that notifies adding, updating or removing a service. This allows for adapting other data structures. While notifying, the write lock is being held!

    • Field Detail

      • logger

        protected final Logger logger
        The logger used for information messages.
      • lock

        protected final ReadWriteLock lock
        The lock for synchronising access to the data structures holding the services. This is provided by the users of this class so synchronisation may incorporate additional data structures.
      • inactiveTime

        protected final long inactiveTime
        The time in milliseconds how long a dynamically registered service may be inactive/unreachable. If the last contact is longer ago than this time and the service is currently not reachable, it will be removed.
      • serviceClass

        protected final Class<? extends S extends ADEPT2Service> serviceClass
        The class of the services handled by this class.
      • serviceAccess

        protected final ServiceAccess serviceAccess
        The service access resolving the URI[] to the corresponding service instance (proxy).
      • sessionProvider

        protected final Function<SessionToken,​SessionToken> sessionProvider
        The provider for creating child session tokens. This avoids the need for a full SessionFactory.
      • registered

        protected final Map<K,​List<Pair<URI[],​Long>>> registered
        The URIs of the registered services and the timestamp of the last contact. Note that these lists may contain null elements after unregistering a service from within the list.
      • used

        protected final Map<K,​Pair<S extends ADEPT2Service,​Integer>> used
        The services that have been dynamically registered and which are currently used. These are cached stubs to avoid URI resolution for each request. The second element is the index in the list of registered URIs for this script type.
      • serviceResolver

        protected final ExecutorService serviceResolver
        The executor service used to resolve services concurrently. This will be used when requiring a new used service which will concurrently contact all registered services.
    • Constructor Detail

      • DynamicServiceRegistration

        public DynamicServiceRegistration​(Map<K,​List<Pair<URI[],​Long>>> registered,
                                          ReadWriteLock lock,
                                          long inactiveSeconds,
                                          Class<? extends S> serviceClass,
                                          ServiceAccess serviceAccess,
                                          Function<SessionToken,​SessionToken> sessionProvider,
                                          DynamicServiceRegistration.DynamicServiceNotification<K> notification,
                                          LogService logService)
        Constructs a new DynamicServiceRegistration for handing dynamically registered services.
        Parameters:
        registered - The registered services known so far. This may stem from a database or alike, e. g. by storing the map provided when shutting down. This may be null.
        lock - The lock for synchronising access to the data structures holding the services. The external provision allows the synchronisation to incorporate additional data structures. This may be null.
        inactiveSeconds - The time in milliseconds how long a dynamically registered service may be inactive/unreachable. If the last contact is longer ago than this time and the service is currently not reachable, it will be removed.
        serviceClass - The class of the services handled by this class.
        serviceAccess - The service access resolving the URI[] to the corresponding service instance (proxy).
        sessionProvider - The provider for creating child session tokens. This avoids the need for a full SessionFactory.
        notification - The notification to signal adding, updating and removing services to users of this DynamicServiceRegistration. This may be null.
        logService - The log service for retrieving the class-specific logger for this instance.
    • Method Detail

      • shutdown

        public Map<K,​List<Pair<URI[],​Long>>> shutdown​(boolean emergency)
        Terminates the executor service for concurrently connecting to registered service and returns the currently registered services (rather their URIs) including the last contact time.

        After calling this method this DynamicServiceRegistration should no longer be used.

        Parameters:
        emergency - Whether the shutdown will be an emergency shutdown.
        Returns:
        All registered services (rather their URIs), indexed by the corresponding keys and including the last contact time.
      • registerService

        public SortedMap<Integer,​URI[]> registerService​(SessionToken parentSession,
                                                              K key,
                                                              URI[] serviceUris,
                                                              DynamicServiceRegistration.RegistrationMode mode)
        Registers the designated service (URI) for the designated key. If there is already a service registered for the designated key, the designated service will be either be ignored, replace all existing services registered for the same key or be appended at the end of the list of known services. When trying to append a service already known (i. e. the URIs are already registered), this service will be silently ignored.
        Parameters:
        parentSession - The session for checking access rights.
        key - The key for which to register the designated service dynamically.
        serviceUris - The (URIs of the) service to be dynamically registered.
        mode - The registration mode with which to register this service.
        Returns:
        The URIs of the services which are currently registered for the designated key indexed by the corresponding position in the list of all registered services. These may be the designated URIs, they may be appended to previously registered ones or it may be null in case registering the designated service has not been successful.
      • unregisterService

        public SortedMap<Integer,​URI[]> unregisterService​(SessionToken parentSession,
                                                                K key,
                                                                URI[] serviceUris)
        Unregisters the service for the designated key. Unregistering will only be successful, if the designated URIs are registered for the designated key. Otherwise this call will be ignored.
        Parameters:
        parentSession - The session for checking access rights.
        key - The key for which to unregister the designated service dynamically.
        serviceUris - The (URIs of the) service to be dynamically unregistered.
        Returns:
        The URIs of the services which are currently registered for the designated key after unregistering the designated service indexed by the corresponding position in the list of all registered services. If this method call unregisters the designated key completely, an empty map will be returned. If the designated key is not registered, null will be returned.
      • getServiceFor

        public S getServiceFor​(SessionToken parentSession,
                               K key)
                        throws ServiceNotKnownException
        Gets the currently used service for the designated key. If there is currently service in use for this key, all corresponding registered services will be contacted, and the first in the list that has responded will become the service in use.
        Services that do not respond and of which the last contact is too long ago will be unregistered.
        Parameters:
        parentSession - The session for checking access rights.
        key - The key for which to retrieve the currently used service.
        Returns:
        The currently used service for the designated key. This will never be null because not finding a suitable service will throw an ServiceNotKnownException.
        Throws:
        ServiceNotKnownException - If there is no available service registered for the designated key, a ServiceNotFoundException will be thrown.
      • updateContactData

        public void updateContactData​(SessionToken parentSession,
                                      K key,
                                      long timestamp)
        Updates the last contact of the service for the designated key which is currently used to the designated timestamp.
        Parameters:
        parentSession - The session for checking access rights.
        key - The key for which to update the last contact of the currently used service.
        timestamp - The timestamp of the last contact.
      • getNewServiceFor

        public S getNewServiceFor​(SessionToken session,
                                  K key)
                           throws ServiceNotKnownException
        Gets a new service for the designated key, i. e. the registered services (after the currently used one) are being contacted and the first successfully contacted service will become the new used service. This will be returned.
        Parameters:
        session - The session for checking access rights.
        key - The key for which to get a new service, i. e. the currently used one will be replaced by another registered service.
        Returns:
        The new used service for the designated key.
        Throws:
        ServiceNotKnownException - If no service has been successfully contacted for the designated key, a ServiceNotKnownException will be thrown.
      • convertToMap

        protected SortedMap<Integer,​URI[]> convertToMap​(List<Pair<URI[],​Long>> list)
        Converts the designated list of services containing null elements to a sorted map containing the same elements (without null elements) indexed by the position in the list.
        The arrays from the list will be cloned to prevent changing them via side effects.
        Parameters:
        list - The list of (registered) services which may contain null elements.
        Returns:
        A sorted map containing the URIs from the designated list indexed by the corresponding position. null elements will be skipped.