1
2
3
4
5
6
7
8
9 package bexee.admin;
10
11 import java.io.ByteArrayInputStream;
12 import java.io.InputStream;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Hashtable;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19
20 import javax.wsdl.Definition;
21 import javax.wsdl.Input;
22 import javax.wsdl.Operation;
23 import javax.wsdl.Output;
24 import javax.wsdl.Part;
25 import javax.wsdl.PortType;
26 import javax.wsdl.extensions.ExtensionRegistry;
27 import javax.wsdl.factory.WSDLFactory;
28 import javax.wsdl.xml.WSDLReader;
29 import javax.xml.namespace.QName;
30
31 import org.apache.axis.AxisEngine;
32 import org.apache.axis.AxisFault;
33 import org.apache.axis.ConfigurationException;
34 import org.apache.axis.EngineConfiguration;
35 import org.apache.axis.MessageContext;
36 import org.apache.axis.configuration.FileProvider;
37 import org.apache.axis.deployment.wsdd.WSDDConstants;
38 import org.apache.axis.deployment.wsdd.WSDDDeployment;
39 import org.apache.axis.deployment.wsdd.WSDDException;
40 import org.apache.axis.deployment.wsdd.WSDDOperation;
41 import org.apache.axis.deployment.wsdd.WSDDService;
42 import org.apache.axis.deployment.wsdd.WSDDUndeployment;
43 import org.apache.axis.description.OperationDesc;
44 import org.apache.axis.description.ParameterDesc;
45 import org.apache.axis.description.ServiceDesc;
46 import org.apache.axis.handlers.soap.SOAPService;
47 import org.apache.axis.utils.XMLUtils;
48 import org.apache.commons.logging.Log;
49 import org.apache.commons.logging.LogFactory;
50 import org.w3c.dom.Document;
51
52 import bexee.dao.BPELProcessDAO;
53 import bexee.dao.DAOException;
54 import bexee.dao.DAOFactory;
55 import bexee.model.BPELDocumentException;
56 import bexee.model.BPELProcessFactory;
57 import bexee.model.process.BPELProcess;
58 import bexee.wsdl.extensions.partnerlinktype.PartnerLinkTypeExtensionRegistry;
59
60 /***
61 * The <code>Manager</code> is used in bexee for deployment of BPEL business
62 * processes and the related WSLD descriptions.
63 *
64 * @version $Revision: 1.1 $, $Date: 2004/12/15 14:18:08 $
65 * @author Patric Fornasier
66 * @author Pawel Kowalski
67 */
68 public class Manager {
69
70 private static Log log = LogFactory.getLog(Manager.class);
71
72 /***
73 * Deploys a BPEL process to the bexee engine and registers it in Axis as a
74 * web service. This method performs the following operations in the given
75 * order:
76 * <p>
77 * <ol>
78 * <li>Checks the WSDL and BPEL namespaces</li>
79 * <li>Create a new <code>BPELProcess</code> with a
80 * <code>BPELProcessFactory</code></li>
81 * <li>Deploys a new web service to Axis under the name defined in the BPEL
82 * document</li>
83 * <li>Returns a <code>SOAPBodyElement</code> of the form
84 * <manager>result text</manager>
85 * </ol>
86 *
87 * @param input
88 * <code>elems[0]</code> must be an <code>Element</code>
89 * representing a BPEL document , while <code>elems[1]</code>
90 * must be an <code>Element</code> represent a BPEL document.
91 * elems[1..n] can be further additional WSDL documents.
92 *
93 * @return an <code>Element[]</code>, whose first element contains a
94 * message that the service was deployed.
95 */
96 public String deploy(String[] input) throws DeploymentException {
97
98 if (input == null || input.length < 2) {
99 throw new DeploymentException("at least two elems expected");
100 }
101
102
103 BPELProcess bpel = null;
104 Definition wsdl = null;
105 List partnerWSDL = new ArrayList();
106
107
108 AxisEngine axis = getAxisEngine();
109 WSDDDeployment deployment = getDeployment();
110
111 try {
112
113 bpel = createBPELProcess(input[0]);
114 } catch (BPELDocumentException e) {
115 throw new DeploymentException("Unable to create BPELProcess", e);
116 }
117
118 try {
119
120 WSDLReader wsdlReader = WSDLFactory.newInstance().newWSDLReader();
121
122
123 ExtensionRegistry reg = new PartnerLinkTypeExtensionRegistry();
124 wsdlReader.setExtensionRegistry(reg);
125 wsdlReader.setFeature("javax.wsdl.importDocuments", true);
126
127
128 InputStream is = new ByteArrayInputStream(input[1].getBytes());
129 Document doc = XMLUtils.newDocument(is);
130 wsdl = wsdlReader.readWSDL(null, doc);
131
132
133 for (int i = 2; i < input.length; i++) {
134 is = new ByteArrayInputStream(input[i].getBytes());
135 doc = XMLUtils.newDocument(is);
136 Definition definition = wsdlReader.readWSDL(null, doc);
137 partnerWSDL.add(definition);
138 }
139 } catch (Exception e) {
140 throw new DeploymentException("Unable to create Definition", e);
141 }
142
143
144 Collection portTypes = wsdl.getPortTypes().values();
145 String targetNS = wsdl.getTargetNamespace();
146 for (Iterator portIter = portTypes.iterator(); portIter.hasNext();) {
147 PortType portType = (PortType) portIter.next();
148
149
150 WSDDService service = new WSDDService();
151 ServiceDesc serviceDesc = service.getServiceDesc();
152
153
154
155
156
157
158
159 String name = bpel.getName();
160 service.setQName(new QName(name));
161 service.setName(name);
162 serviceDesc.setName(name);
163
164
165 service.setProviderQName(new QName(WSDDConstants.URI_WSDD_JAVA,
166 "BexeeProvider"));
167
168
169 Map nsMap = wsdl.getNamespaces();
170 serviceDesc.setNamespaceMappings(new ArrayList(nsMap.entrySet()));
171
172
173 List operations = portType.getOperations();
174 for (Iterator oIter = operations.iterator(); oIter.hasNext();) {
175 Operation operation = (Operation) oIter.next();
176
177 OperationDesc operationDesc = new OperationDesc();
178 operationDesc.setName(operation.getName());
179
180
181 Input in = operation.getInput();
182 Collection inParts = in.getMessage().getParts().values();
183 for (Iterator partIter = inParts.iterator(); partIter.hasNext();) {
184 Part part = (Part) partIter.next();
185 ParameterDesc paramDesc = new ParameterDesc();
186 paramDesc.setName(part.getName());
187
188 paramDesc.setQName(new QName(targetNS, part.getName()));
189
190 paramDesc.setTypeQName(part.getTypeName());
191 paramDesc.setMode(ParameterDesc.IN);
192
193 operationDesc.addParameter(paramDesc);
194 }
195
196
197 Output out = operation.getOutput();
198 Collection outParts = out.getMessage().getParts().values();
199 if (outParts.size() == 0) {
200 throw new DeploymentException(
201 "No message part defined for output in operation "
202 + operation.getName());
203 }
204 if (outParts.size() > 1) {
205 throw new DeploymentException(
206 "More than one message part defined for output in operation "
207 + operation.getName());
208 }
209
210
211
212
213
214
215
216 Part part = (Part) outParts.iterator().next();
217 operationDesc
218 .setReturnQName(new QName(targetNS, part.getName()));
219 operationDesc.setReturnType(part.getTypeName());
220
221 service.addOperation(new WSDDOperation(operationDesc));
222 }
223
224
225
226
227
228
229
230
231
232
233 service.setOptionsHashtable(new Hashtable());
234
235 try {
236
237 service.validateDescriptors();
238 } catch (WSDDException e) {
239 throw new DeploymentException("Invalid WSDD", e);
240 }
241
242
243
244 deployment.deployService(service);
245 }
246
247 try {
248
249 axis.refreshGlobalOptions();
250 } catch (ConfigurationException e) {
251 throw new DeploymentException("Unable to refresh Axis config", e);
252 }
253
254
255 bpel.setWSDL(wsdl);
256
257
258 bpel.addPartnerWSDL(partnerWSDL);
259
260
261 DAOFactory factory = DAOFactory.getInstance();
262 BPELProcessDAO dao = factory.createBPELProcessDAO();
263 String id;
264 try {
265 id = dao.replace(bpel);
266 } catch (DAOException e) {
267 throw new DeploymentException("Unable to insert/update process", e);
268 }
269
270 return "BPEL process succesfully updated, id: " + id;
271 }
272
273 public String undeploy(String name) throws DeploymentException {
274
275 String result = null;
276
277 AxisEngine axis = getAxisEngine();
278 WSDDDeployment deployment = getDeployment();
279
280 SOAPService service;
281 try {
282 service = axis.getService("TravelProcess");
283 } catch (AxisFault e) {
284 throw new DeploymentException("Unable to get service");
285 }
286
287
288 if (service == null) {
289 return "No such service found to undeploy, name: " + name;
290 }
291
292
293 WSDDUndeployment undeployment = new WSDDUndeployment();
294 undeployment.addService(new QName("", name));
295
296 try {
297
298 undeployment.undeployFromRegistry(deployment);
299 axis.refreshGlobalOptions();
300 } catch (ConfigurationException e) {
301 throw new DeploymentException("Unable to undeploy service '" + name
302 + "' from Axis");
303 }
304 try {
305
306
307 DAOFactory factory = DAOFactory.getInstance();
308 BPELProcessDAO dao = factory.createBPELProcessDAO();
309 dao.delete(name);
310
311 } catch (DAOException e) {
312 throw new DeploymentException("Unable to undeploy from bexee", e);
313 }
314
315 return "Service succesfully undeployed, name: " + name;
316 }
317
318 /***
319 * Get the WSDD Deployment from the Axis engine
320 */
321 private WSDDDeployment getDeployment() throws DeploymentException {
322
323 WSDDDeployment deployment = null;
324
325 AxisEngine axis = getAxisEngine();
326
327
328 EngineConfiguration config = axis.getConfig();
329
330
331
332
333
334
335 if (config instanceof FileProvider) {
336 deployment = ((FileProvider) config).getDeployment();
337 } else {
338 throw new DeploymentException("WSDDDeployment supported only!");
339 }
340 return deployment;
341 }
342
343 /***
344 * Get the Axis Engine
345 */
346 private AxisEngine getAxisEngine() {
347
348 MessageContext ctx = MessageContext.getCurrentContext();
349 AxisEngine axis = ctx.getAxisEngine();
350 return axis;
351 }
352
353 /***
354 * Create a new <code>BPELProcess</code> given a bpel xml document.
355 *
356 * @param bpel
357 * the bpel document tree
358 * @return a <code>BPELProcess</code>
359 * @throws BPELDocumentException
360 */
361 protected BPELProcess createBPELProcess(String bpel)
362 throws BPELDocumentException {
363
364 byte[] bytes = bpel.getBytes();
365 InputStream is = new ByteArrayInputStream(bytes);
366 return BPELProcessFactory.getInstance().createBPELProcess(is);
367 }
368 }