/* ====================================================================
* Limited Evaluation License:
*
* This software is open source, but licensed. The license with this package
* is an evaluation license, which may not be used for productive systems. If
* you want a full license, please contact us.
*
* The exclusive owner of this work is the OpenRate project.
* This work, including all associated documents and components
* is Copyright of the OpenRate project 2006-2015.
*
* The following restrictions apply unless they are expressly relaxed in a
* contractual agreement between the license holder or one of its officially
* assigned agents and you or your organisation:
*
* 1) This work may not be disclosed, either in full or in part, in any form
* electronic or physical, to any third party. This includes both in the
* form of source code and compiled modules.
* 2) This work contains trade secrets in the form of architecture, algorithms
* methods and technologies. These trade secrets may not be disclosed to
* third parties in any form, either directly or in summary or paraphrased
* form, nor may these trade secrets be used to construct products of a
* similar or competing nature either by you or third parties.
* 3) This work may not be included in full or in part in any application.
* 4) You may not remove or alter any proprietary legends or notices contained
* in or on this work.
* 5) This software may not be reverse-engineered or otherwise decompiled, if
* you received this work in a compiled form.
* 6) This work is licensed, not sold. Possession of this software does not
* imply or grant any right to you.
* 7) You agree to disclose any changes to this work to the copyright holder
* and that the copyright holder may include any such changes at its own
* discretion into the work
* 8) You agree not to derive other works from the trade secrets in this work,
* and that any such derivation may make you liable to pay damages to the
* copyright holder
* 9) You agree to use this software exclusively for evaluation purposes, and
* that you shall not use this software to derive commercial profit or
* support your business or personal activities.
*
* This software is provided "as is" and any expressed or impled warranties,
* including, but not limited to, the impled warranties of merchantability
* and fitness for a particular purpose are disclaimed. In no event shall
* The OpenRate Project or its officially assigned agents be liable to any
* direct, indirect, incidental, special, exemplary, or consequential damages
* (including but not limited to, procurement of substitute goods or services;
* Loss of use, data, or profits; or any business interruption) however caused
* and on theory of liability, whether in contract, strict liability, or tort
* (including negligence or otherwise) arising in any way out of the use of
* this software, even if advised of the possibility of such damage.
* This software contains portions by The Apache Software Foundation, Robert
* Half International.
* ====================================================================
*/
package OpenRate.resource;
import OpenRate.OpenRate;
import OpenRate.cache.*;
import OpenRate.configurationmanager.ClientManager;
import OpenRate.configurationmanager.IEventInterface;
import OpenRate.exception.InitializationException;
import OpenRate.exception.ProcessingException;
import OpenRate.logging.LogUtil;
import OpenRate.transaction.ISyncPoint;
import OpenRate.utils.ConversionUtils;
import OpenRate.utils.PropertyUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
/**
* CacheFactory class manages caching creation/retrieval of specific cache
* manager. This class uses simple HashMap to store cacheable objects.
*
* Each of the cacheable objects created is stored inside a SimpleCacheManager
* object which is really a minimal wrapper around a hash.
*
* The factory then indexes the manager that is responsible for a given class name,
* thus each factory can be responsible for multiple managers. Managers are loaded
* automatically on start up of the factory, using the property prefix "CacheableClass."
*
* It is a resource class hence has it will be registered into the
* the ResourceContext and in the init method it initializes all the
* CacheManagers and its respective caches.
*
* The CacheManager also manages the propagation of sync point requests to and
* from the managed caches.
*/
public class CacheFactory
implements IResource,
ICacheFactory,
IEventInterface,
ISyncPoint
{
// The symbolic module name of the class stack
private String symbolicName;
// Managers is the list of the caches that we are managing in this factory
private HashMap<String, CacheManager> managers;
// This holds all of the caches that can call for a sync point
private HashMap<String, ISyncPoint> eventCaches;
// List of Services that this Client supports
private final static String SERVICE_RELOAD = "Reload";
private final static String SERVICE_AUTO_RELOAD = "AutoReload";
private final static String SERVICE_NEXT_RELOAD = "NextReloadIn";
// This is how many seconds between reloads, 0 = no auto reload
private long autoReloadPeriod = 0;
// the last time we did a reload
private long lastReloadUTC = 0;
// controls whether resources are loaded sequentially or in parallel
private boolean sequentialLoading;
// used to simplify logging and exception handling
public String message;
/**
* The Key used to get the CacheFactory from the
* configuration settings.
*/
public static final String RESOURCE_KEY = "CacheFactory";
// the list of cacheable classes
private ArrayList<String> cacheableClassList;
/**
* Constructor
*/
public CacheFactory()
{
}
/**
* This init method will be called while Resources are being registered and
* initialised. It obtains all the cacheable objects calls the loading
* methods before adding into the CacheManagers.
*
* @param resourceName The resource name
* @throws InitializationException
*/
@Override
public void init(String resourceName) throws InitializationException
{
IEventInterface tmpEventIntf;
ISyncPoint tmpSyncIntf;
CacheManager cacheManager;
ICacheable cacheableObject;
Class<?> cacheableClass;
String tmpCacheableClassName;
String tmpCacheableClass;
long loadStartTime;
long loadEndTime;
Iterator<String> cacheableClassIter;
String configHelper;
// Start timer for loading
loadStartTime = ConversionUtils.getConversionUtilsObject().getCurrentUTCms();
OpenRate.getOpenRateFrameworkLog().info("Starting CacheFactory initialisation");
symbolicName = resourceName;
if (!symbolicName.equalsIgnoreCase(RESOURCE_KEY))
{
// we are relying on this name to be able to find the resource
// later, so stop if it is not right
message = "Cache Factory ModuleName should be <" + RESOURCE_KEY + ">";
throw new InitializationException(message,getSymbolicName());
}
managers = new HashMap<>(50);
eventCaches = new HashMap<>(50);
// Get the list of cacheable classes
cacheableClassList = PropertyUtils.getPropertyUtils().getGenericNameList("Resource.CacheFactory.CacheableClass");
// Get the loading strategy
sequentialLoading = PropertyUtils.getPropertyUtils().getResourcePropertyValueDef(RESOURCE_KEY, "SequentialLoading", "true").equalsIgnoreCase("true");
// and the iterator we will be using to cycle through them
cacheableClassIter = cacheableClassList.iterator();
// Create a thread group for holding the cache objects while they are
// being created
ThreadGroup tmpGrpCaches = new ThreadGroup("Caches");
// Iterate for the loading
while (cacheableClassIter.hasNext())
{
tmpCacheableClassName = cacheableClassIter.next();
try
{
tmpCacheableClass = PropertyUtils.getPropertyUtils().getDataCachePropertyValueDef(resourceName,
tmpCacheableClassName,
"ClassName",
"None");
// This is where we will launch the resources as separate classes if
// necessary
if (tmpCacheableClassName.equalsIgnoreCase("None") ||
(tmpCacheableClass.equalsIgnoreCase("None")))
{
message = "Configuration for <" + tmpCacheableClassName + ">:<" + tmpCacheableClass + "> not complete.";
throw new InitializationException(message,getSymbolicName());
}
else
{
OpenRate.getOpenRateFrameworkLog().info("Loading Cacheable Class <" + tmpCacheableClassName + ">...");
System.out.println(" Loading Cacheable Class <" + tmpCacheableClassName + ">...");
//Add the CacheManager to the manager list.
cacheManager = new CacheManager();
managers.put(tmpCacheableClassName, cacheManager);
// Instantiate the object
cacheableClass = Class.forName(tmpCacheableClass);
cacheableObject = (ICacheable) cacheableClass.newInstance();
cacheManager.put(tmpCacheableClassName, cacheableObject);
/*
* Check if the cacheable instance is implementing
* CacheLoader, if yes, then call its loadCache() method
* to load all its data into cache i.e. by adding cache in
* cache manager that is passed as argument. Otherwise
* the cacheable object is understood to be lazy-loaded.
*/
if (cacheableObject instanceof ICacheLoader)
{
if (sequentialLoading)
{
((ICacheLoader)cacheableObject).loadCache(resourceName, tmpCacheableClassName);
OpenRate.getOpenRateFrameworkLog().info("Loaded Cacheable Class <" + tmpCacheableClassName + ">...");
System.out.println(" Loaded Cacheable Class <" + tmpCacheableClassName + ">...");
}
else
{
// Create a loader thread
CacheLoaderThread cacheLoaderThread = new CacheLoaderThread(tmpGrpCaches,tmpCacheableClassName);
// Set up the thread for loading
cacheLoaderThread.setCacheObject(cacheableObject);
cacheLoaderThread.setCacheName(tmpCacheableClassName);
cacheLoaderThread.setResourceName(resourceName);
cacheLoaderThread.setLoadStartTime(ConversionUtils.getConversionUtilsObject().getCurrentUTCms());
// Launch the thread
cacheLoaderThread.start();
}
}
}
}
catch (ClassNotFoundException ex)
{
message = "ClassNotFoundException creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (InstantiationException ex)
{
message = "InstantiationException creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">. Perhaps you are trying to use an abstract class.";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (IllegalAccessException ex)
{
message = "IllegalAccessException creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (NullPointerException ex)
{
message = "NullPointerException creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (ClassCastException ex)
{
message = "Class Cast Exception creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (NumberFormatException ex)
{
message = "Number Format Exception creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (InitializationException ie)
{
OpenRate.getFrameworkExceptionHandler().reportException(ie);
}
catch (OutOfMemoryError ex)
{
message = "Out of memory creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,getSymbolicName(),true,true,ex));
}
catch (ArrayIndexOutOfBoundsException ex)
{
message = "Out of memory creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (Exception ex)
{
message = "Unexpected Exception in <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (Throwable ex)
{
message = "Unexpected Exception in <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,getSymbolicName(),true,true,ex));
}
// Set the auto reload parameter
configHelper = PropertyUtils.getPropertyUtils().getResourcePropertyValueDef(resourceName,SERVICE_AUTO_RELOAD,"None");
if (configHelper.equals("None") == false)
{
try
{
autoReloadPeriod = Integer.parseInt(configHelper);
// Set the date so that we don't reload right away
lastReloadUTC = ConversionUtils.getConversionUtilsObject().getCurrentUTC();
}
catch (NumberFormatException ex)
{
message = "Parameter " + SERVICE_AUTO_RELOAD + " expects a numeric value, but the configured value <" + configHelper + "> is not numeric.";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
}
// Check for exceptions
if (OpenRate.getFrameworkExceptionHandler().hasError())
{
throw new InitializationException("Startup failed. Aborting.",getSymbolicName());
}
}
// Join the loading threads we launched
while (tmpGrpCaches.activeCount() > 0)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException ex)
{
// Nothing
}
// Check for errors
if (OpenRate.getFrameworkExceptionHandler().hasError())
{
// no point in carrying on
return;
}
}
// destroy the thread group
tmpGrpCaches.destroy();
// reset the iterator
cacheableClassIter = cacheableClassList.iterator();
// Iterate for the other set ups
while (cacheableClassIter.hasNext())
{
tmpCacheableClassName = cacheableClassIter.next();
try
{
// Instantiate the object
CacheManager manager = managers.get(tmpCacheableClassName);
cacheableObject = manager.get(tmpCacheableClassName);
/*
* Reloadable cache
*
* check if its a cache that can be reloadable, and if is then get the value of
* property and store it in this cache object to be used,
* later in the pipeline, the autorelaodPeriod is known for this specific cache
*/
if (cacheableObject instanceof ICacheAutoReloadable)
{
String autoLoadPeriod = PropertyUtils.getPropertyUtils().getDataCachePropertyValueDef(resourceName,
tmpCacheableClassName,
SERVICE_AUTO_RELOAD,
"0");
try
{
((ICacheAutoReloadable)cacheableObject).setAutoReloadPeriod(Long.parseLong(autoLoadPeriod));
}
catch (NumberFormatException nfe)
{
message = "Expected a numeric value for <" + SERVICE_AUTO_RELOAD +
">, in cache <" + getSymbolicName() + "> but got <" +
autoLoadPeriod + ">";
throw new InitializationException(message,getSymbolicName());
}
// Log the fact that we are reloading this cache
OpenRate.getOpenRateFrameworkLog().info("Cache <" + tmpCacheableClassName + "> is set to auto reload with a period of <" + autoLoadPeriod +">");
}
// Now see if we have to register with the config manager
if (cacheableObject instanceof IEventInterface)
{
// Register to accept events
tmpEventIntf = (IEventInterface)cacheableObject;
tmpEventIntf.registerClientManager();
// If this class wanta to manage sync points, register that as well
if (cacheableObject instanceof ISyncPoint)
{
// Store the reference to the SyncPoint interface
tmpSyncIntf = (ISyncPoint)cacheableObject;
eventCaches.put(tmpCacheableClassName,tmpSyncIntf);
}
}
// Log the creation of the cacheable class
OpenRate.getOpenRateFrameworkLog().info("Created Cacheable Class <" + tmpCacheableClassName + ">");
}
catch (NullPointerException ex)
{
message = "NullPointerException creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (ClassCastException ex)
{
message = "Class Cast Exception creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (NumberFormatException ex)
{
message = "Number Format Exception creating <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
catch (InitializationException ie)
{
OpenRate.getFrameworkExceptionHandler().reportException(ie);
}
catch (Exception ex)
{
message = "Unexpected Exception in <" + tmpCacheableClassName + ">. Message = <" + ex.getMessage() + ">";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
// Set the auto reload parameter
configHelper = PropertyUtils.getPropertyUtils().getResourcePropertyValueDef(resourceName,SERVICE_AUTO_RELOAD,"None");
if (configHelper.equals("None") == false)
{
try
{
autoReloadPeriod = Integer.parseInt(configHelper);
// Set the date so that we don't reload right away
lastReloadUTC = ConversionUtils.getConversionUtilsObject().getCurrentUTC();
}
catch (NumberFormatException ex)
{
message = "Parameter " + SERVICE_AUTO_RELOAD + " expects a numeric value, but the configured value <" + configHelper + "> is not numeric.";
OpenRate.getFrameworkExceptionHandler().reportException(new InitializationException(message,ex,getSymbolicName()));
}
}
}
loadEndTime = ConversionUtils.getConversionUtilsObject().getCurrentUTCms();
OpenRate.getOpenRateFrameworkLog().info("CacheFactory initialised in " + (loadEndTime-loadStartTime) + "ms.");
}
/**
* Retrieves the CacheManager that is specific to the className object.
*
* @param className The name of the class we are managing
* @return The manager
*/
@Override
public ICacheManager getManager(String className)
{
return managers.get(className);
}
/**
* As part of Resource object it cleans up the CacheManagers
* which in turn will make cached data garbage collected.
*/
@Override
public void close()
{
CacheManager cacheableObjectManager;
Object cacheableObject;
Collection<String> CacheObjects;
Iterator<String> CacheObjIterator;
String tmpCacheableClassName;
// Iterate through the managers to find those that have the ICacheSaver
// interface
CacheObjects = managers.keySet();
CacheObjIterator = CacheObjects.iterator();
while (CacheObjIterator.hasNext())
{
tmpCacheableClassName = CacheObjIterator.next();
cacheableObjectManager = managers.get(tmpCacheableClassName);
cacheableObject = cacheableObjectManager.get(tmpCacheableClassName);
if (cacheableObject instanceof ICacheSaver)
{
System.out.println(
" Destroying Cacheable Class <" + tmpCacheableClassName +
">...");
try {
((ICacheSaver)cacheableObject).saveCache();
}
catch (ProcessingException ex) {
OpenRate.getFrameworkExceptionHandler().reportException(ex);
}
OpenRate.getOpenRateFrameworkLog().info("Saved Cacheable Class <" + tmpCacheableClassName + ">...");
System.out.println(
" Unloaded Cacheable Class <" + tmpCacheableClassName +
">...");
}
}
managers.clear();
}
/**
* Get the cache manager for the given class name.
*
* @param className The class name to get the manager for
* @return The manager for the class
* @throws InitializationException
*/
public static ICacheManager getGlobalManager(String className) throws InitializationException
{
ICacheManager CM = null;
ResourceContext ctx = new ResourceContext();
// try the new Logging model.
ICacheFactory factory = (ICacheFactory)ctx.get(RESOURCE_KEY);
if (factory == null)
{
// no factory registered, fall back to the old model
LogUtil.getStaticLogger("Framework").fatal("No Cache Factory loaded");
}
else
{
CM = factory.getManager(className);
}
return CM;
}
// -----------------------------------------------------------------------------
// ---------------- Start of inherited ISyncPoint functions --------------------
// -----------------------------------------------------------------------------
/**
* Pass through method for managing sync points for the data caches that the
* cache manager is handling. To calculate the value to return, we do the
* following:
* 1) if any of the caches requests a sync point, we return the sync request
* immediately (=SyncFlag)
* 2) We return 3 (=SyncReached) when all managed modules are at 3
* 3) Likewise 5 (=SyncDone)
*
* @return The current sync status
*/
@Override
public int getSyncStatus()
{
Iterator<String> SyncListIter;
ISyncPoint tmpSyncIntf;
int tmpReturnCode;
int tmpMaxCode = 0;
boolean SyncReached = true;
boolean SyncFinished = true;
SyncListIter = eventCaches.keySet().iterator();
while (SyncListIter.hasNext())
{
tmpSyncIntf = eventCaches.get(SyncListIter.next());
tmpReturnCode = tmpSyncIntf.getSyncStatus();
// calculate the max code (which will be returned if neither the
// SyncReached nor the SyncFinished is set
if (tmpReturnCode > tmpMaxCode)
{
tmpMaxCode = tmpReturnCode;
}
SyncReached &= (tmpReturnCode == 3);
SyncFinished &= (tmpReturnCode == 5);
}
if (SyncFinished)
{
return 5;
}
else if (SyncReached)
{
return 3;
}
else
{
return tmpMaxCode;
}
}
/**
* Pass through method for managing sync points for the data caches that the
* cache manager is handling. Pass the received value to all managed data
* cache objects
*
* @param newStatus The new sync status to set
*/
@Override
public void setSyncStatus(int newStatus)
{
Iterator<String> SyncListIter;
ISyncPoint tmpSyncIntf;
SyncListIter = eventCaches.keySet().iterator();
while (SyncListIter.hasNext())
{
tmpSyncIntf = eventCaches.get(SyncListIter.next());
tmpSyncIntf.setSyncStatus(newStatus);
}
}
/**
* Pass through method for managing sync points for the data caches that the
* cache manager is handling. Pass the received value to all managed data
* cache objects
*
* @param newStatus The new sync status to set
* @param cacheName The name of the cache to set for
*/
public void setSyncStatus(int newStatus, String cacheName)
{
ISyncPoint tmpSyncIntf;
tmpSyncIntf = eventCaches.get(cacheName);
tmpSyncIntf.setSyncStatus(newStatus);
}
// -----------------------------------------------------------------------------
// ------------- Start of inherited IEventInterface functions ------------------
// -----------------------------------------------------------------------------
/**
* registerClientManager registers the client module to the ClientManager class
* which manages all the client modules available in this OpenRate Application.
*
* registerClientManager registers this class as a client of the ECI listener
* and publishes the commands that the plug in understands. The listener is
* responsible for delivering only these commands to the plug in.
*
* @throws OpenRate.exception.InitializationException
*/
@Override
public void registerClientManager() throws InitializationException
{
//Register this Client
ClientManager.getClientManager().registerClient("Resource",getSymbolicName(), this);
//Register services for this Client
ClientManager.getClientManager().registerClientService(getSymbolicName(), SERVICE_RELOAD, ClientManager.PARAM_DYNAMIC_SYNC);
ClientManager.getClientManager().registerClientService(getSymbolicName(), SERVICE_AUTO_RELOAD, ClientManager.PARAM_DYNAMIC);
ClientManager.getClientManager().registerClientService(getSymbolicName(), SERVICE_NEXT_RELOAD, ClientManager.PARAM_DYNAMIC);
}
/**
* processControlEvent is the method that will be called when an event
* is received for a module that has registered itself as a client of the
* External Control Interface
*
* @param Command - command that is understand by the client module
* @param Init - we are performing initial configuration if true
* @param Parameter - parameter for the command
* @return The result string of the operation
*/
@Override
public String processControlEvent(String Command, boolean Init,
String Parameter)
{
int ResultCode = -1;
// Trigger a sync point
if (Command.equalsIgnoreCase(SERVICE_RELOAD))
{
if (Parameter.equalsIgnoreCase("true"))
{
// Instruct all the caches to reload
setSyncStatus(ISyncPoint.SYNC_STATUS_SYNC_FLAGGED);
// tell the user
return "Event buffered";
}
else if (Parameter.equalsIgnoreCase("false"))
{
// Don't reload
ResultCode = 0;
}
else if (Parameter.equalsIgnoreCase(""))
{
// return the current state
if (getSyncStatus() == ISyncPoint.SYNC_STATUS_NORMAL_RUN)
{
return "false";
}
else
{
return "true";
}
}
}
// Get/Set the auto reload period
if (Command.equalsIgnoreCase(SERVICE_AUTO_RELOAD))
{
if (Parameter.equalsIgnoreCase(""))
{
// return the configured value
return Long.toString(autoReloadPeriod);
}
else
{
// try to set the new value
try
{
autoReloadPeriod = Long.valueOf(Parameter);
ResultCode = 0;
}
catch (Exception e)
{
return "Could not interpret <" + autoReloadPeriod + "> as an integer value";
}
}
}
// Get the number of seconds to the next reload
if (Command.equalsIgnoreCase(SERVICE_NEXT_RELOAD))
{
// see if something is configured
if (autoReloadPeriod == 0)
{
// Just return the value
return Long.toString(autoReloadPeriod);
}
else
{
// calculate the number of seconds until the reload
return Long.toString(lastReloadUTC + autoReloadPeriod - ConversionUtils.getConversionUtilsObject().getCurrentUTC());
}
}
if (ResultCode == 0)
{
OpenRate.getOpenRateFrameworkLog().debug(LogUtil.LogECICacheCommand(getSymbolicName(), Command, Parameter));
return "OK";
}
else
{
return "Command Not Understood";
}
}
/**
* Return the symbolic name of the class
*
* @return The symbolic name of the module
*/
@Override
public String getSymbolicName()
{
return symbolicName;
}
/**
* Manages the auto reload function. This means that we will periodically
* reload the caches without user intervention.
*
* Each cache can be configured independently for the load frequency.
*/
public void updateAutoReload()
{
long currentTimeUTC;
Iterator<String> CacheableClassIter = cacheableClassList.iterator();
String tmpCacheableClassName;
// talk to each of the caches in turn
while (CacheableClassIter.hasNext())
{
// get the reference to the cache
tmpCacheableClassName = CacheableClassIter.next();
Object tmpCacheableClass = getManager(tmpCacheableClassName).get(tmpCacheableClassName);
if (tmpCacheableClass instanceof ICacheAutoReloadable)
{
// get the reload period - this comes from the class itself, or from
// the factory if no period is set for the class
ICacheAutoReloadable cacheableObject = (ICacheAutoReloadable)tmpCacheableClass;
long autoLoadPeriod = cacheableObject.getAutoReloadPeriod();
// set the auto reload period in the class if none was set there
// and one was set on the factory
if(autoLoadPeriod == 0 && this.autoReloadPeriod > 0)
{
cacheableObject.setAutoReloadPeriod( this.autoReloadPeriod);
autoLoadPeriod = this.autoReloadPeriod;
}
if(autoLoadPeriod > 0)
{
// get the current utc date time that we will be working with
currentTimeUTC = ConversionUtils.getConversionUtilsObject().getCurrentUTC();
//If pipeline just started, update the last reload to NOW because the pipeline already loaded all the cache
//once, so we don't want to do it again
if(cacheableObject.getLastReloadUTC()==0) {cacheableObject.setLastReloadUTC(currentTimeUTC);}
// if we have passed the time of the last auto reload
if ((cacheableObject.getLastReloadUTC() + cacheableObject.getAutoReloadPeriod()) < currentTimeUTC)
{
cacheableObject.setLastReloadUTC(currentTimeUTC);
// Instruct specific cache to reload
setSyncStatus(ISyncPoint.SYNC_STATUS_SYNC_FLAGGED,tmpCacheableClassName);
}
}
}
}
}
}