|
|||||||||||||||||||
| 30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover | |||||||||||||||||||
| Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
| Dispatcher.java | 100% | 90.9% | 80% | 90.9% |
|
||||||||||||||
| 1 |
/*
|
|
| 2 |
* $Id: Dispatcher.java,v 1.1 2004/12/15 14:18:10 patforna Exp $
|
|
| 3 |
*
|
|
| 4 |
* Copyright (c) 2004 Patric Fornasier, Pawel Kowalski
|
|
| 5 |
* Berne University of Applied Sciences
|
|
| 6 |
* School of Engineering and Information Technology
|
|
| 7 |
* All rights reserved.
|
|
| 8 |
*/
|
|
| 9 |
package bexee.core;
|
|
| 10 |
|
|
| 11 |
import org.apache.commons.logging.Log;
|
|
| 12 |
import org.apache.commons.logging.LogFactory;
|
|
| 13 |
|
|
| 14 |
import bexee.dao.BPELProcessDAO;
|
|
| 15 |
import bexee.dao.DAOException;
|
|
| 16 |
import bexee.dao.DAOFactory;
|
|
| 17 |
import bexee.model.process.BPELProcess;
|
|
| 18 |
|
|
| 19 |
/**
|
|
| 20 |
* This class is used to lookup or create a <code>ProcessInstance</code> given
|
|
| 21 |
* an inbound <code>BexeeMessage</code> and dispatch the message to the
|
|
| 22 |
* {@link bexee.core.ProcessController}either synchronously or asynchronoulsy.
|
|
| 23 |
* <p>
|
|
| 24 |
* To do this, create the object and then use its {@link #dispatch()}method.
|
|
| 25 |
* <p>
|
|
| 26 |
* When the <code>Dispatcher</code> kicks off the
|
|
| 27 |
* <code>ProcessController</code> it will know, whether a synchronous or
|
|
| 28 |
* asynchronous BPEL process is to be started. Depending on that it will either
|
|
| 29 |
* return right away after starting the process for an asynchronous BPEL process
|
|
| 30 |
* or it will wait until the result is available for a synchronous BPEL process.
|
|
| 31 |
* <p>
|
|
| 32 |
* Either way the <code>ProcessController</code>'s
|
|
| 33 |
* <code>processMessage()</code> method is started in a new Thread, but in
|
|
| 34 |
* case of a synchronous BPEL process the <code>Dispatcher</code> will wait
|
|
| 35 |
* until the result is available. This happens by obtaining a lock on the
|
|
| 36 |
* <code>ProcessContext</code>, which will notify the <code>Dispatcher</code>
|
|
| 37 |
* when the result is available.
|
|
| 38 |
*
|
|
| 39 |
* @version $Revision: 1.1 $, $Date: 2004/12/15 14:18:10 $
|
|
| 40 |
* @author Patric Fornasier
|
|
| 41 |
* @author Pawel Kowalski
|
|
| 42 |
*/
|
|
| 43 |
public class Dispatcher extends Thread { |
|
| 44 |
|
|
| 45 |
/**
|
|
| 46 |
* Result when processing an asynchronous result. This might change in
|
|
| 47 |
* future versions.
|
|
| 48 |
*/
|
|
| 49 |
public static final String ASYNC_RESULT = "Processing request..."; |
|
| 50 |
|
|
| 51 |
protected ProcessController controller;
|
|
| 52 |
|
|
| 53 |
protected ProcessInstance instance;
|
|
| 54 |
|
|
| 55 |
protected BexeeMessage message;
|
|
| 56 |
|
|
| 57 |
private static Log log = LogFactory.getLog(Dispatcher.class); |
|
| 58 |
|
|
| 59 |
/**
|
|
| 60 |
* Creates a new <code>Dispatcher</code> object.
|
|
| 61 |
*
|
|
| 62 |
* @param message
|
|
| 63 |
* the incoming message
|
|
| 64 |
*/
|
|
| 65 | 14 |
public Dispatcher(BexeeMessage message) {
|
| 66 | 14 |
this.message = message;
|
| 67 |
|
|
| 68 |
// get BPELProcess and ProcessContext for incoming message
|
|
| 69 | 14 |
BPELProcess process = getBPELProcess(message); |
| 70 | 14 |
ProcessContext ctx = getProcessContext(message); |
| 71 |
|
|
| 72 |
// create instance from BPELProcess and ProcessContext
|
|
| 73 | 14 |
instance = new ProcessInstance(process, ctx);
|
| 74 |
|
|
| 75 |
// create process controller
|
|
| 76 | 14 |
controller = ProcessControllerFactory.createProcessController(); |
| 77 |
} |
|
| 78 |
|
|
| 79 |
/**
|
|
| 80 |
* Calls the {@link ProcessController}s
|
|
| 81 |
* {@link ProcessController#processMessage(ProcessInstance, BexeeMessage)}
|
|
| 82 |
* method either synchronously or asynchronously.
|
|
| 83 |
* <p>
|
|
| 84 |
* Note that this method may take minutes or hours for long-running
|
|
| 85 |
* synchronous processes.
|
|
| 86 |
*
|
|
| 87 |
* @return the result
|
|
| 88 |
* @throws DispatcherException
|
|
| 89 |
* If something went wrong dispatching the message. This can
|
|
| 90 |
* happen for example if the <code>BPELProcess</code> or the
|
|
| 91 |
* <code>ProcessContext</code> can't be found or created or if
|
|
| 92 |
* something went wrong processing the message in the
|
|
| 93 |
* <code>ProcessController</code>.
|
|
| 94 |
*/
|
|
| 95 | 14 |
public Object dispatch() throws DispatcherException { |
| 96 |
|
|
| 97 | 14 |
Object result = null;
|
| 98 |
|
|
| 99 |
// get BPEL process and process context from process instance
|
|
| 100 | 14 |
ProcessContext ctx = instance.getContext(); |
| 101 | 14 |
BPELProcess process = instance.getProcess(); |
| 102 |
|
|
| 103 |
// check if a context was found or created
|
|
| 104 | 14 |
if (ctx == null) { |
| 105 | 4 |
throw new DispatcherException("No context found"); |
| 106 |
} |
|
| 107 |
|
|
| 108 |
// check if a process was found or created
|
|
| 109 | 10 |
if (process == null) { |
| 110 | 6 |
throw new DispatcherException("No process found"); |
| 111 |
} |
|
| 112 |
|
|
| 113 |
// start processing
|
|
| 114 | 4 |
start(); |
| 115 |
|
|
| 116 |
// if we have a synchronous process, wait until result is available
|
|
| 117 | 4 |
if (process.isSynchronous()) {
|
| 118 | 2 |
synchronized (ctx) {
|
| 119 | 2 |
try {
|
| 120 |
// wait until the process has finished and get the result
|
|
| 121 | 2 |
ctx.wait(); |
| 122 | 2 |
result = ctx.getResult(); |
| 123 |
} catch (InterruptedException e) {
|
|
| 124 | 0 |
throw new DispatcherException("Dispatcher interrupted", e); |
| 125 |
} |
|
| 126 |
} |
|
| 127 |
} else {
|
|
| 128 |
// TODO do we need to give something back here?
|
|
| 129 | 2 |
result = ASYNC_RESULT; |
| 130 |
} |
|
| 131 |
|
|
| 132 | 4 |
return result;
|
| 133 |
} |
|
| 134 |
|
|
| 135 |
/**
|
|
| 136 |
* Do not use this method directly. Use {@link #dispatch()}instead.
|
|
| 137 |
*/
|
|
| 138 | 0 |
public void run() { |
| 139 | 0 |
controller.processMessage(instance, message); |
| 140 |
} |
|
| 141 |
|
|
| 142 |
/**
|
|
| 143 |
* Gets the <code>ProcessContext</code> belonging to the incoming message.
|
|
| 144 |
*
|
|
| 145 |
* @param message
|
|
| 146 |
* the incoming message
|
|
| 147 |
* @return a new <code>ProcessContext</code> if there is currently no
|
|
| 148 |
* process running or the <code>ProcessContext</code> instance
|
|
| 149 |
* belonging to the incoming message if there is a process running
|
|
| 150 |
* already.
|
|
| 151 |
*/
|
|
| 152 | 6 |
protected ProcessContext getProcessContext(BexeeMessage message) {
|
| 153 |
|
|
| 154 | 6 |
ProcessContext ctx = null;
|
| 155 |
|
|
| 156 |
/*
|
|
| 157 |
* TODO Correlation stuff for finding a running process context. Right
|
|
| 158 |
* now this isn't supported, so we create a new instance each time.
|
|
| 159 |
*/
|
|
| 160 | 6 |
ctx = new ProcessContext();
|
| 161 |
|
|
| 162 | 6 |
return ctx;
|
| 163 |
} |
|
| 164 |
|
|
| 165 |
/**
|
|
| 166 |
* Gets the <code>BPELProcess</code> belonging to the incoming message.
|
|
| 167 |
*
|
|
| 168 |
* @param message
|
|
| 169 |
* the incoming message
|
|
| 170 |
* @return the <code>BPELProcess</code> that will be identified by the
|
|
| 171 |
* incoming message or null if it can't be found.
|
|
| 172 |
*/
|
|
| 173 | 6 |
protected BPELProcess getBPELProcess(BexeeMessage message) {
|
| 174 |
|
|
| 175 | 6 |
BPELProcess process = null;
|
| 176 | 6 |
String name = message.getService(); |
| 177 |
|
|
| 178 | 6 |
DAOFactory factory = DAOFactory.getInstance(); |
| 179 | 6 |
BPELProcessDAO bpelDAO = factory.createBPELProcessDAO(); |
| 180 |
|
|
| 181 | 6 |
try {
|
| 182 | 6 |
process = bpelDAO.find(name); |
| 183 |
} catch (DAOException e) {
|
|
| 184 | 0 |
log.info("Error trying to find process", e);
|
| 185 |
} |
|
| 186 |
|
|
| 187 | 6 |
return process;
|
| 188 |
} |
|
| 189 |
} |
|
||||||||||