diff options
Diffstat (limited to 'src/main')
12 files changed, 169 insertions, 55 deletions
diff --git a/src/main/java/com/c2kernel/entity/agent/Job.java b/src/main/java/com/c2kernel/entity/agent/Job.java index b5274ec..216a88d 100644 --- a/src/main/java/com/c2kernel/entity/agent/Job.java +++ b/src/main/java/com/c2kernel/entity/agent/Job.java @@ -11,6 +11,7 @@ import com.c2kernel.persistency.ClusterStorage; import com.c2kernel.persistency.outcome.Outcome;
import com.c2kernel.persistency.outcome.Viewpoint;
import com.c2kernel.process.Gateway;
+import com.c2kernel.scripting.ErrorInfo;
import com.c2kernel.utils.CastorHashMap;
import com.c2kernel.utils.KeyValuePair;
import com.c2kernel.utils.Logger;
@@ -46,12 +47,16 @@ public class Job implements C2KLocalObject private CastorHashMap mActProps = new CastorHashMap();
private String mOutcome;
+
+ private ErrorInfo mError;
private String mStepType;
private ItemProxy item = null;
private AgentProxy agent = null;
+
+ private boolean outcomeSet;
/***************************************************************************
* Empty constructor for Castor
@@ -105,29 +110,43 @@ public class Job implements C2KLocalObject public String getSchemaType()
{
- return (String) mActProps.get("SchemaType");
+ if (isError()) return "Errors";
+ if (requiresOutcome()) return (String)mActProps.get("SchemaType");
+ else return null;
}
public int getSchemaVersion()
{
- try
- {
- return Integer.parseInt((String) mActProps.get("SchemaVersion"));
- } catch (NumberFormatException ex)
- {
- return -1;
- }
+ if (isError()) return 0;
+ if (requiresOutcome())
+ try {
+ return Integer.parseInt((String) mActProps.get("SchemaVersion"));
+ } catch (NumberFormatException ex) {
+ return -1;
+ }
+ return -1;
}
public void setOutcome(String outcome)
{
- mOutcome = outcome;
+ mOutcome = outcome;
+ outcomeSet = !(mOutcome == null);
+ }
+
+ public void setError(ErrorInfo errors)
+ {
+ mError = errors;
+ try {
+ mOutcome = Gateway.getMarshaller().marshall(errors);
+ } catch (Exception e) {
+ Logger.error("Error marshalling ErrorInfo in job");
+ Logger.error(e);
+ }
}
public String getOutcomeString()
{
- Logger.debug(8, "getOutcomeString() " + (mOutcome == null && isOutcomeUsed()));
- if (mOutcome == null && isOutcomeUsed())
+ if (mOutcome == null && requiresOutcome())
{
String viewName = (String) getActProp("Viewpoint");
mOutcome = null;
@@ -136,16 +155,19 @@ public class Job implements C2KLocalObject {
Viewpoint view = (Viewpoint) Gateway.getStorage().get(getItemSysKey(), ClusterStorage.VIEWPOINT + "/" + getSchemaType() + "/" + viewName, null);
mOutcome = view.getOutcome().getData();
+ outcomeSet = true;
} catch (Exception ex)
- { // not found, return null
+ {
+ mOutcome = null;
+ outcomeSet = false;
}
+
}
return mOutcome;
}
public Outcome getOutcome()
{
- Logger.msg(1, "Get outcome");
return new Outcome(-1, getOutcomeString(), getSchemaType(), getSchemaVersion());
}
@@ -186,10 +208,22 @@ public class Job implements C2KLocalObject mAgentRole = role;
}
- public boolean isOutcomeUsed()
+ public boolean requiresOutcome()
{
- String schemaType = getSchemaType();
- return (Boolean.TRUE.equals(getActProp("AlwaysUseOutcome")) || mPossibleTransition == Transitions.DONE || mPossibleTransition == Transitions.COMPLETE) && !(schemaType == null || schemaType.equals(""));
+ String schemaType = (String) mActProps.get("SchemaVersion");
+ return (mPossibleTransition == Transitions.DONE || mPossibleTransition == Transitions.COMPLETE) && !(schemaType == null || schemaType.equals(""));
+ }
+
+ public boolean isError() {
+ return (mPossibleTransition == Transitions.SUSPEND);
+ }
+
+ public boolean hasOutcome() {
+ return requiresOutcome() || isError();
+ }
+
+ public boolean isOutcomeSet() {
+ return outcomeSet;
}
public int getID()
diff --git a/src/main/java/com/c2kernel/entity/proxy/AgentProxy.java b/src/main/java/com/c2kernel/entity/proxy/AgentProxy.java index 5c6a37e..286be88 100644 --- a/src/main/java/com/c2kernel/entity/proxy/AgentProxy.java +++ b/src/main/java/com/c2kernel/entity/proxy/AgentProxy.java @@ -36,6 +36,7 @@ import com.c2kernel.persistency.outcome.Schema; import com.c2kernel.process.Gateway;
import com.c2kernel.scripting.ErrorInfo;
import com.c2kernel.scripting.Script;
+import com.c2kernel.scripting.ScriptErrorException;
import com.c2kernel.scripting.ScriptingEngineException;
import com.c2kernel.utils.LocalObjectLoader;
import com.c2kernel.utils.Logger;
@@ -98,6 +99,7 @@ public class AgentProxy extends EntityProxy *
* @param item - item holding this job
* @param job - the job to execute
+ * @throws ScriptErrorException
*/
public void execute(ItemProxy item, Job job)
throws AccessRightsException,
@@ -105,24 +107,19 @@ public class AgentProxy extends EntityProxy ObjectNotFoundException,
InvalidDataException,
PersistencyException,
- ObjectAlreadyExistsException
+ ObjectAlreadyExistsException,
+ ScriptErrorException
{
OutcomeValidator validator = null;
String scriptName = job.getActPropString("ScriptName");
Date startTime = new Date();
Logger.msg(3, "AgentProxy - executing "+job.getStepPath()+" for "+path.getAgentName());
// get the outcome validator if present
- if (job.isOutcomeUsed())
+ if (job.isOutcomeSet())
{
+ String schemaName = job.getSchemaType();
+ int schemaVersion = job.getSchemaVersion();
- // get schema info from act props
- String schemaName = job.getActPropString("SchemaType");
- int schemaVersion;
- try {
- schemaVersion = Integer.parseInt(job.getActPropString("SchemaVersion"));
- } catch (Exception e) {
- throw new InvalidDataException(e.getClass().getName()+" extracing schema version", "");
- }
Logger.msg(5, "AgentProxy - fetching schema "+schemaName+"_"+schemaVersion+" for validation");
// retrieve schema
Schema schema = LocalObjectLoader.getSchema(schemaName, schemaVersion);
@@ -155,20 +152,20 @@ public class AgentProxy extends EntityProxy // load script
ErrorInfo scriptErrors = (ErrorInfo)callScript(item, job);
+ String errorString = scriptErrors.toString();
if (scriptErrors.getFatal()) {
Logger.msg(3, "AgentProxy - fatal script error");
- Logger.error(scriptErrors.getErrors());
- throw new InvalidDataException("Fatal Script Error: \n"+scriptErrors.getErrors(), "");
+ throw new ScriptErrorException(scriptErrors);
}
- if (scriptErrors.getErrors().length() > 0)
- Logger.warning("Script errors: "+scriptErrors.getErrors());
+ if (errorString.length() > 0)
+ Logger.warning("Script errors: "+errorString);
} catch (ScriptingEngineException ex) {
Logger.error(ex);
throw new InvalidDataException(ex.getMessage(), "");
}
}
- if (job.isOutcomeUsed()) {
+ if (job.isOutcomeSet()) {
Logger.msg(3, "AgentProxy - validating outcome");
String error = validator.validate(job.getOutcomeString());
if (error.length() > 0)
@@ -201,6 +198,7 @@ public class AgentProxy extends EntityProxy * @throws ObjectNotFoundException
* @throws PersistencyException
* @throws ObjectAlreadyExistsException
+ * @throws ScriptErrorException
*/
public void execute(Job job)
throws AccessRightsException,
@@ -208,7 +206,8 @@ public class AgentProxy extends EntityProxy InvalidTransitionException,
ObjectNotFoundException,
PersistencyException,
- ObjectAlreadyExistsException
+ ObjectAlreadyExistsException,
+ ScriptErrorException
{
try {
ItemProxy targetItem = (ItemProxy)Gateway.getProxyManager().getProxy(new EntityPath(job.getItemSysKey()));
diff --git a/src/main/java/com/c2kernel/entity/proxy/ItemProxy.java b/src/main/java/com/c2kernel/entity/proxy/ItemProxy.java index dcaef55..55e1fe9 100644 --- a/src/main/java/com/c2kernel/entity/proxy/ItemProxy.java +++ b/src/main/java/com/c2kernel/entity/proxy/ItemProxy.java @@ -105,7 +105,7 @@ public class ItemProxy extends EntityProxy String outcome = thisJob.getOutcomeString();
// check fields that should have been filled in
if (outcome==null)
- if (thisJob.isOutcomeUsed())
+ if (thisJob.requiresOutcome())
throw new InvalidDataException("Outcome is required.", "");
else
outcome="";
diff --git a/src/main/java/com/c2kernel/lifecycle/WfCastorHashMap.java b/src/main/java/com/c2kernel/lifecycle/WfCastorHashMap.java index 7d88ea9..176f22e 100644 --- a/src/main/java/com/c2kernel/lifecycle/WfCastorHashMap.java +++ b/src/main/java/com/c2kernel/lifecycle/WfCastorHashMap.java @@ -16,7 +16,6 @@ public class WfCastorHashMap extends CastorHashMap put(StateMachine.SKIPPABLE, new Boolean(true));
put(StateMachine.REPEATABLE, new Boolean(true));
put(StateMachine.IGNORABLE, new Boolean(false));
- put("AlwaysUseOutcome", new Boolean(false));
put("Viewpoint", "");
put("Show time", new Boolean(true));
put("Description", "");
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/Activity.java b/src/main/java/com/c2kernel/lifecycle/instance/Activity.java index 8d92522..8dc6b9d 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/Activity.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/Activity.java @@ -543,26 +543,28 @@ public class Activity extends WfVertex } /**
* Stores the request data as an outcome of the Item It does a great deal of storing outcomes in different configuration
*/ //requestdata is xmlstring
- private String storeOutcome(int eventID, String requestData)
+ private String storeOutcome(int eventID, String requestData, boolean isError) throws InvalidDataException
{
EntityPath entityPath = getItemEntityPath();
if (entityPath != null)
{
- String schemaType = (String) getProperties().get("SchemaType");
- if (schemaType == null || schemaType.length() == 0) // no
- // outcome
- // required
- return null;
- int schemaVersion = 0;
- String versionString = (String) getProperties().get("SchemaVersion");
- try
- {
- schemaVersion = Integer.parseInt(versionString);
+ String schemaType; int schemaVersion;
+ if (isError) {
+ schemaType="Errors";
+ schemaVersion=0;
}
- catch (Exception e)
- {
- Logger.error("Activity.storeOutcome() - invalid schemaVersion " + versionString);
+ else {
+ schemaType = (String) getProperties().get("SchemaType");
+ if (schemaType == null || schemaType.length() == 0) return null;
+ String versionString = (String) getProperties().get("SchemaVersion");
+ try
+ {
+ schemaVersion = Integer.parseInt(versionString);
+ } catch (Exception e) {
+ throw new InvalidDataException("Activity.storeOutcome() - invalid schemaVersion " + versionString, "");
+ }
}
+
Logger.msg(5, "Activity::storeOutcome() - type:" + schemaType + " version:" + schemaVersion);
try
{
@@ -588,16 +590,19 @@ public class Activity extends WfVertex }
else
return null;
- } /** the method to be called by the requestAction() method */
- public void sendEventStoreOutcome(int transitionID, String requestData, AgentPath agent)
+ }
+
+ /** the method to be called by the requestAction() method
+ * @throws InvalidDataException */
+ public void sendEventStoreOutcome(int transitionID, String requestData, AgentPath agent) throws InvalidDataException
{
int eventID = -1;
Event event = null;
event = auditEvent(transitionID, agent);
if (event != null)
eventID = event.getID();
- if (transitionID == Transitions.DONE || transitionID == Transitions.COMPLETE)
- storeOutcome(eventID, requestData);
+ if ((transitionID == Transitions.DONE || transitionID == Transitions.COMPLETE || transitionID == Transitions.SUSPEND) && requestData != null && requestData.length() > 0)
+ storeOutcome(eventID, requestData, transitionID == Transitions.SUSPEND);
EntityPath entityPath = getItemEntityPath();
TransactionManager storage = Gateway.getStorage();
if (entityPath != null)
diff --git a/src/main/java/com/c2kernel/process/UserCodeProcess.java b/src/main/java/com/c2kernel/process/UserCodeProcess.java index 7779802..2f508bc 100644 --- a/src/main/java/com/c2kernel/process/UserCodeProcess.java +++ b/src/main/java/com/c2kernel/process/UserCodeProcess.java @@ -14,6 +14,8 @@ import com.c2kernel.entity.proxy.EntityProxyObserver; import com.c2kernel.entity.proxy.MemberSubscription;
import com.c2kernel.lifecycle.instance.stateMachine.Transitions;
import com.c2kernel.persistency.ClusterStorage;
+import com.c2kernel.scripting.ErrorInfo;
+import com.c2kernel.scripting.ScriptErrorException;
import com.c2kernel.utils.Logger;
/**************************************************************************
@@ -28,6 +30,7 @@ public class UserCodeProcess extends StandardClient implements EntityProxyObserv protected AgentProxy agent;
static boolean active = true;
ArrayList<String> ignoredPaths = new ArrayList<String>();
+ HashMap<String, ErrorInfo> errors = new HashMap<String, ErrorInfo>();
HashMap<String, C2KLocalObject> jobs;
public UserCodeProcess(String agentName, String agentPass) {
@@ -96,18 +99,31 @@ public class UserCodeProcess extends StandardClient implements EntityProxyObserv ignoredPaths.remove(jobKey);
}
else if (thisJob.getPossibleTransition()==Transitions.SUSPEND) {
- if (ignoredPaths.contains(jobKey))
+ if (ignoredPaths.contains(jobKey)) {
+ if (errors.containsKey(jobKey)) {
+ thisJob.setOutcome(Gateway.getMarshaller().marshall(errors.get(jobKey)));
+ errors.remove(jobKey);
+ }
agent.execute(thisJob);
+ }
}
else if (thisJob.getPossibleTransition()==Transitions.RESUME) {
if (!ignoredPaths.contains(jobKey))
agent.execute(thisJob);
}
+ } catch (ScriptErrorException ex) {
+ errors.put(jobKey, ex.getErrors());
+ ignoredPaths.add(jobKey);
} catch (InvalidTransitionException ex) {
// must have already been done by someone else - ignore
} catch (Throwable ex) {
Logger.error("Error executing "+Transitions.getTransitionName(thisJob.getPossibleTransition())+" job:");
Logger.error(ex);
+ ErrorInfo ei = new ErrorInfo();
+ ei.setFatal();
+ ei.addError(ex.getClass().getSimpleName());
+ ei.addError(ex.getMessage());
+ errors.put(jobKey, ei);
ignoredPaths.add(jobKey);
}
}
diff --git a/src/main/java/com/c2kernel/process/module/Module.java b/src/main/java/com/c2kernel/process/module/Module.java index 4a0987a..19cc41a 100644 --- a/src/main/java/com/c2kernel/process/module/Module.java +++ b/src/main/java/com/c2kernel/process/module/Module.java @@ -42,7 +42,7 @@ public class Module { Object result = script.getScript().execute();
if (result instanceof ErrorInfo) {
ErrorInfo error = (ErrorInfo) result;
- Logger.error(error.getErrors());
+ Logger.error(error.toString());
if (error.getFatal())
throw new ScriptingEngineException("Fatal Script Error");
}
diff --git a/src/main/java/com/c2kernel/scripting/ErrorInfo.java b/src/main/java/com/c2kernel/scripting/ErrorInfo.java index 26c0384..efe90ce 100644 --- a/src/main/java/com/c2kernel/scripting/ErrorInfo.java +++ b/src/main/java/com/c2kernel/scripting/ErrorInfo.java @@ -28,13 +28,22 @@ public class ErrorInfo { msg.add(error);
}
- public String getErrors() {
+ @Override
+ public String toString() {
StringBuffer err = new StringBuffer();
for (String element : msg) {
err.append(element+"\n");
}
return err.toString();
}
+
+ public void setErrors(ArrayList<String> msg) {
+ this.msg = msg;
+ }
+
+ public ArrayList<String> getErrors() {
+ return msg;
+ }
public void setFatal() {
fatal=true;
diff --git a/src/main/java/com/c2kernel/scripting/ScriptErrorException.java b/src/main/java/com/c2kernel/scripting/ScriptErrorException.java new file mode 100644 index 0000000..9b1084f --- /dev/null +++ b/src/main/java/com/c2kernel/scripting/ScriptErrorException.java @@ -0,0 +1,30 @@ +package com.c2kernel.scripting;
+
+public class ScriptErrorException extends java.lang.Exception {
+
+ /**
+ * Creates new <code>sciptingEngineException</code> without detail message.
+ */
+ ErrorInfo errors;
+ public ScriptErrorException() {
+ }
+
+ /**
+ * Constructs an <code>sciptingEngineException</code> with the specified detail message.
+ * @param msg the detail message.
+ */
+ public ScriptErrorException(String msg) {
+ super(msg);
+ }
+
+ public ScriptErrorException(ErrorInfo errors) {
+ super(errors.toString());
+ this.errors = errors;
+ }
+
+ public ErrorInfo getErrors() {
+ return errors;
+ }
+}
+
+
diff --git a/src/main/resources/boot/OD/Errors.xsd b/src/main/resources/boot/OD/Errors.xsd new file mode 100644 index 0000000..a30473c --- /dev/null +++ b/src/main/resources/boot/OD/Errors.xsd @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" + elementFormDefault="qualified" attributeFormDefault="unqualified"> + <xs:element name="Errors"> + <xs:complexType> + <xs:sequence> + <xs:element name="Message" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> + </xs:sequence> + <xs:attribute name="fatal" type="xs:boolean"/> + </xs:complexType> + </xs:element> +</xs:schema>
\ No newline at end of file diff --git a/src/main/resources/boot/allbootitems.txt b/src/main/resources/boot/allbootitems.txt index 810d5ee..8c6e052 100644 --- a/src/main/resources/boot/allbootitems.txt +++ b/src/main/resources/boot/allbootitems.txt @@ -7,6 +7,7 @@ OD/PredefinedStepOutcome OD/PropertyDescription
OD/Schema
OD/Script
+OD/Errors
EA/AssignNewVersionFromLast
EA/EditActivityDef
EA/EditSchema
diff --git a/src/main/resources/mapFiles/LifeCycleMap.xml b/src/main/resources/mapFiles/LifeCycleMap.xml index ba75864..f623e52 100644 --- a/src/main/resources/mapFiles/LifeCycleMap.xml +++ b/src/main/resources/mapFiles/LifeCycleMap.xml @@ -97,4 +97,13 @@ <class name="com.c2kernel.lifecycle.instance.predefined.ServerPredefinedStepContainer" extends="com.c2kernel.lifecycle.instance.predefined.PredefinedStepContainer">
<map-to xml="ServerPredefinedStepContainer"/>
</class>
+ <class name="com.c2kernel.scripting.ErrorInfo">
+ <map-to xml="Errors"/>
+ <field name="fatal" type="boolean" direct="false">
+ <bind-xml name="fatal" node="attribute"/>
+ </field>
+ <field name="msg" type="string" direct="false" collection="arraylist" get-method="getErrors" set-method="setErrors">
+ <bind-xml name="Message" node="element"/>
+ </field>
+ </class>
</mapping>
|
