From a1f0ecbb6a2bea6aa214322c412af2f3c5ce124b Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Wed, 7 May 2014 17:33:13 +0200 Subject: Agent now extends Item, so they can have workflows. All traces of the old 'Entity' superclasses should be removed, including proxies and paths. Very large change, breaks API compatibility with CRISTAL 2.x. Fixes #135 --- .../com/c2kernel/entity/ItemImplementation.java | 281 +++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 src/main/java/com/c2kernel/entity/ItemImplementation.java (limited to 'src/main/java/com/c2kernel/entity/ItemImplementation.java') diff --git a/src/main/java/com/c2kernel/entity/ItemImplementation.java b/src/main/java/com/c2kernel/entity/ItemImplementation.java new file mode 100644 index 0000000..e0d107a --- /dev/null +++ b/src/main/java/com/c2kernel/entity/ItemImplementation.java @@ -0,0 +1,281 @@ +package com.c2kernel.entity; + +import com.c2kernel.collection.Collection; +import com.c2kernel.collection.CollectionArrayList; +import com.c2kernel.common.AccessRightsException; +import com.c2kernel.common.InvalidDataException; +import com.c2kernel.common.InvalidTransitionException; +import com.c2kernel.common.ObjectAlreadyExistsException; +import com.c2kernel.common.ObjectNotFoundException; +import com.c2kernel.common.PersistencyException; +import com.c2kernel.entity.agent.JobArrayList; +import com.c2kernel.lifecycle.instance.CompositeActivity; +import com.c2kernel.lifecycle.instance.Workflow; +import com.c2kernel.lookup.AgentPath; +import com.c2kernel.lookup.InvalidItemPathException; +import com.c2kernel.persistency.ClusterStorage; +import com.c2kernel.persistency.ClusterStorageException; +import com.c2kernel.persistency.TransactionManager; +import com.c2kernel.process.Gateway; +import com.c2kernel.property.Property; +import com.c2kernel.property.PropertyArrayList; +import com.c2kernel.utils.Logger; + +public class ItemImplementation implements ItemOperations { + + protected final TransactionManager mStorage; + protected final int mSystemKey; + + protected ItemImplementation(int systemKey) { + this.mStorage = Gateway.getStorage(); + this.mSystemKey = systemKey; + } + + @Override + public int getSystemKey() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public void initialise(int agentId, String propString, String initWfString, + String initCollsString) throws AccessRightsException, + InvalidDataException, PersistencyException + { + Logger.msg(5, "Item::initialise("+mSystemKey+") - agent:"+agentId); + Object locker = new Object(); + + AgentPath agentPath; + try { + agentPath = new AgentPath(agentId); + } catch (InvalidItemPathException e) { + throw new AccessRightsException("Invalid Agent Id:" + agentId); + } + + // must supply properties + if (propString == null || propString.length() == 0) { + throw new InvalidDataException("No properties supplied", ""); + } + + // store properties + try { + PropertyArrayList props = (PropertyArrayList) Gateway + .getMarshaller().unmarshall(propString); + for (Property thisProp : props.list) + mStorage.put(mSystemKey, thisProp, locker); + } catch (Throwable ex) { + Logger.msg(8, "TraceableEntity::initialise(" + mSystemKey + + ") - Properties were invalid: " + propString); + Logger.error(ex); + mStorage.abort(locker); + throw new InvalidDataException("Properties were invalid", ""); + } + + // create wf + try { + Workflow lc = null; + if (initWfString == null || initWfString.length() == 0) + lc = new Workflow(new CompositeActivity()); + else + lc = new Workflow((CompositeActivity) Gateway + .getMarshaller().unmarshall(initWfString)); + lc.initialise(mSystemKey, agentPath); + mStorage.put(mSystemKey, lc, locker); + } catch (Throwable ex) { + Logger.msg(8, "TraceableEntity::initialise(" + mSystemKey + + ") - Workflow was invalid: " + initWfString); + Logger.error(ex); + mStorage.abort(locker); + throw new InvalidDataException("Workflow was invalid", ""); + } + + // init collections + if (initCollsString != null && initCollsString.length() > 0) { + try { + CollectionArrayList colls = (CollectionArrayList) Gateway + .getMarshaller().unmarshall(initCollsString); + for (Collection thisColl : colls.list) { + mStorage.put(mSystemKey, thisColl, locker); + } + } catch (Throwable ex) { + Logger.msg(8, "TraceableEntity::initialise(" + mSystemKey + + ") - Collections were invalid: " + + initCollsString); + Logger.error(ex); + mStorage.abort(locker); + throw new InvalidDataException("Collections were invalid"); + } + } + mStorage.commit(locker); + Logger.msg(3, "Initialisation of item " + mSystemKey + + " was successful"); + } + + + @Override + public void requestAction(int agentId, String stepPath, int transitionID, + String requestData) throws AccessRightsException, + InvalidTransitionException, ObjectNotFoundException, + InvalidDataException, PersistencyException, + ObjectAlreadyExistsException { + + try { + + Logger.msg(1, "TraceableEntity::request(" + mSystemKey + ") - " + + transitionID + " " + stepPath + " by " + agentId); + + AgentPath agent = new AgentPath(agentId); + Workflow lifeCycle = (Workflow) mStorage.get(mSystemKey, + ClusterStorage.LIFECYCLE + "/workflow", null); + + lifeCycle.requestAction(agent, stepPath, mSystemKey, + transitionID, requestData); + + // store the workflow if we've changed the state of the domain + // wf + if (!(stepPath.startsWith("workflow/predefined"))) + mStorage.put(mSystemKey, lifeCycle, null); + + // Normal operation exceptions + } catch (AccessRightsException ex) { + Logger.msg("Propagating AccessRightsException back to the calling agent"); + throw ex; + } catch (InvalidTransitionException ex) { + Logger.msg("Propagating InvalidTransitionException back to the calling agent"); + throw ex; + } catch (ObjectNotFoundException ex) { + Logger.msg("Propagating ObjectNotFoundException back to the calling agent"); + throw ex; + // errors + } catch (ClusterStorageException ex) { + Logger.error(ex); + throw new PersistencyException("Error on storage: " + + ex.getMessage(), ""); + } catch (InvalidItemPathException ex) { + Logger.error(ex); + throw new AccessRightsException("Invalid Agent Id: " + agentId, + ""); + } catch (InvalidDataException ex) { + Logger.error(ex); + Logger.msg("Propagating InvalidDataException back to the calling agent"); + throw ex; + } catch (ObjectAlreadyExistsException ex) { + Logger.error(ex); + Logger.msg("Propagating ObjectAlreadyExistsException back to the calling agent"); + throw ex; + // non-CORBA exception hasn't been caught! + } catch (Throwable ex) { + Logger.error("Unknown Error: requestAction on " + mSystemKey + + " by " + agentId + " executing " + stepPath); + Logger.error(ex); + throw new InvalidDataException( + "Extraordinary Exception during execution:" + + ex.getClass().getName() + " - " + + ex.getMessage(), ""); + } + } + + @Override + public String queryLifeCycle(int agentId, boolean filter) + throws AccessRightsException, ObjectNotFoundException, + PersistencyException { + Logger.msg(1, "TraceableEntity::queryLifeCycle(" + mSystemKey + + ") - agent: " + agentId); + try { + AgentPath agent; + try { + agent = new AgentPath(agentId); + } catch (InvalidItemPathException e) { + throw new AccessRightsException("Agent " + agentId + + " doesn't exist"); + } + Workflow wf; + try { + wf = (Workflow) mStorage.get(mSystemKey, + ClusterStorage.LIFECYCLE + "/workflow", null); + } catch (ClusterStorageException e) { + Logger.error("TraceableEntity::queryLifeCycle(" + + mSystemKey + ") - Error loading workflow"); + Logger.error(e); + throw new PersistencyException("Error loading workflow"); + } + JobArrayList jobBag = new JobArrayList(); + CompositeActivity domainWf = (CompositeActivity) wf + .search("workflow/domain"); + jobBag.list = filter ? domainWf.calculateJobs(agent, + mSystemKey, true) : domainWf.calculateAllJobs(agent, + mSystemKey, true); + Logger.msg(1, "TraceableEntity::queryLifeCycle(" + mSystemKey + + ") - Returning " + jobBag.list.size() + " jobs."); + try { + return Gateway.getMarshaller().marshall(jobBag); + } catch (Exception e) { + Logger.error(e); + throw new PersistencyException("Error marshalling job bag"); + } + } catch (Throwable ex) { + Logger.error("TraceableEntity::queryLifeCycle(" + mSystemKey + + ") - Unknown error"); + Logger.error(ex); + throw new PersistencyException( + "Unknown error querying jobs. Please see server log."); + } + } + + @Override + public String queryData(String path) throws AccessRightsException, + ObjectNotFoundException, PersistencyException { + + String result = ""; + + Logger.msg(1, "TraceableEntity::queryData(" + mSystemKey + ") - " + + path); + + try { // check for cluster contents query + + if (path.endsWith("/all")) { + int allPos = path.lastIndexOf("all"); + String query = path.substring(0, allPos); + String[] ids = mStorage.getClusterContents(mSystemKey, + query); + + for (int i = 0; i < ids.length; i++) { + result += ids[i]; + + if (i != ids.length - 1) + result += ","; + } + } + // **************************************************************** + else { // retrieve the object instead + C2KLocalObject obj = mStorage.get(mSystemKey, path, null); + + // marshall it, or in the case of an outcome get the data. + result = Gateway.getMarshaller().marshall(obj); + } + } catch (ObjectNotFoundException ex) { + throw ex; + } catch (Throwable ex) { + Logger.warning("TraceableEntity::queryData(" + mSystemKey + + ") - " + path + " Failed: " + ex.getClass().getName()); + throw new PersistencyException("Server exception: " + + ex.getClass().getName(), ""); + } + + if (Logger.doLog(9)) + Logger.msg(9, "TraceableEntity::queryData(" + mSystemKey + + ") - result:" + result); + + return result; + } + + /** + * + */ + @Override + protected void finalize() throws Throwable { + Logger.msg(7, "Item "+mSystemKey+" reaped"); + Gateway.getStorage().clearCache(mSystemKey, null); + super.finalize(); + } +} -- cgit v1.2.3