/************************************************************************** * AgentProxy.java * * $Revision: 1.37 $ * $Date: 2005/10/05 07:39:36 $ * * Copyright (C) 2001 CERN - European Organization for Nuclear Research * All rights reserved. **************************************************************************/ package com.c2kernel.entity.proxy; import java.util.Date; import java.util.Enumeration; 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; import com.c2kernel.entity.AgentHelper; import com.c2kernel.entity.C2KLocalObject; import com.c2kernel.entity.ManageableEntity; import com.c2kernel.entity.agent.Job; import com.c2kernel.lifecycle.instance.predefined.PredefinedStep; import com.c2kernel.lifecycle.instance.stateMachine.Transitions; import com.c2kernel.lookup.AgentPath; import com.c2kernel.lookup.DomainPath; import com.c2kernel.lookup.EntityPath; import com.c2kernel.lookup.InvalidEntityPathException; import com.c2kernel.lookup.Path; import com.c2kernel.persistency.outcome.OutcomeValidator; 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; /****************************************************************************** * It is a wrapper for the connection and communication with Agent * It caches data loaded from the Agent to reduce communication * * @version $Revision: 1.37 $ $Date: 2005/10/05 07:39:36 $ * @author $Author: abranson $ ******************************************************************************/ public class AgentProxy extends EntityProxy { AgentPath path; /************************************************************************** * Creates an AgentProxy without cache and change notification **************************************************************************/ public AgentProxy( org.omg.CORBA.Object ior, int systemKey) throws ObjectNotFoundException { super(ior, systemKey); try { path = new AgentPath(systemKey); } catch (InvalidEntityPathException e) { throw new ObjectNotFoundException(); } } @Override public ManageableEntity narrow() throws ObjectNotFoundException { try { return AgentHelper.narrow(mIOR); } catch (org.omg.CORBA.BAD_PARAM ex) { } throw new ObjectNotFoundException("CORBA Object was not an Agent, or the server is down."); } /************************************************************************** * * **************************************************************************/ public void initialise( String agentProps, String collector ) throws AccessRightsException, InvalidDataException, PersistencyException, ObjectNotFoundException { Logger.msg(7, "AgentProxy::initialise - started"); ((Agent)getEntity()).initialise( agentProps ); } public AgentPath getPath() { return path; } /** * Executes a job on the given item using this agent. * * @param item - item holding this job * @param job - the job to execute * @throws ScriptErrorException */ public void execute(ItemProxy item, Job job) throws AccessRightsException, InvalidTransitionException, ObjectNotFoundException, InvalidDataException, PersistencyException, 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.isOutcomeSet()) { String schemaName = job.getSchemaType(); int schemaVersion = job.getSchemaVersion(); Logger.msg(5, "AgentProxy - fetching schema "+schemaName+"_"+schemaVersion+" for validation"); // retrieve schema Schema schema = LocalObjectLoader.getSchema(schemaName, schemaVersion); if (schema == null) throw new InvalidDataException("Job references outcome type "+schemaName+" version "+schemaVersion+" that does not exist in this centre.", ""); try { validator = OutcomeValidator.getValidator(schema); } catch (Exception e) { throw new InvalidDataException("Could not create validator: "+e.getMessage(), ""); } } if(scriptName != null && scriptName.length() > 0 && (job.getPossibleTransition() == Transitions.DONE || job.getPossibleTransition() == Transitions.COMPLETE)) { Logger.msg(3, "AgentProxy - executing script "+scriptName); try { // pre-validate outcome from script if there is one if (job.getOutcomeString()!= null && validator != null) { Logger.msg(5, "AgentProxy - validating outcome before script execution"); String error = validator.validate(job.getOutcomeString()); if (error.length() > 0) { Logger.error("Outcome not valid: \n " + error); throw new InvalidDataException(error, ""); } } // load script ErrorInfo scriptErrors = (ErrorInfo)callScript(item, job); String errorString = scriptErrors.toString(); if (scriptErrors.getFatal()) { Logger.msg(3, "AgentProxy - fatal script error"); throw new ScriptErrorException(scriptErrors); } if (errorString.length() > 0) Logger.warning("Script errors: "+errorString); } catch (ScriptingEngineException ex) { Logger.error(ex); throw new InvalidDataException(ex.getMessage(), ""); } } if (job.isOutcomeSet()) { Logger.msg(3, "AgentProxy - validating outcome"); String error = validator.validate(job.getOutcomeString()); if (error.length() > 0) throw new InvalidDataException(error, ""); } job.setAgentId(getSystemKey()); Logger.msg(3, "AgentProxy - submitting job to item proxy"); item.requestAction(job); if (Logger.doLog(3)) { Date timeNow = new Date(); long secsNow = (timeNow.getTime()-startTime.getTime())/1000; Logger.msg(3, "Execution took "+secsNow+" seconds"); } } private Object callScript(ItemProxy item, Job job) throws ScriptingEngineException { Script script = new Script(item, this, job); return script.execute(); } /** * Standard execution of jobs. Note that this method should always be the one used from clients - all execution * parameters are taken from the job where they're probably going to be correct. * * @param job * @throws AccessRightsException * @throws InvalidDataException * @throws InvalidTransitionException * @throws ObjectNotFoundException * @throws PersistencyException * @throws ObjectAlreadyExistsException * @throws ScriptErrorException */ public void execute(Job job) throws AccessRightsException, InvalidDataException, InvalidTransitionException, ObjectNotFoundException, PersistencyException, ObjectAlreadyExistsException, ScriptErrorException { try { ItemProxy targetItem = (ItemProxy)Gateway.getProxyManager().getProxy(new EntityPath(job.getItemSysKey())); execute(targetItem, job); } catch (InvalidEntityPathException e) { throw new ObjectNotFoundException("Job contained invalid item sysKey: "+job.getItemSysKey(), ""); } } public void execute(ItemProxy item, String predefStep, C2KLocalObject obj) throws AccessRightsException, InvalidDataException, InvalidTransitionException, ObjectNotFoundException, PersistencyException, ObjectAlreadyExistsException { String param; try { param = marshall(obj); } catch (Exception ex) { Logger.error(ex); throw new InvalidDataException("Error on marshall", ""); } execute(item, predefStep, param); } public void execute(ItemProxy item, String predefStep, String... params) throws AccessRightsException, InvalidDataException, InvalidTransitionException, ObjectNotFoundException, PersistencyException, ObjectAlreadyExistsException { item.requestAction(getSystemKey(), "workflow/predefined/"+predefStep, Transitions.DONE, PredefinedStep.bundleData(params)); } /** Wrappers for scripts */ public String marshall(Object obj) throws Exception { return Gateway.getMarshaller().marshall(obj); } public Object unmarshall(String obj) throws Exception { return Gateway.getMarshaller().unmarshall(obj); } /** Let scripts resolve items */ public ItemProxy searchItem(String name) throws ObjectNotFoundException { Enumeration results = Gateway.getLookup().search(new DomainPath(""),name); Path returnPath = null; if (!results.hasMoreElements()) throw new ObjectNotFoundException(name, ""); while(results.hasMoreElements()) { Path nextMatch = results.nextElement(); if (returnPath != null && nextMatch.getSysKey() != -1 && returnPath.getSysKey() != nextMatch.getSysKey()) throw new ObjectNotFoundException("Too many items with that name"); returnPath = nextMatch; } return (ItemProxy)Gateway.getProxyManager().getProxy(returnPath); } public ItemProxy getItem(String itemPath) throws ObjectNotFoundException { return (getItem(new DomainPath(itemPath))); } public ItemProxy getItem(Path itemPath) throws ObjectNotFoundException { return (ItemProxy)Gateway.getProxyManager().getProxy(itemPath); } public ItemProxy getItemBySysKey(int sysKey) throws ObjectNotFoundException, InvalidEntityPathException { return (ItemProxy)Gateway.getProxyManager().getProxy(new EntityPath(sysKey)); } }