package tud.st.bpel.history; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import tud.st.bpel.history.facts.BpelProcess; import tud.st.bpel.history.facts.InvokeFact; import tud.st.bpel.history.facts.ReadVariableFact; import tud.st.bpel.history.facts.StaticActivityFact; import tud.st.bpel.history.facts.StaticInvokeFact; import tud.st.bpel.history.facts.WriteVariableFact; import tud.st.bpel.prolog.BPELPrologEngine; import tud.st.bpel.prolog.IBPELPrologEngine; import tud.st.bpel.prolog.IStaticProcessFactGenerator; import tud.st.bpel.prolog.MalformedPolicyException; import tud.st.bpel.prolog.Policy; import tud.st.bpel.prolog.StaticProcessFactGenerator; /** * This listener connects the BPEL-Prolog-Engine to the * history framework. * * @author A. Look * */ public class BpelPrologHistoryListener implements BpelHistoryListener { // The engine IBPELPrologEngine engine = new BPELPrologEngine(true); protected final Log log = LogFactory.getLog(BpelPrologHistoryListener.class); // Remember violated policies for debugging private Vector<Policy> violatedPolicies = new Vector<Policy>(); // We need to disable policy checking for failed processes, // for fault handlers to work private Vector<Long> failedProcesses = new Vector<Long>(); public void beforeInvoke(Long pid, InvokeFact invoke, PolicyViolationHandler pvh) throws PolicyViolatedException { engine.addInvoke(pid+"", invoke.getXPath(), System.currentTimeMillis(), invoke.getParameters(), true); checkAllPolicies(pid, pvh, "Invoke will not be executed because a policy was violated!"); engine.addInvoke(pid+"", invoke.getXPath(), System.currentTimeMillis(), invoke.getParameters(), false); } public void afterInvokeOneWay(Long pid, InvokeFact invoke, PolicyViolationHandler pvh) throws PolicyViolatedException { engine.addEndInvoke(pid+"", invoke.getXPath(), System.currentTimeMillis(), null, true); checkAllPolicies(pid, pvh, "A policy was violated after one way invoke!"); engine.addEndInvoke(pid+"", invoke.getXPath(), System.currentTimeMillis(), null, false); } public void afterInvokeTwoWay(Long pid, InvokeFact invoke, PolicyViolationHandler pvh) throws PolicyViolatedException { engine.addEndInvoke(pid+"", invoke.getXPath(), System.currentTimeMillis(), invoke.getResponse(), true); checkAllPolicies(pid, pvh, "A policy was violated after two way invoke!"); engine.addEndInvoke(pid+"", invoke.getXPath(), System.currentTimeMillis(), invoke.getResponse(), false); } public void setVar(Long pid, WriteVariableFact writeVar, PolicyViolationHandler pvh) throws PolicyViolatedException { engine.addSetVar(pid+"", writeVar.getXPath(), System.currentTimeMillis(), writeVar.getVarName(), writeVar.getNewValue(), true); checkAllPolicies(pid, pvh, "Variable will not be set because a policy was violated: " + writeVar.getVarName() + " (XPath: " + writeVar.getXPath() + ")"); engine.addSetVar(pid+"", writeVar.getXPath(), System.currentTimeMillis(), writeVar.getVarName(), writeVar.getNewValue(), false); } public void getVar(Long pid, ReadVariableFact readVar, PolicyViolationHandler pvh) throws PolicyViolatedException { engine.addGetVar(pid+"", readVar.getXPath(), System.currentTimeMillis(), readVar.getVarName(), true); checkAllPolicies(pid, pvh, "A Policy was violated trying to read a variable: " + readVar.getVarName() + " (XPath: " + readVar.getXPath() + ")"); engine.addGetVar(pid+"", readVar.getXPath(), System.currentTimeMillis(), readVar.getXPath(), false); } public void registerProcess(BpelProcess process) { // get static facts from BpelProcess implementation IStaticProcessFactGenerator ps = new StaticProcessFactGenerator(process.getName()); for(StaticActivityFact act : process.getStaticActivityFacts()) { ps.addActivity(act.getXPath(), act.getParentXPath()); } for(StaticInvokeFact inv : process.getStaticInvokeFacts()) { ps.addInvoke(inv.getXPath(), inv.getParentXPath(), inv.getPartnerLink(), inv.getPortType(), inv.getOperation(), inv.getInputVar(), inv.getOutputVar()); } engine.addStaticProcessFacts(ps); } public void processStarted(Long pid, BpelProcess process, PolicyViolationHandler pvh) throws PolicyViolatedException { engine.addCreateProcessInstance(process.getName(), pid+"", System.currentTimeMillis(), true); checkAllPolicies(pid, pvh, "A policy was violated during process startup"); engine.addCreateProcessInstance(process.getName(), pid+"", System.currentTimeMillis(), false); } public void processEnded(Long pid, BpelProcess process, PolicyViolationHandler pvh) throws PolicyViolatedException { engine.addDestroyProcessInstance(pid+"", System.currentTimeMillis(), true); checkAllPolicies(pid, pvh, "A policy was violated during process shutdown"); engine.addDestroyProcessInstance(pid+"", System.currentTimeMillis(), false); // Debug output: engine.printFacts(); if(violatedPolicies.size() > 0) { System.out.println("Violated policies:"); for(Policy pol : violatedPolicies) { System.out.println(pol); } } else { System.out.println("No violated policies!"); } } public void addPolicy(String name, String faultName, String policy) { Policy pol = new Policy(name, faultName, policy); System.out.println("Adding policy: " + pol); engine.addPolicy(pol); // Only check for malformed policies! try { System.out.println("Checking for malformed policy"); engine.checkAllPolicies(); } catch (tud.st.bpel.prolog.PolicyViolatedException e) { // ignore! } catch (MalformedPolicyException e) { log.error(e.getMessage()); } } private void checkAllPolicies(Long pid, PolicyViolationHandler pvh, String reason) throws PolicyViolatedException { // check all policies try { // Allow fault handlers to be executed if(BpelHistory.getInstance().getAllowFaultHandlers() && failedProcesses.contains(pid)) log.debug("Ignoring policies for FAILED pid: " + pid); else engine.checkAllPolicies(pid); } catch(tud.st.bpel.prolog.PolicyViolatedException prologPVE) { // A policy was violated PolicyViolatedException pve = new PolicyViolatedException(prologPVE); Policy pol = pve.getPolicy(); violatedPolicies.add(pol); log.error("PolicyViolatedException: " + pol + " (" + reason + ")"); pve.setReason(reason); // Remeber failed processes so we can disable policy checking // for fault handlers failedProcesses.add(pid); pvh.handlePolicyViolation(pve); } catch(MalformedPolicyException mpe) { log.error("Malformed policy detected: " + mpe.getMalformedPolicy()); System.out.println("Malformed policy detected: " + mpe.getMalformedPolicy()); } } public boolean isPolicyViolated(Long pid) { return failedProcesses.contains(pid); } }