Class DynamicServiceRegistration<K,S extends ADEPT2Service>
- java.lang.Object
-
- de.aristaflow.adept2.base.service.DynamicServiceRegistration<K,S>
-
- 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!
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interface
DynamicServiceRegistration.DynamicServiceNotification<K>
This interface provides the means for signalling adding, updating and removing services to users of theDynamicServiceRegistration
.static class
DynamicServiceRegistration.RegistrationMode
The mode to register a service.
-
Field Summary
Fields Modifier and Type Field Description protected long
inactiveTime
The time in milliseconds how long a dynamically registered service may be inactive/unreachable.protected ReadWriteLock
lock
The lock for synchronising access to the data structures holding the services.protected Logger
logger
The logger used for information messages.protected DynamicServiceRegistration.DynamicServiceNotification<K>
notification
The notification to signal adding, updating and removing services to users of thisDynamicServiceRegistration
.protected Map<K,List<Pair<URI[],Long>>>
registered
The URIs of the registered services and the timestamp of the last contact.protected ServiceAccess
serviceAccess
The service access resolving theURI[]
to the corresponding service instance (proxy).protected Class<? extends S>
serviceClass
The class of the services handled by this class.protected ExecutorService
serviceResolver
The executor service used to resolve services concurrently.protected Function<SessionToken,SessionToken>
sessionProvider
The provider for creating child session tokens.protected Map<K,Pair<S,Integer>>
used
The services that have been dynamically registered and which are currently used.
-
Constructor Summary
Constructors Constructor Description 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 newDynamicServiceRegistration
for handing dynamically registered services.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected SortedMap<Integer,URI[]>
convertToMap(List<Pair<URI[],Long>> list)
Converts the designated list of services containingnull
elements to a sorted map containing the same elements (withoutnull
elements) indexed by the position in the list.S
getNewServiceFor(SessionToken session, K key)
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.S
getServiceFor(SessionToken parentSession, K key)
Gets the currently used service for the designated key.SortedMap<Integer,URI[]>
registerService(SessionToken parentSession, K key, URI[] serviceUris, DynamicServiceRegistration.RegistrationMode mode)
Registers the designated service (URI) for the designated key.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.SortedMap<Integer,URI[]>
unregisterService(SessionToken parentSession, K key, URI[] serviceUris)
Unregisters the service for the designated key.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.
-
-
-
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 theURI[]
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 fullSessionFactory
.
-
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.
-
notification
protected final DynamicServiceRegistration.DynamicServiceNotification<K> notification
The notification to signal adding, updating and removing services to users of thisDynamicServiceRegistration
.
-
-
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 newDynamicServiceRegistration
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 benull
.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 benull
.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 theURI[]
to the corresponding service instance (proxy).sessionProvider
- The provider for creating child session tokens. This avoids the need for a fullSessionFactory
.notification
- The notification to signal adding, updating and removing services to users of thisDynamicServiceRegistration
. This may benull
.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
URI
s 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 designatedURI
s, they may be appended to previously registered ones or it may benull
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
URI
s 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 anServiceNotKnownException
. - Throws:
ServiceNotKnownException
- If there is no available service registered for the designated key, aServiceNotFoundException
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, aServiceNotKnownException
will be thrown.
-
convertToMap
protected SortedMap<Integer,URI[]> convertToMap(List<Pair<URI[],Long>> list)
Converts the designated list of services containingnull
elements to a sorted map containing the same elements (withoutnull
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 containnull
elements.- Returns:
- A sorted map containing the URIs from the designated list indexed by the corresponding
position.
null
elements will be skipped.
-
-