/* * Copyright 2004,2005 The Apache Software Foundation. * * Licensed 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.axis2.osgi.deployment; import org.apache.axiom.om.OMElement; import org.apache.axis2.AxisFault; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.deployment.*; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.AxisServiceGroup; import static org.apache.axis2.osgi.deployment.OSGiAxis2Constants.MODULE_NOT_FOUND_ERROR; import static org.apache.axis2.osgi.deployment.OSGiAxis2Constants.OSGi_BUNDLE_ID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import java.io.InputStream; import java.net.URL; import java.util.*; /** * Creates proper AxisServiceGroup/AxisService looking into bundles */ public class ServiceRegistry extends AbstractRegistry<AxisServiceGroup> { private static Log log = LogFactory.getLog(ServiceRegistry.class); public ServiceRegistry(BundleContext context, ConfigurationContext configCtx) { super(context, configCtx); } public void register(Bundle bundle) { lock.lock(); try { addServices(bundle); } finally { lock.unlock(); } } /** * When a bundle is started this method will look for xml files that suffix with "services.xml". * Thus, a given bundle can have n number of *services.xml. * Ex: my1services.xml and my2_services.xml. * <p/> * Due to security consideration, if one *services.xml fail, all the services will treated as fail. * * @param bundle registered bundle */ private void addServices(Bundle bundle) { if (!resolvedBundles.containsKey(bundle)) { Enumeration enumeration = bundle.findEntries("META-INF", "*services.xml", false); int i = 0; List<AxisServiceGroup> axisServiceGroupList = null; if (enumeration != null) { axisServiceGroupList = new ArrayList<AxisServiceGroup>(); } while (enumeration != null && enumeration.hasMoreElements()) { try { URL url = (URL) enumeration.nextElement(); AxisServiceGroup serviceGroup = new AxisServiceGroup(configCtx.getAxisConfiguration()); serviceGroup.addParameter("last.updated", bundle.getLastModified()); ClassLoader loader = new BundleClassLoader(bundle, Registry.class.getClassLoader()); serviceGroup.setServiceGroupClassLoader(loader); InputStream inputStream = url.openStream(); DescriptionBuilder builder = new DescriptionBuilder(inputStream, configCtx); OMElement rootElement = builder.buildOM(); String elementName = rootElement.getLocalName(); Dictionary headers = bundle.getHeaders(); String bundleSymbolicName = (String) headers.get("Bundle-SymbolicName"); bundleSymbolicName = bundleSymbolicName + "_" + i; serviceGroup.setServiceGroupName(bundleSymbolicName); HashMap wsdlServicesMap = new HashMap(); if (DeploymentConstants.TAG_SERVICE.equals(elementName)) { AxisService axisService = new AxisService(bundleSymbolicName); axisService.setParent(serviceGroup); axisService.setClassLoader(loader); ServiceBuilder serviceBuilder = new OSGiServiceBuilder(configCtx, axisService); serviceBuilder.setWsdlServiceMap(wsdlServicesMap); AxisService service = serviceBuilder.populateService(rootElement); ArrayList<AxisService> serviceList = new ArrayList<AxisService>(); serviceList.add(service); DeploymentEngine.addServiceGroup(serviceGroup, serviceList, null, null, configCtx.getAxisConfiguration()); log.info("[Axis2/OSGi] Deployed axis2 service:" + service.getName() + " in Bundle: " + bundle.getSymbolicName()); } else if (DeploymentConstants.TAG_SERVICE_GROUP.equals(elementName)) { ServiceGroupBuilder groupBuilder = new OSGiServiceGroupBuilder(rootElement, wsdlServicesMap, configCtx); ArrayList serviceList = groupBuilder.populateServiceGroup(serviceGroup); DeploymentEngine.addServiceGroup(serviceGroup, serviceList, null, null, configCtx.getAxisConfiguration()); log.info("[Axis2/OSGi] Deployed axis2 service group:" + serviceGroup.getServiceGroupName() + " in Bundle: " + bundle.getSymbolicName()); } //bundle Id keeps the association between bundle and axisService group for later use serviceGroup.addParameter(OSGi_BUNDLE_ID, bundle.getBundleId()); axisServiceGroupList.add(serviceGroup); //marked as resolved. if (unreslovedBundles.contains(bundle)) { unreslovedBundles.remove(bundle); } i++; } catch (Throwable e) { String msg = "Error while reading from the bundle"; if (e instanceof DeploymentException) { String message = e.getMessage(); if (message != null && message.length() != 0) { if (message.indexOf(MODULE_NOT_FOUND_ERROR) > -1) { if (!unreslovedBundles.contains(bundle)) { log.info("A service being found with unmeant module " + "dependency. Hence, moved it to UNRESOLVED state."); unreslovedBundles.add(bundle); } else { log.info("A service being found in UNRESOLVED state."); } } else { log.error(msg, e); break; } } else { log.error(msg, e); break; } } else { log.error(msg, e); break; } } } if (axisServiceGroupList != null && axisServiceGroupList.size() > 0) { resolvedBundles.put(bundle, axisServiceGroupList); } } } public void unRegister(Bundle bundle, boolean uninstall) { lock.lock(); try { List<AxisServiceGroup> axisServiceGroupList = resolvedBundles.get(bundle); if (axisServiceGroupList != null) { for (AxisServiceGroup axisServiceGroup : axisServiceGroupList) { if (resolvedBundles.containsKey(bundle)) { resolvedBundles.remove(bundle); } if (!unreslovedBundles.contains(bundle) && !uninstall) { unreslovedBundles.add(bundle); } try { if (log.isInfoEnabled()) { List<String> serviceNames = new ArrayList<String>(); for (Iterator<AxisService> iterator = axisServiceGroup.getServices(); iterator.hasNext(); ) { AxisService service = (AxisService) iterator.next(); serviceNames.add(service.getName()); } log.info("Stopping service group " + axisServiceGroup.getServiceGroupName() + " with services " + serviceNames + " in bundle " + bundle.getSymbolicName()); } configCtx.getAxisConfiguration() .removeServiceGroup(axisServiceGroup.getServiceGroupName()); } catch (AxisFault e) { String msg = "Error while removing the service group"; log.error(msg, e); } } } } finally { lock.unlock(); } } public void remove(Bundle bundle) { unRegister(bundle, true); lock.lock(); try { if (resolvedBundles.containsKey(bundle)) { resolvedBundles.remove(bundle); } if (unreslovedBundles.contains(bundle)) { unreslovedBundles.remove(bundle); } } finally { lock.unlock(); } } }