ClarityAPI
bean as an aspect.
Looks to see what objects have already been fetched or created and, if they
are in the cache, doesn't go back to the server for them. Creates, updates and
deletes are passed through immediately.
The "stateful" Artifact
class produces some problems. There is more than
one way these could be handled, where an Artifact's state (specifically its QC flag)
will be different for different number of its "state" URI parameter.
This implementation uses a "latest available" strategy, where if the state
requested for an Artifact is earlier than the one in the cache, the cached version
is returned. If a later state is requested, it is fetched and replaces the one in
the cache.
This strategy may not be suitable for all cases and future refinements will allow
different strategies to be selected.
-
Field Summary
Modifier and TypeFieldDescriptionprotected ClarityAPI
The API this aspect will call through to.protected ClarityAPIInternal
The API again, but via its internal interface.protected CacheStatefulBehaviour
The behaviour for dealing with stateful entities.protected CacheManager
The cache manager.protected LatestVersionsResetAspect
The aspect that resets API version behaviour.protected Logger
Logger. -
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
Makes sure the effects ofClarityAPI.overrideStateful()
is reset after a call.void
clear()
Clears the cache of all cached entities.void
Join point for theClarityAPI.create
method.void
Join point for theClarityAPI.createAll
method.void
Join point for theClarityAPI.delete
method.void
Join point for theClarityAPI.deleteAll
method.void
Join point for theClarityAPI.deleteAndRemoveFile
method.protected CacheStatefulBehaviour
Get the type of stateful behaviour to use for the current call.protected <E extends Locatable>
EgetFromWrapper
(org.cruk.clarity.api.cache.CacheElementWrapper wrapper) Get the object from its cache wrapper.boolean
isCacheable
(Class<?> entityClass) Test whether entities of a class are cacheable.boolean
isCacheable
(Object thing) Test whether an entity is cacheable.boolean
isCacheable
(Collection<?> entities) Test whether a collection of entities is cacheable.protected boolean
Convenience method to test whether the latest version of stateful entities is required.boolean
isStateful
(Class<?> entityClass) Test whether entities of a class are stateful.boolean
isStateful
(Object thing) Test whether an entity is stateful.boolean
isStateful
(Collection<?> entities) Test whether a collection of entities is stateful.keyFromLocatable
(Locatable thing) Extract the cache key value from the given object's URI.keyFromUri
(String uri) Extract the cache key value from the given URI string.keyFromUri
(URI uri) Extract the cache key value from the given URI.Join point for theClarityAPI.loadAll
method.Join point for theClarityAPI.load
methods taking an id and a class.Join point for theClarityAPI.load
methods taking aLimsLink
.protected Object
loadOrRetrieve
(ProceedingJoinPoint pjp, String uri, Class<?> entityClass) Fetch an object from the cache or, if it's not yet been seen, from the API and store the result in the cache for future use.void
Join point for theClarityAPI.reload
method.Join point for theClarityAPI.retrieve
methods.Join point for the methods that take an object in to perform an operation and return an object as a result (not necessarily object passed in).void
setCacheManager
(CacheManager cacheManager) Set the Ehcache cache manager.void
setClarityAPI
(ClarityAPI api) Sets the API being used.void
setInternalClarityAPI
(ClarityAPIInternal internalApi) Set the internal interface access to the API.void
setLatestVersionsResetAspect
(LatestVersionsResetAspect latestVersionsResetAspect) Set a reference to the aspect that resets the API's behaviour around stateful entities.void
setStatefulBehaviour
(CacheStatefulBehaviour behaviour) Set the behaviour for dealing with stateful objects.protected String
toUriString
(Class<?> entityClass, String... ids) Assemble a URI for an object's id and class.void
Join point for theClarityAPI.update
method.void
Join point for theClarityAPI.updateAll
method.Join point for theClarityAPI.uploadFile
method.long
versionFromLocatable
(Locatable thing) Extract the state value from the given object's URI, if such an entity can have a state value.long
versionFromUri
(String uri) Extract the state value from a string version of a URI.long
versionFromUri
(URI uri) Extract the state value from a URI.
-
Field Details
-
logger
Logger. -
api
The API this aspect will call through to. -
apiCacheControl
The API again, but via its internal interface. -
cacheManager
The cache manager. -
latestVersionsResetAspect
The aspect that resets API version behaviour. -
behaviour
The behaviour for dealing with stateful entities.
-
-
Constructor Details
-
ClarityAPICache
public ClarityAPICache()Empty constructor.
-
-
Method Details
-
setClarityAPI
Sets the API being used.- Parameters:
api
- The ClarityAPI bean.
-
setInternalClarityAPI
@Autowired @Qualifier("clarityAPI") public void setInternalClarityAPI(ClarityAPIInternal internalApi) Set the internal interface access to the API.- Parameters:
internalApi
- The API bean, but through its internal interface.
-
setCacheManager
Set the Ehcache cache manager.- Parameters:
cacheManager
- The cache manager.
-
setLatestVersionsResetAspect
@Autowired public void setLatestVersionsResetAspect(LatestVersionsResetAspect latestVersionsResetAspect) Set a reference to the aspect that resets the API's behaviour around stateful entities.- Parameters:
latestVersionsResetAspect
- The version resetting aspect.- See Also:
-
setStatefulBehaviour
Set the behaviour for dealing with stateful objects. Note that changing this behaviour during operation clears the cache.- Parameters:
behaviour
- The desired behaviour.- Since:
- 2.22
-
clear
public void clear()Clears the cache of all cached entities. -
cancelStatefulOverride
Makes sure the effects ofClarityAPI.overrideStateful()
is reset after a call. The API itself has its own wrapper to clear this after a call, but if the cache intercepts the call and doesn't call through to the API (because the objects are already in the cache) we need to make sure the behaviour reverts to respecting the state version anyway.If one considers this, it might not be necessary because when the API is instructed to fetch the most recent, the call will always pass through the cache. This is a belt and braces method.
- Parameters:
jp
- The join point.- See Also:
-
retrieve
Join point for theClarityAPI.retrieve
methods. Fetches the object requested, either from the cache or from the API.- Parameters:
pjp
- The join point object.- Returns:
- The object retrieved.
- Throws:
Throwable
- if there is an error.- See Also:
-
loadById
Join point for theClarityAPI.load
methods taking an id and a class. Fetches the object requested, either from the cache or from the API.- Parameters:
pjp
- The join point object.- Returns:
- The object retrieved.
- Throws:
Throwable
- if there is an error.- See Also:
-
loadByLink
Join point for theClarityAPI.load
methods taking aLimsLink
. Fetches the object requested, either from the cache or from the API.- Parameters:
pjp
- The join point object.- Returns:
- The object retrieved.
- Throws:
Throwable
- if there is an error.- See Also:
-
getFromWrapper
protected <E extends Locatable> E getFromWrapper(org.cruk.clarity.api.cache.CacheElementWrapper wrapper) Get the object from its cache wrapper. In its own method to suppress unchecked warnings.- Type Parameters:
E
- The type of object held in the cache element.- Parameters:
wrapper
- The cache Element.- Returns:
- The object in the cache element.
-
loadOrRetrieve
protected Object loadOrRetrieve(ProceedingJoinPoint pjp, String uri, Class<?> entityClass) throws Throwable Fetch an object from the cache or, if it's not yet been seen, from the API and store the result in the cache for future use.Special consideration has to be made for objects that have a "state" parameter to their URIs. See the class description for more details.
- Parameters:
pjp
- The join point object.uri
- The URI of the object to fetch.entityClass
- The type of object to fetch.- Returns:
- The object retrieved.
- Throws:
Throwable
- if there is an error.
-
loadAll
Join point for theClarityAPI.loadAll
method. Examines the cache for objects already loaded and only fetches those that are not already seen (or, for stateful objects, those whose requested state is later than that in the cache).- Type Parameters:
E
- The type of LIMS entity referred to.- Parameters:
pjp
- The join point object.- Returns:
- The list of entities retrieved.
- Throws:
Throwable
- if there is an error.- See Also:
-
reload
Join point for theClarityAPI.reload
method. Force a reload from the API of an object by fetching again and updating its cache entry.- Parameters:
pjp
- The join point object.- Throws:
Throwable
- if there is an error.- See Also:
-
create
Join point for theClarityAPI.create
method. Create the object through the API and, if it can be cached, record it in the cache.- Parameters:
pjp
- The join point object.- Throws:
Throwable
- if there is an error.- See Also:
-
createAll
Join point for theClarityAPI.createAll
method. Create the objects through the API and, if they can be cached, record them in the cache.- Parameters:
pjp
- The join point object.- Throws:
Throwable
- if there is an error.- See Also:
-
update
Join point for theClarityAPI.update
method. Update the object through the API and, if it can be cached, update the record in the cache.- Parameters:
pjp
- The join point object.- Throws:
Throwable
- if there is an error.- See Also:
-
updateAll
Join point for theClarityAPI.updateAll
method. Update the objects through the API and, if they can be cached, update their records in the cache.- Parameters:
pjp
- The join point object.- Throws:
Throwable
- if there is an error.- See Also:
-
delete
Join point for theClarityAPI.delete
method. Delete the object through the API and, if it can be cached, remove it from the cache.- Parameters:
pjp
- The join point object.- Throws:
Throwable
- if there is an error.- See Also:
-
deleteAll
Join point for theClarityAPI.deleteAll
method. Delete the objects through the API and, if they can be cached, remove their records from the cache.- Parameters:
pjp
- The join point object.- Throws:
Throwable
- if there is an error.- See Also:
-
runSomething
Join point for the methods that take an object in to perform an operation and return an object as a result (not necessarily object passed in). For example,ClarityAPI.executeProcess
andClarityAPI.beginProcessStep
.Run the operation and store the resulting object in the cache (if cacheable).
- Parameters:
pjp
- The join point object.- Returns:
- The object created by the operation.
- Throws:
Throwable
- if there is an error.- See Also:
-
uploadFile
Join point for theClarityAPI.uploadFile
method. Call through to the API to do the work and store the resultingClarityFile
object in the cache.- Parameters:
pjp
- The join point object.- Returns:
- The file record in the Clarity LIMS.
- Throws:
Throwable
- if there is an error.- See Also:
-
deleteAndRemoveFile
Join point for theClarityAPI.deleteAndRemoveFile
method. Call through to the API to do the work and remove theClarityFile
object from the cache.- Parameters:
pjp
- The join point object.- Throws:
Throwable
- if there is an error.- See Also:
-
toUriString
Assemble a URI for an object's id and class.Uses the reference to the ClarityAPI to obtain the current server address.
This method essentially replicates
ClarityAPIImpl.limsIdToUri(String, Class)
but is looser on the class object it accepts for entityClass and doesn't create the URI object for the identifier.- Parameters:
entityClass
- The class of the entity.ids
- The LIMS id(s) of the entity.- Returns:
- A URI in string form for the entity.
-
isCacheable
Test whether a collection of entities is cacheable. Finds the first non-null item in the list an tests itsClarityEntity
annotation. Assumes the collection is homogeneous in its content.- Parameters:
entities
- The collection to test.- Returns:
true
if the first non-null item is the list is cacheable,false
otherwise (including for a null or empty list).- See Also:
-
isCacheable
Test whether an entity is cacheable. If the object given is not null, examine itsClarityEntity
annotation for its "cacheable" attribute and return that value.- Parameters:
thing
- The object to test.- Returns:
true
ifthing
is not null, is annotated with theClarityEntity
annotation, and that annotation has its "cacheable" attribute set to true;false
otherwise.- See Also:
-
isCacheable
Test whether entities of a class are cacheable. Tests whether the given class is annotated with theClarityEntity
annotation and, if so, its "cacheable" attribute is set.- Parameters:
entityClass
- The class to test.- Returns:
true
ifentityClass
is annotated with theClarityEntity
annotation, and that annotation has its "cacheable" attribute set to true;false
otherwise.- See Also:
-
isStateful
Test whether a collection of entities is stateful. Finds the first non-null item in the list an tests itsClarityEntity
annotation. Assumes the collection is homogeneous in its content.- Parameters:
entities
- The collection to test.- Returns:
true
if the first non-null item is the list is stateful,false
otherwise (including for a null or empty list).- See Also:
-
isStateful
Test whether an entity is stateful. If the object given is not null, examine itsClarityEntity
annotation for its "stateful" attribute and return that value.- Parameters:
thing
- The object to test.- Returns:
true
ifthing
is not null, is annotated with theClarityEntity
annotation, and that annotation has its "stateful" attribute set to true;false
otherwise.- See Also:
-
isStateful
Test whether entities of a class are stateful. Tests whether the given class is annotated with theClarityEntity
annotation and, if so, its "stateful" attribute is set.- Parameters:
entityClass
- The class to test.- Returns:
true
ifentityClass
is annotated with theClarityEntity
annotation, and that annotation has its "stateful" attribute set to true;false
otherwise.- See Also:
-
versionFromLocatable
Extract the state value from the given object's URI, if such an entity can have a state value.- Parameters:
thing
- The entity to extract the state for.- Returns:
- The state number, or
NO_STATE_VALUE
if either the object is not a stateful object or there is no state information in the object's URI.
-
versionFromUri
Extract the state value from a URI.- Parameters:
uri
- The URI to dissect for a state value.- Returns:
- The state number, or
NO_STATE_VALUE
if there is no state information in the URI.
-
versionFromUri
Extract the state value from a string version of a URI.- Parameters:
uri
- The URI string to dissect for a state value.- Returns:
- The state number, or
NO_STATE_VALUE
if there is no state information in the URI.
-
keyFromLocatable
Extract the cache key value from the given object's URI. This is the full path of the entity, less any query string.- Parameters:
thing
- The entity to extract the key for.- Returns:
- The cache key value.
-
keyFromUri
Extract the cache key value from the given URI. This is the full path of the entity, less any query string.- Parameters:
uri
- The URI to extract the key from.- Returns:
- The cache key value.
-
keyFromUri
Extract the cache key value from the given URI string. This is the full path of the entity, less any query string.- Parameters:
uri
- The URI string to extract the key from.- Returns:
- The cache key value.
-
getBehaviourForCall
Get the type of stateful behaviour to use for the current call. If there is an override that requires the exact version, behave on this call as if the cache were in EXACT operation (for the fetch, not the store). Otherwise return the configured behaviour.- Returns:
- The cache behaviour to use this time.
-
isFetchLatestVersions
protected boolean isFetchLatestVersions()Convenience method to test whether the latest version of stateful entities is required.- Returns:
- True if there is an override wanting the latest version set on the API, false if not.
-