blob: 51ffcab31be434d3e46c4b223bbfbccfc7dbde00 [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.apache.ode.bpel.engine;
import org.apache.ode.bpel.bdi.breaks.ActivityBreakpoint;
import org.apache.ode.bpel.bdi.breaks.Breakpoint;
import org.apache.ode.bpel.bdi.breaks.VariableModificationBreakpoint;
import org.apache.ode.bpel.common.CorrelationKey;
import org.apache.ode.bpel.dao.*;
import org.apache.ode.bpel.iapi.BpelServer;
import org.apache.ode.bpel.iapi.ProcessStore;
import org.apache.ode.bpel.o.OProcess;
import org.apache.ode.bpel.pmapi.*;
import org.apache.ode.bpel.pmapi.TInstanceInfo.EventInfo;
import org.apache.ode.bpel.runtime.breaks.ActivityBreakpointImpl;
import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.uuid.UUIDGen;
import org.w3c.dom.Node;
import javax.xml.namespace.QName;
import java.util.*;
/**
* Implementation of the instance/process management interaction. This class implements
* the methods necessary to support process debugging. It also implements all the methods in the
* newer Process/Instance Management interface (pmapi).
*/
public class BpelManagementFacadeImpl extends ProcessAndInstanceManagementImpl
implements BpelManagementFacade {
private static UUIDGen _uuidGen = new UUIDGen();
public BpelManagementFacadeImpl(BpelServer server, ProcessStore store) {
super(server, store);
}
public short getState(final Long iid) throws ManagementException {
return dbexec(new BpelDatabase.Callable<Short>() {
public Short run(BpelDAOConnection session) throws Exception {
ProcessInstanceDAO instance = session.getInstance(iid);
return Short.valueOf(instance.getState());
}
}).shortValue();
}
public Long getProcessInstance(String pid, final CorrelationKey ckey) throws ManagementException {
return dbexec(_db.getProcessDb(QName.valueOf(pid)).new Callable<Long>() {
public Long run(BpelDAOConnection session) throws Exception {
Iterator<ProcessInstanceDAO> i = getProcessDAO().findInstance(ckey).iterator();
return (i.hasNext()) ? i.next().getInstanceId() : null;
}
});
}
public EventInfoListDocument getEvents(final Long iid, final int startIdx, final int count)
throws ManagementException {
// TODO: this is a bit of hack, if there are two events with exactly the
// same timestamp, we can have more events returned then requested.
List<String> timeline;
try {
timeline = getEventTimeline("iid="+iid,null);
} catch (Exception ex) {
throw new ManagementException("Unable to retrieve timeline.", ex);
}
if (startIdx >= timeline.size())
return EventInfoListDocument.Factory.newInstance();
timeline = timeline.subList(startIdx,Math.min(timeline.size(),startIdx+count));
String startdt = timeline.get(0);
String enddt = timeline.get(timeline.size()-1);
return listEvents("iid="+iid,"timestamp>="+startdt +" " +"timestamp<="+enddt,0);
}
public int getEventCount(final Long iid) throws ManagementException {
EventInfo einfo = getInstanceInfo(iid).getInstanceInfo().getEventInfo();
if (einfo == null)
return 0;
return einfo.getCount();
}
public String getVariable(final Long iid, final Long scopeId, final String varName)
throws ManagementException {
return dbexec(new BpelDatabase.Callable<String>() {
public String run(BpelDAOConnection session) throws Exception {
ProcessInstanceDAO instance = session.getInstance(iid);
if (instance == null) {
throw new ManagementException("InstanceNotFound:" + iid);
}
ScopeDAO scope = instance.getScope(scopeId);
if (scope == null) {
throw new ManagementException("ScopeNotFound:" + scopeId);
}
XmlDataDAO var = scope.getVariable(varName);
if (var == null) {
throw new ManagementException("VarNotFound:" + varName);
}
return nodeToString(var);
}
});
}
public Long[] getScopeInstancesForScope(final Long iid, final String scopeName) throws ManagementException {
return dbexec(new BpelDatabase.Callable<Long[]>() {
public Long[] run(BpelDAOConnection session) throws Exception {
ProcessInstanceDAO instance = session.getInstance(iid);
if (instance == null) {
throw new ManagementException("InstanceNotFound:" + iid);
}
Collection<ScopeDAO> scopes = instance.getScopes(scopeName);
List<Long>instanceIds = new ArrayList<Long>(scopes.size());
for(ScopeDAO i : scopes) {
instanceIds.add(i.getScopeInstanceId());
}
return instanceIds.toArray(new Long[scopes.size()]);
}
});
}
public void setVariable(Long pid, Long scopeId, String varName, String data) {
throw new UnsupportedOperationException();
}
public void setCorrelation(final Long iid, final Long scopeId, final String correlationSet,
final QName[] propertyNames, final CorrelationKey values)
throws ManagementException {
dbexec(new BpelDatabase.Callable<Object>() {
public Object run(BpelDAOConnection session) throws Exception {
ProcessInstanceDAO instance = session.getInstance(iid);
if (instance == null) {
throw new ManagementException("InstanceNotFound:" + iid);
}
CorrelationSetDAO correlationSetDAO = instance.getCorrelationSet(correlationSet);
correlationSetDAO.setValue(propertyNames, values);
return null;
}
});
}
public CorrelationKey getCorrelation(final Long iid, final Long scopeId, final String correlationSet) throws ManagementException {
return dbexec(new BpelDatabase.Callable<CorrelationKey>() {
public CorrelationKey run(BpelDAOConnection session) throws Exception {
ProcessInstanceDAO instance = session.getInstance(iid);
if (instance == null) {
throw new ManagementException("InstanceNotFound:" + iid);
}
CorrelationSetDAO corr = findCorrelationSetDAO(instance, scopeId, correlationSet);
return corr.getValue();
}
});
}
/**
* @see BpelManagementFacade#getProcessDef(String)
* @param procid
*/
public OProcess getProcessDef(String procid) throws ManagementException {
if (_server._engine == null)
throw new ProcessingException("ServiceProvider required for debugger operation.");
BpelProcess process = _server._engine._activeProcesses.get(QName.valueOf(procid));
if (process == null)
throw new InvalidRequestException("The process \"" + procid + "\" is not available. Please make sure it is deployed and encompassing System is activated." );
return process.getOProcess();
}
public void step(final Long iid) throws ManagementException {
// We need debugger support in order to resume (since we have to force
// a reduction. If one is not available the getDebugger() method should
// throw a ProcessingException
DebuggerSupport debugSupport = getDebugger(iid);
assert debugSupport != null : "getDebugger(Long) returned NULL!";
debugSupport.step(iid);
}
public QName getCompletedFault(final Long iid) throws ManagementException {
return dbexec(new BpelDatabase.Callable<QName>() {
public QName run(BpelDAOConnection session) throws Exception {
ProcessInstanceDAO instance = session.getInstance(iid);
if (instance == null)
throw new ManagementException("InstanceNotFound:" + iid);
return instance.getFault().getName();
}
});
}
public Breakpoint[] getGlobalBreakpoints(String procId) throws ManagementException {
DebuggerSupport debuggerSupport = getDebugger(QName.valueOf(procId));
return debuggerSupport.getGlobalBreakpoints();
}
public Breakpoint[] getBreakpoints(Long iid) throws ManagementException {
DebuggerSupport debuggerSupport = getDebugger(iid);
return debuggerSupport.getBreakpoints(iid);
}
public void removeGlobalBreakpoint(String procid, Breakpoint sp) throws ManagementException {
DebuggerSupport debuggerSupport = getDebugger(QName.valueOf(procid));
debuggerSupport.removeGlobalBreakpoint(sp);
}
public void removeBreakpoint(Long iid, Breakpoint sp) throws ManagementException {
DebuggerSupport debuggerSupport = getDebugger(iid);
debuggerSupport.removeBreakpoint(iid, sp);
}
public ActivityBreakpoint addGlobalActivityBreakpoint(String procid, String activity) throws ManagementException {
DebuggerSupport debuggerSupport = getDebugger(QName.valueOf(procid));
ActivityBreakpointImpl bp = new ActivityBreakpointImpl(_uuidGen.nextUUID(), activity);
debuggerSupport.addGlobalBreakpoint(bp);
return bp;
}
public ActivityBreakpoint addActivityBreakpoint(Long iid, String activity) throws ManagementException {
DebuggerSupport debuggerSupport = getDebugger(iid);
ActivityBreakpointImpl bp = new ActivityBreakpointImpl(_uuidGen.nextUUID(), activity);
debuggerSupport.addBreakpoint(iid, bp);
return bp;
}
public VariableModificationBreakpoint addVariableModificationBreakpoint(Long iid, String scopename, String variable) {
throw new UnsupportedOperationException();
}
public Date getStartTime(final Long iid) throws ManagementException {
return dbexec(new BpelDatabase.Callable<Date>() {
public Date run(BpelDAOConnection session) throws Exception {
ProcessInstanceDAO instance = session.getInstance(iid);
if (instance == null)
throw new InstanceNotFoundException("InstanceNotFound:" + iid);
return instance.getCreateTime();
}
});
}
private CorrelationSetDAO findCorrelationSetDAO(ProcessInstanceDAO instance, Long scopeId, String correlationSet)
throws ManagementException {
ScopeDAO scope = instance.getScope(scopeId);
CorrelationSetDAO corr = null;
do {
corr = scope.getCorrelationSet(correlationSet);
if(corr != null)
break;
scope = scope.getParentScope();
} while(scope != null);
if(corr == null)
throw new ManagementException("CorrelationSetNotFound:" + correlationSet);
return corr;
}
private static String nodeToString(XmlDataDAO xml){
Node data = xml.get();
String str;
if (data == null) {
str = null;
} else if (data.getNodeType() == Node.ELEMENT_NODE) {
str = DOMUtils.domToString(data);
} else {
str = data.getNodeValue();
}
return str;
}
}