1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20
21 package org.apache.axis2.deployment;
22
23 import org.apache.axiom.om.OMElement;
24 import org.apache.axis2.AxisFault;
25 import org.apache.axis2.classloader.JarFileClassLoader;
26 import org.apache.axis2.Constants;
27 import org.apache.axis2.context.ConfigurationContext;
28 import org.apache.axis2.context.ServiceContext;
29 import org.apache.axis2.deployment.repository.util.ArchiveReader;
30 import org.apache.axis2.deployment.repository.util.DeploymentFileData;
31 import org.apache.axis2.deployment.repository.util.WSInfo;
32 import org.apache.axis2.deployment.resolver.AARBasedWSDLLocator;
33 import org.apache.axis2.deployment.resolver.AARFileBasedURIResolver;
34 import org.apache.axis2.deployment.scheduler.DeploymentIterator;
35 import org.apache.axis2.deployment.scheduler.Scheduler;
36 import org.apache.axis2.deployment.scheduler.SchedulerTask;
37 import org.apache.axis2.deployment.util.Utils;
38 import org.apache.axis2.description.AxisModule;
39 import org.apache.axis2.description.AxisOperation;
40 import org.apache.axis2.description.AxisService;
41 import org.apache.axis2.description.AxisServiceGroup;
42 import org.apache.axis2.description.Flow;
43 import org.apache.axis2.description.Parameter;
44 import org.apache.axis2.description.WSDL11ToAxisServiceBuilder;
45 import org.apache.axis2.description.WSDL2Constants;
46 import org.apache.axis2.engine.AxisConfiguration;
47 import org.apache.axis2.engine.MessageReceiver;
48 import org.apache.axis2.i18n.Messages;
49 import org.apache.axis2.util.JavaUtils;
50 import org.apache.commons.logging.Log;
51 import org.apache.commons.logging.LogFactory;
52
53 import javax.xml.namespace.QName;
54 import javax.xml.stream.XMLStreamException;
55 import java.io.BufferedReader;
56 import java.io.File;
57 import java.io.FileInputStream;
58 import java.io.FileOutputStream;
59 import java.io.IOException;
60 import java.io.InputStream;
61 import java.io.InputStreamReader;
62 import java.net.MalformedURLException;
63 import java.net.URL;
64 import java.util;
65 import java.util.zip.ZipEntry;
66 import java.util.zip.ZipInputStream;
67 import java.lang.reflect.Method;
68 import java.lang.reflect.InvocationTargetException;
69
70 public abstract class DeploymentEngine implements DeploymentConstants {
71 private static final Log log = LogFactory.getLog(DeploymentEngine.class);
72
73 //to keep the web resource location if any
74 protected static String webLocationString = null;
75 protected Scheduler scheduler;
76
77 public static void setWebLocationString(String webLocationString) {
78 DeploymentEngine.webLocationString = webLocationString;
79 }
80
81
82 /**
83 * Support for hot update is controlled by this flag
84 */
85 protected boolean hotUpdate = true;
86
87 /**
88 * Support for hot deployment is controlled by this flag
89 */
90 protected boolean hotDeployment = true;
91
92 /**
93 * Stores all the web Services to deploy.
94 */
95 protected List wsToDeploy = new ArrayList();
96
97 /**
98 * Stores all the web Services to undeploy.
99 */
100 protected List wsToUnDeploy = new ArrayList();
101
102 /**
103 * to keep a ref to engine register
104 * this ref will pass to engine when it call start()
105 * method
106 */
107 protected AxisConfiguration axisConfig;
108
109 protected ConfigurationContext configContext;
110
111 protected RepositoryListener repoListener;
112
113 protected String servicesPath = null;
114 protected File servicesDir = null;
115 protected String modulesPath = null;
116 protected File modulesDir = null;
117 private File repositoryDir = null;
118
119 //to deploy service (both aar and expanded)
120 protected ServiceDeployer serviceDeployer;
121 //To deploy modules (both mar and expanded)
122 protected ModuleDeployer moduleDeployer;
123
124 //to keep map of which deployer can process which file extension ,
125 // for example ServiceDeployer will process .aar file
126 private HashMap extensionToDeployerMappingMap = new HashMap();
127
128 private Map<String, Map<String, Deployer>> deployerMap = new HashMap<String, Map<String, Deployer>>();
129
130 public void loadServices() {
131 repoListener.checkServices();
132 if (hotDeployment) {
133 startSearch(repoListener);
134 }
135 }
136
137 public void loadRepository(String repoDir) throws DeploymentException {
138 File axisRepo = new File(repoDir);
139 if (!axisRepo.exists()) {
140 throw new DeploymentException(
141 Messages.getMessage("cannotfindrepo", repoDir));
142 }
143 setDeploymentFeatures();
144 prepareRepository(repoDir);
145 // setting the CLs
146 setClassLoaders(repoDir);
147 repoListener = new RepositoryListener(this, false);
148 org.apache.axis2.util.Utils
149 .calculateDefaultModuleVersion(axisConfig.getModules(), axisConfig);
150 try {
151 try {
152 axisConfig.setRepository(axisRepo.toURL());
153 } catch (MalformedURLException e) {
154 log.info(e.getMessage());
155 }
156 axisConfig.validateSystemPredefinedPhases();
157 } catch (AxisFault axisFault) {
158 throw new DeploymentException(axisFault);
159 }
160 }
161
162 public void loadFromClassPath() throws DeploymentException {
163 //loading modules from the classpath
164 new RepositoryListener(this, true);
165 org.apache.axis2.util.Utils.calculateDefaultModuleVersion(
166 axisConfig.getModules(), axisConfig);
167 axisConfig.validateSystemPredefinedPhases();
168 try {
169 engageModules();
170 } catch (AxisFault axisFault) {
171 log.info(Messages.getMessage(DeploymentErrorMsgs.MODULE_VALIDATION_FAILED,
172 axisFault.getMessage()));
173 throw new DeploymentException(axisFault);
174 }
175 }
176
177 private void loadCustomServices(URL repoURL){
178 for (Map.Entry<String, Map<String, Deployer>> entry : getDeployers().entrySet()) {
179 String directory = entry.getKey();
180 Map<String, Deployer> extensionMap = entry.getValue();
181 try {
182 String listName;
183 if (!directory.endsWith("/")) {
184 listName = directory + ".list";
185 directory += "/";
186 } else {
187 listName = directory.replaceAll("/","") + ".list";
188 }
189 String repoPath = repoURL.getPath();
190 if (!repoPath.endsWith("/")) {
191 repoPath += "/";
192 repoURL = new URL(repoURL.getProtocol() + "://" + repoPath);
193 }
194
195 URL servicesDir = new URL(repoURL, directory);
196 URL filelisturl = new URL(servicesDir, listName);
197 ArrayList files = getFileList(filelisturl);
198 for (int i = 0; i < files.size(); i++) {
199 String fileName = (String) files.get(i);
200 String extension = getExtension(fileName);
201 Deployer deployer = extensionMap.get(extension);
202 if (deployer == null) {
203 continue;
204 }
205 URL servicesURL = new URL(servicesDir, fileName);
206
207 // We are calling reflection code here , to avoid changes to the interface
208 Class classToLoad = deployer.getClass();
209 // We can not call classToLoad.getDeclaredMethed() , since there
210 // can be insatnce where mutiple services extends using one class
211 // just for init and other reflection methods
212 Method method = null;
213 try {
214 method = classToLoad.getMethod("deployFromURL", new Class[]{URL.class});
215 } catch (Exception e) {
216 //We do not need to inform this to user , since this something
217 // Axis2 is checking to support Session. So if the method is
218 // not there we should ignore that
219 }
220 if (method != null) {
221 try {
222 method.invoke(deployer, new Object[]{servicesURL});
223 } catch (Exception e) {
224 log.info("Exception trying to call " + "deployFromURL for the deployer" + deployer.getClass() , e);
225 }
226 }
227 }
228
229 } catch (MalformedURLException e) {
230 //I am just ignoring the error at the moment , but need to think how to handle this
231 }
232
233 }
234 }
235
236 private String getExtension(String fileName){
237 int lastIndex = fileName.lastIndexOf(".");
238 return fileName.substring(lastIndex +1);
239 }
240
241 public void loadServicesFromUrl(URL repoURL) {
242 try {
243 String path = servicesPath == null ? DeploymentConstants.SERVICE_PATH : servicesPath;
244 if (!path.endsWith("/")) {
245 path += "/";
246 }
247 String repoPath = repoURL.getPath();
248 if (!repoPath.endsWith("/")) {
249 repoPath += "/";
250 repoURL = new URL(repoURL.getProtocol() + "://" + repoPath);
251 }
252 URL servicesDir = new URL(repoURL, path);
253 URL filelisturl = new URL(servicesDir, "services.list");
254 ArrayList files = getFileList(filelisturl);
255
256 for (Iterator fileIterator = files.iterator();
257 fileIterator.hasNext();) {
258 String fileUrl = (String) fileIterator.next();
259 if (fileUrl.endsWith(".aar")) {
260 AxisServiceGroup serviceGroup = new AxisServiceGroup();
261 URL servicesURL = new URL(servicesDir, fileUrl);
262 ArrayList servicelist =
263 populateService(serviceGroup,
264 servicesURL,
265 fileUrl.substring(0, fileUrl.indexOf(".aar")));
266 addServiceGroup(serviceGroup, servicelist, servicesURL, null, axisConfig);
267 log.info(Messages.getMessage(DeploymentErrorMsgs.DEPLOYING_WS,
268 org.apache.axis2.util.Utils.getModuleName(serviceGroup.getServiceGroupName()),
269 servicesURL.toString()));
270 }
271 }
272 //Loading other type of services such as custom deployers
273 loadCustomServices(repoURL);
274 } catch (MalformedURLException e) {
275 log.error(e.getMessage(), e);
276 } catch (IOException e) {
277 log.error(e.getMessage(), e);
278 }
279 }
280
281 public void loadRepositoryFromURL(URL repoURL) throws DeploymentException {
282 try {
283 String path = modulesPath == null ? DeploymentConstants.MODULE_PATH : modulesPath;
284 if (!path.endsWith("/")) {
285 path = path + "/";
286 }
287 String repoPath = repoURL.getPath();
288 if (!repoPath.endsWith("/")) {
289 repoPath += "/";
290 repoURL = new URL(repoURL.getProtocol() + "://" + repoPath);
291 }
292 URL moduleDir = new URL(repoURL, path);
293 URL filelisturl = new URL(moduleDir, "modules.list");
294 ArrayList files = getFileList(filelisturl);
295 Iterator fileIterator = files.iterator();
296 while (fileIterator.hasNext()) {
297 String fileUrl = (String) fileIterator.next();
298 if (fileUrl.endsWith(".mar")) {
299 URL moduleurl = new URL(moduleDir, fileUrl);
300 ClassLoader deploymentClassLoader =
301 Utils.createClassLoader(
302 new URL[]{moduleurl},
303 axisConfig.getModuleClassLoader(),
304 true,
305 (File) axisConfig.getParameterValue(Constants.Configuration.ARTIFACTS_TEMP_DIR));
306 AxisModule module = new AxisModule();
307 module.setModuleClassLoader(deploymentClassLoader);
308 module.setParent(axisConfig);
309 String moduleFile = fileUrl.substring(0, fileUrl.indexOf(".mar"));
310 if (module.getName() == null) {
311 module.setName(org.apache.axis2.util.Utils.getModuleName(moduleFile));
312 module.setVersion(org.apache.axis2.util.Utils.getModuleVersion(moduleFile));
313 }
314 populateModule(module, moduleurl);
315 module.setFileName(moduleurl);
316 addNewModule(module, axisConfig);
317 log.info(Messages.getMessage(DeploymentErrorMsgs.DEPLOYING_MODULE,
318 org.apache.axis2.util.Utils.getModuleName(module.getName(),
319 module.getVersion()),
320 moduleurl.toString()));
321 }
322 }
323 org.apache.axis2.util.Utils.
324 calculateDefaultModuleVersion(axisConfig.getModules(), axisConfig);
325 axisConfig.validateSystemPredefinedPhases();
326 } catch (MalformedURLException e) {
327 throw new DeploymentException(e);
328 } catch (IOException e) {
329 throw new DeploymentException(e);
330 }
331 }
332
333 private void populateModule(AxisModule module, URL moduleUrl) throws DeploymentException {
334 try {
335 ClassLoader classLoader = module.getModuleClassLoader();
336 InputStream moduleStream = classLoader.getResourceAsStream("META-INF/module.xml");
337 if (moduleStream == null) {
338 moduleStream = classLoader.getResourceAsStream("meta-inf/module.xml");
339 }
340 if (moduleStream == null) {
341 throw new DeploymentException(
342 Messages.getMessage(
343 DeploymentErrorMsgs.MODULE_XML_MISSING, moduleUrl.toString()));
344 }
345 ModuleBuilder moduleBuilder = new ModuleBuilder(moduleStream, module, axisConfig);
346 moduleBuilder.populateModule();
347 } catch (IOException e) {
348 throw new DeploymentException(e);
349 }
350 }
351
352 protected ArrayList populateService(AxisServiceGroup serviceGroup,
353 URL servicesURL,
354 String serviceName) throws DeploymentException {
355 try {
356 serviceGroup.setServiceGroupName(serviceName);
357 ClassLoader serviceClassLoader = Utils.createClassLoader(
358 new URL[]{servicesURL},
359 axisConfig.getServiceClassLoader(),
360 true,
361 (File) axisConfig.getParameterValue(Constants.Configuration.ARTIFACTS_TEMP_DIR));
362 String metainf = "meta-inf";
363 serviceGroup.setServiceGroupClassLoader(serviceClassLoader);
364 //processing wsdl.list
365 InputStream wsdlfilesStream =
366 serviceClassLoader.getResourceAsStream("meta-inf/wsdl.list");
367 if (wsdlfilesStream == null) {
368 wsdlfilesStream = serviceClassLoader.getResourceAsStream("META-INF/wsdl.list");
369 if (wsdlfilesStream != null) {
370 metainf = "META-INF";
371 }
372 }
373 HashMap servicesMap = new HashMap();
374 if (wsdlfilesStream != null) {
375 ArchiveReader reader = new ArchiveReader();
376 BufferedReader input = new BufferedReader(new InputStreamReader(wsdlfilesStream));
377 String line;
378 while ((line = input.readLine()) != null) {
379 line = line.trim();
380 if (line.length() > 0 && line.charAt(0)!='#') {
381 line = metainf + "/" + line;
382 try {
383 List services = reader.getAxisServiceFromWsdl(
384 serviceClassLoader.getResourceAsStream(line),
385 serviceClassLoader, line);
386 if (services != null) {
387 for (int i = 0; i < services.size(); i++) {
388 AxisService axisService = (AxisService) services.get(i);
389 servicesMap.put(axisService.getName(), axisService);
390 }
391 }
392
393 } catch (Exception e) {
394 throw new DeploymentException(e);
395 }
396 }
397 }
398 }
399 InputStream servicexmlStream =
400 serviceClassLoader.getResourceAsStream("META-INF/services.xml");
401 if (servicexmlStream == null) {
402 servicexmlStream = serviceClassLoader.getResourceAsStream("meta-inf/services.xml");
403 } else {
404 metainf = "META-INF";
405 }
406 if (servicexmlStream == null) {
407 throw new DeploymentException(
408 Messages.getMessage(DeploymentErrorMsgs.SERVICE_XML_NOT_FOUND,
409 servicesURL.toString()));
410 }
411 DescriptionBuilder builder = new DescriptionBuilder(servicexmlStream, configContext);
412 OMElement rootElement = builder.buildOM();
413 String elementName = rootElement.getLocalName();
414
415 if (TAG_SERVICE.equals(elementName)) {
416 AxisService axisService = null;
417 String wsdlLocation = "META-INF/service.wsdl";
418 InputStream wsdlStream =
419 serviceClassLoader.getResourceAsStream(wsdlLocation);
420 URL wsdlURL = serviceClassLoader.getResource(metainf + "/service.wsdl");
421 if (wsdlStream == null) {
422 wsdlLocation = "META-INF/" + serviceName + ".wsdl";
423 wsdlStream = serviceClassLoader
424 .getResourceAsStream(wsdlLocation);
425 wsdlURL = serviceClassLoader.getResource(wsdlLocation);
426 }
427 if (wsdlStream != null) {
428 WSDL11ToAxisServiceBuilder wsdl2AxisServiceBuilder =
429 new WSDL11ToAxisServiceBuilder(wsdlStream, null, null);
430 File file = Utils.toFile(servicesURL);
431 if(file != null && file.exists()){
432 wsdl2AxisServiceBuilder.setCustomWSLD4JResolver(
433 new AARBasedWSDLLocator(wsdlLocation, file, wsdlStream));
434 wsdl2AxisServiceBuilder.setCustomResolver(
435 new AARFileBasedURIResolver(file));
436 }
437 if (wsdlURL != null) {
438 wsdl2AxisServiceBuilder.setDocumentBaseUri(wsdlURL.toString());
439 }
440 axisService = wsdl2AxisServiceBuilder.populateService();
441 axisService.setWsdlFound(true);
442 axisService.setCustomWsdl(true);
443 axisService.setName(serviceName);
444 }
445 if (axisService == null) {
446 axisService = new AxisService(serviceName);
447 }
448
449 axisService.setParent(serviceGroup);
450 axisService.setClassLoader(serviceClassLoader);
451
452 ServiceBuilder serviceBuilder = new ServiceBuilder(configContext, axisService);
453 AxisService service = serviceBuilder.populateService(rootElement);
454
455 ArrayList serviceList = new ArrayList();
456 serviceList.add(service);
457 return serviceList;
458 } else if (TAG_SERVICE_GROUP.equals(elementName)) {
459 ServiceGroupBuilder groupBuilder = new ServiceGroupBuilder(rootElement, servicesMap,
460 configContext);
461 ArrayList servicList = groupBuilder.populateServiceGroup(serviceGroup);
462 Iterator serviceIterator = servicList.iterator();
463 while (serviceIterator.hasNext()) {
464 AxisService axisService = (AxisService) serviceIterator.next();
465 String wsdlLocation = "META-INF/service.wsdl";
466 InputStream wsdlStream =
467 serviceClassLoader.getResourceAsStream(wsdlLocation);
468 URL wsdlURL = serviceClassLoader.getResource(wsdlLocation);
469 if (wsdlStream == null) {
470 wsdlLocation = "META-INF/" + serviceName + ".wsdl";
471 wsdlStream = serviceClassLoader
472 .getResourceAsStream(wsdlLocation);
473 wsdlURL =
474 serviceClassLoader.getResource(wsdlLocation);
475 }
476 if (wsdlStream != null) {
477 WSDL11ToAxisServiceBuilder wsdl2AxisServiceBuilder =
478 new WSDL11ToAxisServiceBuilder(wsdlStream, axisService);
479 File file = Utils.toFile(servicesURL);
480 if(file != null && file.exists()){
481 wsdl2AxisServiceBuilder.setCustomWSLD4JResolver(
482 new AARBasedWSDLLocator(wsdlLocation, file, wsdlStream));
483 wsdl2AxisServiceBuilder.setCustomResolver(
484 new AARFileBasedURIResolver(file));
485 }
486 if (wsdlURL != null) {
487 wsdl2AxisServiceBuilder.setDocumentBaseUri(wsdlURL.toString());
488 }
489 axisService = wsdl2AxisServiceBuilder.populateService();
490 axisService.setWsdlFound(true);
491 axisService.setCustomWsdl(true);
492 // Set the default message receiver for the operations that were
493 // not listed in the services.xml
494 Iterator operations = axisService.getOperations();
495 while (operations.hasNext()) {
496 AxisOperation operation = (AxisOperation) operations.next();
497 if (operation.getMessageReceiver() == null) {
498 operation.setMessageReceiver(loadDefaultMessageReceiver(
499 operation.getMessageExchangePattern(), axisService));
500 }
501 }
502 }
503 }
504 return servicList;
505 }
506 } catch (IOException e) {
507 throw new DeploymentException(e);
508 } catch (XMLStreamException e) {
509 throw new DeploymentException(e);
510 }
511 return null;
512 }
513
514 protected MessageReceiver loadDefaultMessageReceiver(String mepURL, AxisService service) {
515 MessageReceiver messageReceiver;
516 if (mepURL == null) {
517 mepURL = WSDL2Constants.MEP_URI_IN_OUT;
518 }
519 if (service != null) {
520 messageReceiver = service.getMessageReceiver(mepURL);
521 if (messageReceiver != null) {
522 return messageReceiver;
523 }
524 }
525 return axisConfig.getMessageReceiver(mepURL);
526 }
527
528 public static void addNewModule(AxisModule modulemetadata,
529 AxisConfiguration axisConfiguration) throws AxisFault {
530
531 Flow inflow = modulemetadata.getInFlow();
532 ClassLoader moduleClassLoader = modulemetadata.getModuleClassLoader();
533
534 if (inflow != null) {
535 Utils.addFlowHandlers(inflow, moduleClassLoader);
536 }
537
538 Flow outFlow = modulemetadata.getOutFlow();
539
540 if (outFlow != null) {
541 Utils.addFlowHandlers(outFlow, moduleClassLoader);
542 }
543
544 Flow faultInFlow = modulemetadata.getFaultInFlow();
545
546 if (faultInFlow != null) {
547 Utils.addFlowHandlers(faultInFlow, moduleClassLoader);
548 }
549
550 Flow faultOutFlow = modulemetadata.getFaultOutFlow();
551
552 if (faultOutFlow != null) {
553 Utils.addFlowHandlers(faultOutFlow, moduleClassLoader);
554 }
555
556 axisConfiguration.addModule(modulemetadata);
557 log.debug(Messages.getMessage(DeploymentErrorMsgs.ADDING_NEW_MODULE));
558 }
559
560 public static void addServiceGroup(AxisServiceGroup serviceGroup,
561 ArrayList serviceList,
562 URL serviceLocation,
563 DeploymentFileData currentDeploymentFile,
564 AxisConfiguration axisConfiguration) throws AxisFault {
565 fillServiceGroup(serviceGroup, serviceList, serviceLocation, axisConfiguration);
566 axisConfiguration.addServiceGroup(serviceGroup);
567 if (currentDeploymentFile != null) {
568 addAsWebResources(currentDeploymentFile.getFile(),
569 serviceGroup.getServiceGroupName(), serviceGroup);
570 }
571 }
572
573 protected static void fillServiceGroup(AxisServiceGroup serviceGroup,
574 ArrayList serviceList,
575 URL serviceLocation,
576 AxisConfiguration axisConfig) throws AxisFault {
577 // serviceGroup.setParent(axisConfig);
578 // module from services.xml at serviceGroup level
579 ArrayList groupModules = serviceGroup.getModuleRefs();
580 serviceGroup.setParent(axisConfig);
581 for (int i = 0; i < groupModules.size(); i++) {
582 String moduleName = (String) groupModules.get(i);
583 AxisModule module = axisConfig.getModule(moduleName);
584
585 if (module != null) {
586 serviceGroup.engageModule(axisConfig.getModule(moduleName));
587 } else {
588 throw new DeploymentException(
589 Messages.getMessage(
590 DeploymentErrorMsgs.BAD_MODULE_FROM_SERVICE,
591 serviceGroup.getServiceGroupName(), moduleName));
592 }
593 }
594
595 Iterator services = serviceList.iterator();
596
597 while (services.hasNext()) {
598 AxisService axisService = (AxisService) services.next();
599 axisService.setUseDefaultChains(false);
600
601 axisService.setFileName(serviceLocation);
602 serviceGroup.addService(axisService);
603
604 // modules from <service>
605 ArrayList list = axisService.getModules();
606
607 for (int i = 0; i < list.size(); i++) {
608 AxisModule module = axisConfig.getModule((String) list.get(i));
609
610 if (module == null) {
611 throw new DeploymentException(
612 Messages.getMessage(
613 DeploymentErrorMsgs.BAD_MODULE_FROM_SERVICE,
614 axisService.getName(),
615 ((QName) list.get(i)).getLocalPart()));
616 }
617
618 axisService.engageModule(module);
619 }
620
621 for (Iterator iterator = axisService.getOperations(); iterator.hasNext();) {
622 AxisOperation opDesc = (AxisOperation) iterator.next();
623 ArrayList modules = opDesc.getModuleRefs();
624
625 for (int i = 0; i < modules.size(); i++) {
626 String moduleName = (String) modules.get(i);
627 AxisModule module = axisConfig.getModule(moduleName);
628
629 if (module != null) {
630 opDesc.engageModule(module);
631 } else {
632 throw new DeploymentException(
633 Messages.getMessage(
634 DeploymentErrorMsgs.BAD_MODULE_FROM_OPERATION,
635 opDesc.getName().getLocalPart(),
636 moduleName));
637 }
638 }
639 }
640 }
641 }
642
643 /**
644 * @param file ArchiveFileData
645 */
646 public void addWSToDeploy(DeploymentFileData file) {
647 wsToDeploy.add(file);
648 }
649
650 /**
651 * @param file WSInfo
652 */
653 public void addWSToUndeploy(WSInfo file) {
654 wsToUnDeploy.add(file);
655 }
656
657 public void doDeploy() {
658 try {
659 if (wsToDeploy.size() > 0) {
660 for (int i = 0; i < wsToDeploy.size(); i++) {
661 DeploymentFileData fileToDeploy = (DeploymentFileData) wsToDeploy.get(i);
662 try {
663 fileToDeploy.deploy();
664 } catch (DeploymentException e) {
665 // TODO : This probably isn't sufficient. Maybe provide an option to stop?
666 log.info(e);
667 }
668 }
669 }
670 } finally {
671 wsToDeploy.clear();
672 }
673 }
674
675 /**
676 * Checks if the modules, referred by server.xml, exist or that they are deployed.
677 *
678 * @throws org.apache.axis2.AxisFault : If smt goes wrong
679 */
680 public void engageModules() throws AxisFault {
681 axisConfig.engageGlobalModules();
682 }
683
684 /**
685 * To get AxisConfiguration for a given inputStream this method can be used.
686 * The inputstream should be a valid axis2.xml , else you will be getting
687 * DeploymentExceptions.
688 * <p/>
689 * First creat a AxisConfiguration using given inputSream , and then it will
690 * try to find the repository location parameter from AxisConfiguration, so
691 * if user has add a parameter with the name "repository" , then the value
692 * specified by that parameter will be the repository and system will try to
693 * load modules and services from that repository location if it a valid
694 * location. hot deployment and hot update will work as usual in this case.
695 * <p/>
696 * You will be getting AxisConfiguration corresponding to given inputstream
697 * if it is valid , if something goes wrong you will be getting
698 * DeploymentException
699 *
700 * @param in : InputStream to axis2.xml
701 * @return a populated AxisConfiguration
702 * @throws DeploymentException : If something goes wrong
703 */
704 public AxisConfiguration populateAxisConfiguration(InputStream in) throws DeploymentException {
705 axisConfig = new AxisConfiguration();
706 AxisConfigBuilder builder = new AxisConfigBuilder(in, axisConfig, this);
707 builder.populateConfig();
708 try {
709 if (in != null) {
710 in.close();
711 }
712 } catch (IOException e) {
713 log.info("error in closing input stream");
714 }
715 moduleDeployer = new ModuleDeployer(axisConfig);
716 return axisConfig;
717 }
718
719 /**
720 * Starts the Deployment engine to perform Hot deployment and so on.
721 *
722 * @param listener : RepositoryListener
723 */
724 protected void startSearch(RepositoryListener listener) {
725 scheduler = new Scheduler();
726
727 scheduler.schedule(new SchedulerTask(listener), new DeploymentIterator());
728 }
729
730 public void unDeploy() {
731 try {
732 if (wsToUnDeploy.size() > 0) {
733 for (int i = 0; i < wsToUnDeploy.size(); i++) {
734 WSInfo wsInfo = (WSInfo) wsToUnDeploy.get(i);
735 if (wsInfo.getType() == WSInfo.TYPE_SERVICE) {
736 //No matter what we need to undeploy the service
737 // if user has deleted the file from the repository
738 serviceDeployer.unDeploy(wsInfo.getFileName());
739 } else {
740 //We need to undeploy the service whether we have enable hotUpdate or not ,
741 // o.w what happen if someone delete the service from the repo
742 Deployer deployer = wsInfo.getDeployer();
743 if (deployer != null) {
744 deployer.unDeploy(wsInfo.getFileName());
745 }
746 }
747 }
748 }
749 } catch (Exception e) {
750 log.info(e);
751 }
752 wsToUnDeploy.clear();
753 }
754
755 /**
756 * Gets AxisConfiguration.
757 *
758 * @return AxisConfiguration <code>AxisConfiguration</code>
759 */
760 public AxisConfiguration getAxisConfig() {
761 return axisConfig;
762 }
763
764 /**
765 * Retrieves service name from the archive file name.
766 * If the archive file name is service1.aar , then axis2 service name would be service1
767 *
768 * @param fileName the archive file name
769 * @return Returns String.
770 */
771 public static String getAxisServiceName(String fileName) {
772 char seperator = '.';
773 String value;
774 int index = fileName.lastIndexOf(seperator);
775
776 if (index > 0) {
777 value = fileName.substring(0, index);
778
779 return value;
780 }
781
782 return fileName;
783 }
784
785 public AxisModule getModule(String moduleName) throws AxisFault {
786 return axisConfig.getModule(moduleName);
787 }
788
789 public boolean isHotUpdate() {
790 return hotUpdate;
791 }
792
793 private static void addAsWebResources(File in,
794 String serviceFileName,
795 AxisServiceGroup serviceGroup) {
796 try {
797 if (webLocationString == null) {
798 return;
799 }
800 if (in.isDirectory()) {
801 return;
802 }
803 File webLocation = new File(webLocationString);
804 File out = new File(webLocation, serviceFileName);
805 int BUFFER = 1024;
806 byte data[] = new byte[BUFFER];
807 FileInputStream fin = new FileInputStream(in);
808 ZipInputStream zin = new ZipInputStream(
809 fin);
810 ZipEntry entry;
811 while ((entry = zin.getNextEntry()) != null) {
812 ZipEntry zip = new ZipEntry(entry);
813 if (zip.getName().toUpperCase().startsWith("WWW")) {
814 String fileName = zip.getName();
815 fileName = fileName.substring("WWW/".length(),
816 fileName.length());
817 if (zip.isDirectory()) {
818 new File(out, fileName).mkdirs();
819 } else {
820 FileOutputStream tempOut = new FileOutputStream(new File(out, fileName));
821 int count;
822 while ((count = zin.read(data, 0, BUFFER)) != -1) {
823 tempOut.write(data, 0, count);
824 }
825 tempOut.close();
826 tempOut.flush();
827 }
828 serviceGroup.setFoundWebResources(true);
829 }
830 }
831 zin.close();
832 fin.close();
833 } catch (IOException e) {
834 log.info(e.getMessage());
835 }
836 }
837
838 public static String getWebLocationString() {
839 return webLocationString;
840 }
841
842 /**
843 * To set the all the classLoader hierarchy this method can be used , the top most parent is
844 * CCL then SCL(system Class Loader)
845 * CCL
846 * :
847 * SCL
848 * : :
849 * MCCL SCCL
850 * : :
851 * MCL SCL
852 * <p/>
853 * <p/>
854 * MCCL : module common class loader
855 * SCCL : Service common class loader
856 * MCL : module class loader
857 * SCL : Service class loader
858 *
859 * @param axis2repoURI : The repository folder of Axis2
860 * @throws DeploymentException if there's a problem
861 */
862 protected void setClassLoaders(String axis2repoURI) throws DeploymentException {
863 ClassLoader sysClassLoader =
864 Utils.getClassLoader(Thread.currentThread().getContextClassLoader(), axis2repoURI);
865
866 axisConfig.setSystemClassLoader(sysClassLoader);
867 if (servicesDir.exists()) {
868 axisConfig.setServiceClassLoader(
869 Utils.getClassLoader(axisConfig.getSystemClassLoader(), servicesDir));
870 } else {
871 axisConfig.setServiceClassLoader(axisConfig.getSystemClassLoader());
872 }
873
874 if (modulesDir.exists()) {
875 axisConfig.setModuleClassLoader(Utils.getClassLoader(axisConfig.getSystemClassLoader(),
876 modulesDir));
877 } else {
878 axisConfig.setModuleClassLoader(axisConfig.getSystemClassLoader());
879 }
880 }
881
882 /**
883 * Sets hotDeployment and hot update.
884 */
885 protected void setDeploymentFeatures() {
886 Parameter hotDeployment = axisConfig.getParameter(TAG_HOT_DEPLOYMENT);
887 Parameter hotUpdate = axisConfig.getParameter(TAG_HOT_UPDATE);
888
889 if (hotDeployment != null) {
890 this.hotDeployment = JavaUtils.isTrue(hotDeployment.getValue(), true);
891 }
892
893 if (hotUpdate != null) {
894 this.hotUpdate = JavaUtils.isTrue(hotUpdate.getValue(), true);
895 }
896
897 String serviceDirPara = (String)
898 axisConfig.getParameterValue(DeploymentConstants.SERVICE_DIR_PATH);
899 if (serviceDirPara != null) {
900 servicesPath = serviceDirPara;
901 }
902
903 String moduleDirPara = (String)
904 axisConfig.getParameterValue(DeploymentConstants.MODULE_DRI_PATH);
905 if (moduleDirPara != null) {
906 modulesPath = moduleDirPara;
907 }
908 }
909
910 /**
911 * Creates directories for modules/services, copies configuration xml from class loader if necessary
912 *
913 * @param repositoryName the pathname of the repository
914 */
915
916 protected void prepareRepository(String repositoryName) {
917 repositoryDir = new File(repositoryName);
918 if (servicesPath != null) {
919 servicesDir = new File(servicesPath);
920 if (!servicesDir.exists()) {
921 servicesDir = new File(repositoryDir, servicesPath);
922 }
923 } else {
924 servicesDir = new File(repositoryDir, DeploymentConstants.SERVICE_PATH);
925 }
926 if (!servicesDir.exists()) {
927 log.info(Messages.getMessage("noservicedirfound", getRepositoryPath(repositoryDir)));
928 }
929 if (modulesPath != null) {
930 modulesDir = new File(modulesPath);
931 if (!modulesDir.exists()) {
932 modulesDir = new File(repositoryDir, modulesPath);
933 }
934 } else {
935 modulesDir = new File(repositoryDir, DeploymentConstants.MODULE_PATH);
936 }
937 if (!modulesDir.exists()) {
938 log.info(Messages.getMessage("nomoduledirfound", getRepositoryPath(repositoryDir)));
939 }
940 }
941
942 protected String getRepositoryPath(File repository) {
943 try {
944 return repository.getCanonicalPath();
945 } catch (IOException e) {
946 return repository.getAbsolutePath();
947 }
948 }
949
950 protected ArrayList getFileList(URL fileListUrl) {
951 ArrayList fileList = new ArrayList();
952 InputStream in;
953 try {
954 in = fileListUrl.openStream();
955 } catch (IOException e) {
956 return fileList;
957 }
958 BufferedReader input = null;
959 try {
960 input = new BufferedReader(new InputStreamReader(in));
961 String line;
962 while ((line = input.readLine()) != null) {
963 line = line.trim();
964 if (line.length() > 0 && line.charAt(0)!='#') {
965 fileList.add(line);
966 }
967 }
968 } catch (IOException ex) {
969 ex.printStackTrace();
970 } finally {
971 try {
972 if (input != null) {
973 input.close();
974 }
975 }
976 catch (IOException ex) {
977 ex.printStackTrace();
978 }
979 }
980 return fileList;
981 }
982
983 public void setConfigContext(ConfigurationContext configContext) {
984 this.configContext = configContext;
985 initializeDeployers(this.configContext);
986 }
987
988 private void initializeDeployers(ConfigurationContext configContext) {
989 serviceDeployer = new ServiceDeployer();
990 serviceDeployer.init(configContext);
991 for (Map<String, Deployer> extensionMap : deployerMap.values()) {
992 for (Deployer deployer : extensionMap.values()) {
993 deployer.init(configContext);
994 }
995 }
996 }
997
998 /**
999 * Builds an AxisModule for a given module archive file. This does not
1000 * called the init method since there is no reference to configuration context
1001 * so who ever create module using this has to called module.init if it is
1002 * required
1003 *
1004 * @param modulearchive : Actual module archive file
1005 * @param config : AxisConfiguration : for get classloaders etc..
1006 * @return a complete AxisModule read from the file.
1007 * @throws org.apache.axis2.deployment.DeploymentException
1008 * if there's a problem
1009 */
1010 public static AxisModule buildModule(File modulearchive,
1011 AxisConfiguration config)
1012 throws DeploymentException {
1013 final String MODULE_DEPLOYER = "moduleDeployer";
1014 AxisModule axismodule;
1015 ModuleDeployer deployer = (ModuleDeployer) config.getParameterValue(MODULE_DEPLOYER);
1016 try {
1017 if (deployer == null) {
1018 deployer = new ModuleDeployer(config);
1019 config.addParameter(MODULE_DEPLOYER, deployer);
1020 }
1021
1022 DeploymentFileData currentDeploymentFile = new DeploymentFileData(modulearchive,
1023 deployer);
1024 axismodule = new AxisModule();
1025 ArchiveReader archiveReader = new ArchiveReader();
1026
1027 currentDeploymentFile.setClassLoader(false, config.getModuleClassLoader(), null);
1028 axismodule.setModuleClassLoader(currentDeploymentFile.getClassLoader());
1029 archiveReader.readModuleArchive(currentDeploymentFile, axismodule,
1030 false, config);
1031 ClassLoader moduleClassLoader = axismodule.getModuleClassLoader();
1032 Flow inflow = axismodule.getInFlow();
1033
1034 if (inflow != null) {
1035 Utils.addFlowHandlers(inflow, moduleClassLoader);
1036 }
1037
1038 Flow outFlow = axismodule.getOutFlow();
1039
1040 if (outFlow != null) {
1041 Utils.addFlowHandlers(outFlow, moduleClassLoader);
1042 }
1043
1044 Flow faultInFlow = axismodule.getFaultInFlow();
1045
1046 if (faultInFlow != null) {
1047 Utils.addFlowHandlers(faultInFlow, moduleClassLoader);
1048 }
1049
1050 Flow faultOutFlow = axismodule.getFaultOutFlow();
1051
1052 if (faultOutFlow != null) {
1053 Utils.addFlowHandlers(faultOutFlow, moduleClassLoader);
1054 }
1055 } catch (AxisFault axisFault) {
1056 throw new DeploymentException(axisFault);
1057 }
1058 return axismodule;
1059 }
1060
1061 /**
1062 * Fills an axisservice object using services.xml. First creates
1063 * an axisservice object using WSDL and then fills it using the given services.xml.
1064 * Loads all the required class and builds the chains, finally adds the
1065 * servicecontext to EngineContext and axisservice into EngineConfiguration.
1066 *
1067 * @param serviceInputStream InputStream containing configuration data
1068 * @param configCtx the ConfigurationContext in which we're deploying
1069 * @return Returns AxisService.
1070 * @throws DeploymentException if there's a problem
1071 */
1072 public static AxisService buildService(InputStream serviceInputStream,
1073 ConfigurationContext configCtx)
1074 throws DeploymentException {
1075 AxisService axisService = new AxisService();
1076 try {
1077 ServiceBuilder builder = new ServiceBuilder(serviceInputStream, configCtx, axisService);
1078 builder.populateService(builder.buildOM());
1079 } catch (AxisFault axisFault) {
1080 throw new DeploymentException(axisFault);
1081 } catch (XMLStreamException e) {
1082 throw new DeploymentException(e);
1083 }
1084
1085 return axisService;
1086 }
1087
1088 /**
1089 * To build a AxisServiceGroup for a given services.xml
1090 * You have to add the created group into AxisConfig
1091 *
1092 * @param servicesxml InputStream created from services.xml or equivalent
1093 * @param classLoader ClassLoader to use
1094 * @param serviceGroupName name of the service group
1095 * @param configCtx the ConfigurationContext in which we're deploying
1096 * @param archiveReader the ArchiveReader we're working with
1097 * @param wsdlServices Map of existing WSDL services
1098 * @return a fleshed-out AxisServiceGroup
1099 * @throws AxisFault if there's a problem
1100 */
1101 public static AxisServiceGroup buildServiceGroup(InputStream servicesxml,
1102 ClassLoader classLoader,
1103 String serviceGroupName,
1104 ConfigurationContext configCtx,
1105 ArchiveReader archiveReader,
1106 HashMap wsdlServices) throws AxisFault {
1107 DeploymentFileData currentDeploymentFile = new DeploymentFileData(null, null);
1108 currentDeploymentFile.setClassLoader(classLoader);
1109 AxisServiceGroup serviceGroup = new AxisServiceGroup();
1110 serviceGroup.setServiceGroupClassLoader(classLoader);
1111 serviceGroup.setServiceGroupName(serviceGroupName);
1112 AxisConfiguration axisConfig = configCtx.getAxisConfiguration();
1113 try {
1114 ArrayList serviceList = archiveReader.buildServiceGroup(servicesxml,
1115 currentDeploymentFile,
1116 serviceGroup,
1117 wsdlServices, configCtx);
1118 fillServiceGroup(serviceGroup, serviceList, null, axisConfig);
1119 return serviceGroup;
1120 } catch (XMLStreamException e) {
1121 throw AxisFault.makeFault(e);
1122 }
1123 }
1124
1125 public static AxisServiceGroup loadServiceGroup(File serviceFile,
1126 ConfigurationContext configCtx)
1127 throws AxisFault {
1128 try {
1129 DeploymentFileData currentDeploymentFile = new DeploymentFileData(serviceFile, null);
1130 DeploymentClassLoader classLoader = Utils.createClassLoader(serviceFile);
1131 currentDeploymentFile.setClassLoader(classLoader);
1132 AxisServiceGroup serviceGroup = new AxisServiceGroup();
1133 serviceGroup.setServiceGroupClassLoader(classLoader);
1134
1135 // Drop the extension and take the name
1136 String fileName = serviceFile.getName();
1137 String serviceGroupName = fileName.substring(0, fileName.lastIndexOf("."));
1138 serviceGroup.setServiceGroupName(serviceGroupName);
1139 AxisConfiguration axisConfig = configCtx.getAxisConfiguration();
1140
1141 ArchiveReader archiveReader = new ArchiveReader();
1142 HashMap wsdlServices = archiveReader.processWSDLs(currentDeploymentFile);
1143 InputStream serviceXml = classLoader.getResourceAsStream("META-INF/services.xml");
1144 ArrayList serviceList = archiveReader.buildServiceGroup(serviceXml,
1145 currentDeploymentFile,
1146 serviceGroup,
1147 wsdlServices, configCtx);
1148 fillServiceGroup(serviceGroup, serviceList, null, axisConfig);
1149 return serviceGroup;
1150 } catch (Exception e) {
1151 throw new DeploymentException(e);
1152 }
1153 }
1154
1155 public File getServicesDir() {
1156 return servicesDir;
1157 }
1158
1159 public File getModulesDir() {
1160 return modulesDir;
1161 }
1162
1163
1164 public File getRepositoryDir() {
1165 return repositoryDir;
1166 }
1167
1168 public void setExtensionToDeployerMappingMap(HashMap extensionToDeployerMappingMap) {
1169 this.extensionToDeployerMappingMap = extensionToDeployerMappingMap;
1170 }
1171
1172 public void setDeployers(Map<String, Map<String, Deployer>> deployerMap) {
1173 this.deployerMap = deployerMap;
1174 }
1175
1176 public Map<String, Map<String, Deployer>> getDeployers() {
1177 return this.deployerMap;
1178 }
1179
1180 public RepositoryListener getRepoListener() {
1181 return repoListener;
1182 }
1183
1184
1185 public ServiceDeployer getServiceDeployer() {
1186 return serviceDeployer;
1187 }
1188
1189 public ModuleDeployer getModuleDeployer() {
1190 return moduleDeployer;
1191 }
1192
1193 public Deployer getDeployer(String directory, String extension) {
1194 Map<String, Deployer> extensionMap = deployerMap.get(directory);
1195 return (extensionMap != null) ? extensionMap.get(extension) : null;
1196 }
1197
1198 public Deployer getDeployerForExtension(String extension) {
1199 return (Deployer) extensionToDeployerMappingMap.get(extension);
1200 }
1201
1202 /**
1203 * Clean up the mess
1204 */
1205 public void cleanup() {
1206 if (axisConfig.getModuleClassLoader() instanceof JarFileClassLoader) {
1207 ((JarFileClassLoader)axisConfig.getModuleClassLoader()).destroy();
1208 }
1209 if (axisConfig.getServiceClassLoader() instanceof JarFileClassLoader) {
1210 ((JarFileClassLoader)axisConfig.getServiceClassLoader()).destroy();
1211 }
1212 if (axisConfig.getSystemClassLoader() instanceof JarFileClassLoader) {
1213 ((JarFileClassLoader)axisConfig.getSystemClassLoader()).destroy();
1214 }
1215 if (scheduler != null) {
1216 scheduler.cleanup();
1217 }
1218 }
1219 }