blob: 23d212cd3269c441af9a0dcdb828bbf048220596 [file] [log] [blame]
/*******************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*******************************************************************************/
package org.enhydra.shark;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import org.enhydra.shark.SharkEngineManager;
import org.enhydra.shark.api.ApplicationMappingTransaction;
import org.enhydra.shark.api.RootException;
import org.enhydra.shark.api.SharkTransaction;
import org.enhydra.shark.api.client.wfbase.BaseException;
import org.enhydra.shark.api.internal.appmappersistence.ApplicationMap;
import org.enhydra.shark.api.internal.appmappersistence.ApplicationMappingManager;
import org.enhydra.shark.api.internal.toolagent.AppParameter;
import org.enhydra.shark.api.internal.toolagent.ConnectFailed;
import org.enhydra.shark.api.internal.toolagent.SessionHandle;
import org.enhydra.shark.api.internal.toolagent.ToolAgent;
import org.enhydra.shark.api.internal.toolagent.ToolAgentGeneralException;
import org.enhydra.shark.api.internal.working.CallbackUtilities;
import org.enhydra.shark.api.internal.working.ToolAgentManager;
import org.enhydra.shark.api.internal.working.WfActivityInternal;
import org.enhydra.shark.api.internal.working.WfProcessInternal;
import org.enhydra.shark.xpdl.XMLComplexElement;
import org.enhydra.shark.xpdl.XPDLConstants;
import org.enhydra.shark.xpdl.XMLUtil;
import org.enhydra.shark.xpdl.elements.Activity;
import org.enhydra.shark.xpdl.elements.ActivityTypes;
import org.enhydra.shark.xpdl.elements.ActualParameter;
import org.enhydra.shark.xpdl.elements.ActualParameters;
import org.enhydra.shark.xpdl.elements.Application;
import org.enhydra.shark.xpdl.elements.FormalParameter;
import org.enhydra.shark.xpdl.elements.FormalParameters;
import org.enhydra.shark.xpdl.elements.ImplementationTypes;
import org.enhydra.shark.xpdl.elements.Tool;
import org.enhydra.shark.xpdl.elements.WorkflowProcess;
/**
* Executes tool agents for Tool activities.
*/
public class ThreadedToolAgentManager implements ToolAgentManager {
private final static long APP_STATUS_INVALID=-1;
private final static String DEFAULT_TOOL_AGENT="DefaultToolAgent";
private String defaultToolAgentClassName;
private CallbackUtilities cus;
protected ThreadedToolAgentManager () {
this.cus=SharkEngineManager.getInstance().getCallbackUtilities();
Properties props= cus.getProperties();
// setting default tool agent
try {
defaultToolAgentClassName=(String)props.get(DEFAULT_TOOL_AGENT);
} catch (Throwable ex) {
cus.error("ToolAgentManagerImpl -> Can't read default tool agent name - can't work without mappings !!!");
}
}
public void executeActivity (SharkTransaction t,WfActivityInternal act) throws BaseException, ToolAgentGeneralException {
ToolRunner tr=new ToolRunner(t,act);
tr.run();
}
protected class ToolRunner{// implements Runnable {
protected WfActivityInternal activity;
protected Activity actDef;
protected SharkTransaction transaction;
protected ToolRunner (SharkTransaction t,WfActivityInternal wai) throws BaseException {
this.transaction=t;
this.activity=wai;
WfProcessInternal pr=wai.container(t);
WorkflowProcess wp=SharkUtilities.
getWorkflowProcess(pr.package_id(t),
pr.manager_version(t),
pr.process_definition_id(t));
this.actDef=SharkUtilities.getActivityDefinition(t,wai,wp,wai.block_activity(t));
}
public void run () throws BaseException, ToolAgentGeneralException {
Iterator tools = null;
try {
ActivityTypes acTypes = actDef.getActivityTypes();
org.enhydra.shark.xpdl.elements.Implementation impl = acTypes.getImplementation();
ImplementationTypes implt = impl.getImplementationTypes();
org.enhydra.shark.xpdl.elements.Tools tolls = implt.getTools();
ArrayList al = tolls.toElements();
tools = al.iterator();
} catch (Exception e) {
e.printStackTrace();
throw new BaseException(e);
}
while (tools.hasNext()) {
Tool tool = (Tool)tools.next();
cus.info("Activity"+activity.toString()+" - Executing tool [id="+tool.getId()+"]");
// implement me
/*if (tool.get("Type").toValue().toString().equals("APPLICATION")) {
} else {*/
try {
invokeApplication(tool);
// if some application is not executed, throw an exception
} catch (Throwable ex) {
cus.error("Activity"+activity.toString()+" - failed to execute tool [id="+tool.getId()+"]");
if (ex instanceof ToolAgentGeneralException) {
throw (ToolAgentGeneralException)ex;
} else {
throw new BaseException(ex);
}
}
//}
}
}
protected Map createContextMap (ActualParameters aps,FormalParameters fps) throws Exception {
return SharkUtilities.createContextMap(transaction,activity,aps,fps);
}
protected String getAssignmentId (String procId,String actId) throws Exception {
String actRes=activity.getResourceRequesterUsername(transaction);
String assId=SharkUtilities.createAssignmentKey(actId,actRes);
return assId;
}
protected void invokeApplication(Tool tool) throws Throwable {
String applicationId = tool.getId();
Application app=SharkUtilities.getApplication(tool, applicationId);
ArrayList parameters = new ArrayList();
// the extended attributes are always the first parameter passed to tool agent
String appPStr=app.getExtendedAttributes().getExtendedAttributesString();
AppParameter param=new AppParameter("ExtendedAttributes","ExtendedAttributes",XPDLConstants.FORMAL_PARAMETER_MODE_IN,appPStr,String.class);
parameters.add(param);
ActualParameters aps=tool.getActualParameters();
FormalParameters fps=app.getApplicationTypes().getFormalParameters();
Map m=createContextMap(aps,fps);
Iterator itFps=fps.toElements().iterator();
Iterator itAps=aps.toElements().iterator();
while (itFps.hasNext() && itAps.hasNext()) {
FormalParameter fp=(FormalParameter)itFps.next();
ActualParameter ap=(ActualParameter)itAps.next();
String fpMode=fp.getMode();
String fpId=fp.getId();
Object paramVal=m.get(fpId);
param=new AppParameter(ap.toValue(),fpId,fpMode,paramVal,SharkUtilities.getJavaClass(fp));
parameters.add(param);
}
ApplicationMappingManager mm=SharkEngineManager.getInstance().getApplicationMapPersistenceManager();
ApplicationMap tad=null;
if (mm!=null) {
XMLComplexElement cOwn=(XMLComplexElement)app.getParent().getParent();
boolean isProcessApp=(cOwn instanceof WorkflowProcess);
ApplicationMappingTransaction t=null;
try {
t = SharkUtilities.createApplicationMappingTransaction();
tad= mm.getApplicationMap(
t,
XMLUtil.getPackage(app).getId(),
((isProcessApp)? cOwn.get("Id").toValue() : null),
applicationId
);
SharkUtilities.commitMappingTransaction(t);
} catch (RootException e) {
SharkUtilities.rollbackMappingTransaction(t,e);
throw e;
} finally {
SharkUtilities.releaseMappingTransaction(t);
}
}
SessionHandle shandle=null;
String tacn=(tad!=null) ? tad.getToolAgentClassName() : defaultToolAgentClassName;
String uname=(tad!=null) ? tad.getUsername() : "";
String pwd=(tad!=null) ? tad.getPassword() : "";
String appN=(tad!=null) ? tad.getApplicationName() : "";
Integer appM=(tad!=null) ? tad.getApplicationMode() : null;
ToolAgent ta=SharkEngineManager.getInstance().
getToolAgentFactory().
createToolAgent(transaction,tacn);
// try to connect to the tool agent
try {
shandle=ta.connect(transaction,uname,pwd,cus.getProperty("enginename","imaobihostrezube"),"");
} catch (ConnectFailed cf) {
cus.error("Activity"+activity.toString()+" - connection to Tool agent "+tacn+" failed !");
throw cf;
}
String procId=activity.container(transaction).key(transaction);
String actKey=activity.key(transaction);
String assId=getAssignmentId(procId,actKey);
// invoke the procedure with the specified parameters
AppParameter[] aprs=(AppParameter[])parameters.toArray(
new AppParameter[parameters.size()]);
ta.invokeApplication(transaction,
shandle.getHandle(),
appN,
procId,
assId,
aprs,
appM);
long appStatus;
appStatus=ta.requestAppStatus(transaction,
shandle.getHandle(),
procId,
assId,
aprs);
if (appStatus==APP_STATUS_INVALID) {
ta.disconnect(transaction,shandle);
throw new Exception("Tool agent status is invalid!");
}
ta.disconnect(transaction,shandle);
AppParameter[] returnValues=aprs;
// copy the return values into the workflow data
Map newData=new HashMap();
for(int i = 0; i < returnValues.length; i++) {
if (returnValues[i].the_mode.equals(XPDLConstants.FORMAL_PARAMETER_MODE_OUT) ||
returnValues[i].the_mode.equals(XPDLConstants.FORMAL_PARAMETER_MODE_INOUT)) {
String name = returnValues[i].the_actual_name;
Object value = returnValues[i].the_value;
newData.put(name,value);
}
}
activity.set_result(transaction,newData);
}
}
}