| /* |
| * 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.axis2.AxisFault; |
| import org.apache.axis2.builder.Builder; |
| import org.apache.axis2.context.ConfigurationContext; |
| import org.apache.axis2.context.ConfigurationContextFactory; |
| import org.apache.axis2.deployment.Deployer; |
| import org.apache.axis2.deployment.util.Utils; |
| import org.apache.axis2.description.AxisService; |
| import org.apache.axis2.description.Parameter; |
| import org.apache.axis2.description.TransportInDescription; |
| import org.apache.axis2.engine.*; |
| import static org.apache.axis2.osgi.deployment.OSGiAxis2Constants.*; |
| import org.apache.axis2.osgi.deployment.tracker.BundleTracker; |
| import org.apache.axis2.osgi.deployment.tracker.WSTracker; |
| import org.apache.axis2.osgi.tx.HttpListener; |
| import org.apache.axis2.transport.MessageFormatter; |
| import org.apache.axis2.transport.TransportListener; |
| import org.apache.axis2.transport.TransportSender; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.osgi.framework.*; |
| import org.osgi.service.cm.ConfigurationException; |
| import org.osgi.service.cm.ManagedService; |
| |
| import java.util.Dictionary; |
| import java.util.Iterator; |
| import java.util.Properties; |
| import java.util.concurrent.locks.Lock; |
| import java.util.concurrent.locks.ReentrantLock; |
| |
| /** |
| * OSGiConfigurationContextFactory creates ConfigurationContext, which is the ultimate Axis2 environment. |
| * This creation is handled as a ManagedService service, thus, Configuraiton Admin has control over it. |
| */ |
| public class OSGiConfigurationContextFactory implements ManagedService { |
| |
| private static Log log = LogFactory.getLog(OSGiConfigurationContextFactory.class); |
| |
| private BundleContext context; |
| |
| private ServiceRegistration mngServiceRegistration; |
| |
| private ServiceRegistration transportServiceRegistration; |
| |
| private ConfigurationContext configCtx; |
| |
| private ServiceRegistration configCtxServiceRegistration; |
| |
| private BundleTracker bundleTracker; |
| |
| public synchronized void start(BundleContext context) { |
| this.context = context; |
| bundleTracker = new BundleTracker(context); |
| Dictionary props = new Properties(); |
| props.put(Constants.SERVICE_PID, "org.apache.axis2.osgi"); |
| mngServiceRegistration = |
| context.registerService(ManagedService.class.getName(), this, props); |
| } |
| |
| public synchronized void stop() { |
| if (configCtxServiceRegistration != null) { |
| configCtxServiceRegistration.unregister(); |
| } |
| |
| if (transportServiceRegistration != null) { |
| transportServiceRegistration.unregister(); |
| } |
| |
| if (mngServiceRegistration != null) { |
| mngServiceRegistration.unregister(); |
| } |
| bundleTracker.close(); |
| if (configCtx != null) { |
| log.debug("Terminating configuration context"); |
| try { |
| configCtx.terminate(); |
| configCtx = null; |
| } catch (AxisFault e) { |
| String msg = "Error while ConfigurationContext is terminated"; |
| log.error(msg, e); |
| } |
| } |
| log.info("Axis2 environment has stopped"); |
| } |
| |
| public synchronized void startConfigurationContext(Dictionary dictionary) throws AxisFault { |
| AxisConfigurator configurator = new OSGiServerConfigurator(context); |
| configCtx = ConfigurationContextFactory.createConfigurationContext(configurator); |
| ListenerManager listenerManager = new ListenerManager(); |
| listenerManager.init(configCtx); |
| listenerManager.start(); |
| } |
| |
| public void updated(Dictionary dictionary) throws ConfigurationException { |
| try { |
| startConfigurationContext(dictionary); |
| if (configCtxServiceRegistration != null) { |
| configCtxServiceRegistration.unregister(); |
| } |
| //register ConfigurationContext as a OSGi serivce |
| configCtxServiceRegistration = |
| context.registerService(ConfigurationContext.class.getName(), configCtx, null); |
| |
| Registry servicesRegistry = new ServiceRegistry(context, configCtx); |
| Registry moduleRegistry = new ModuleRegistry(context, configCtx, servicesRegistry); |
| bundleTracker.addRegistry(servicesRegistry); |
| bundleTracker.addRegistry(moduleRegistry); |
| bundleTracker.open(); |
| |
| new WSTracker(configCtx, context).open(); |
| |
| context.addServiceListener(new AxisConfigServiceListener(configCtx, context)); |
| |
| Dictionary prop = new Properties(); |
| prop.put(PROTOCOL, "http"); |
| //adding the default listener |
| transportServiceRegistration = context.registerService(TransportListener.class.getName(), new HttpListener(context), |
| prop); |
| log.info("Axis2 environment has started."); |
| } catch (AxisFault e) { |
| String msg = "Error while creating ConfigurationContext"; |
| log.error(msg, e); |
| throw new ConfigurationException(msg, msg, e); |
| } |
| |
| } |
| |
| /** |
| * @see org.osgi.framework.ServiceListener |
| * <p/> |
| * AxisConfigServiceListener is a ServiceListener. This class listen to OSGi services and |
| * build the appropriate AxisConfiguration plugins. These plugins include, message receivers, |
| * transport listeners, transport senders, message formatters & builders, etc. |
| */ |
| private static class AxisConfigServiceListener implements ServiceListener { |
| |
| private ConfigurationContext configCtx; |
| |
| private AxisConfiguration axisConfig; |
| |
| private BundleContext context; |
| |
| private Lock lock = new ReentrantLock(); |
| |
| public AxisConfigServiceListener(ConfigurationContext configCtx, BundleContext context) { |
| this.configCtx = configCtx; |
| this.context = context; |
| this.axisConfig = configCtx.getAxisConfiguration(); |
| } |
| |
| public void serviceChanged(ServiceEvent event) { |
| ServiceReference reference = event.getServiceReference(); |
| Object service = context.getService(reference); |
| if (service instanceof TransportListener) { |
| String protocol = (String) reference.getProperty(PROTOCOL); |
| if (protocol == null || protocol.length() == 0) { |
| String msg = "Protocol is not found for the trnasport object"; |
| log.error(msg); |
| throw new RuntimeException(msg); |
| } |
| if (event.getType() == ServiceEvent.REGISTERED) { |
| TransportListener txListener = |
| (TransportListener) service; |
| |
| TransportInDescription txInDes = new TransportInDescription(protocol); |
| txInDes.setReceiver(txListener); |
| String[] keys = reference.getPropertyKeys(); |
| if (keys != null) { |
| for (String key : keys) { |
| if (key.equals(PROTOCOL)) { |
| continue; |
| } |
| //TODO: assume String properties at this moment. |
| try { |
| Object propObj = reference.getProperty(key); |
| if (propObj instanceof String) { |
| String value = (String) propObj; |
| Parameter param = new Parameter(key, value); |
| txInDes.addParameter(param); |
| } |
| } catch (AxisFault e) { |
| String msg = "Error while reading transport properties from :" + |
| txListener.toString(); |
| log.error(msg, e); |
| throw new RuntimeException(msg, e); |
| } |
| } |
| } |
| try { |
| configCtx.getListenerManager().addListener(txInDes, false); |
| //Now update the AxisService endpoint map |
| lock.lock(); |
| try { |
| for (Iterator iterator = axisConfig.getServices().keySet().iterator(); |
| iterator.hasNext();) { |
| String serviceName = (String) iterator.next(); |
| AxisService axisService = axisConfig.getService(serviceName); |
| Utils.addEndpointsToService(axisService, axisConfig); |
| } |
| } finally { |
| lock.unlock(); |
| } |
| } catch (AxisFault e) { |
| String msg = "Error while intiating and starting the listener"; |
| log.error(msg, e); |
| throw new RuntimeException(msg, e); |
| } |
| } |
| |
| } else if (service instanceof Builder) { |
| String contextType = (String) reference.getProperty(CONTENT_TYPE); |
| if (contextType == null || contextType.length() == 0) { |
| String msg = CONTENT_TYPE + " is missing from builder object"; |
| log.error(msg); |
| throw new RuntimeException(msg); |
| } |
| if (event.getType() == ServiceEvent.REGISTERED || event.getType() == |
| ServiceEvent.MODIFIED) { |
| Builder builder = (Builder) service; |
| lock.lock(); |
| try { |
| axisConfig.addMessageBuilder(contextType, builder); |
| } finally { |
| lock.unlock(); |
| } |
| } |
| } else if (service instanceof MessageFormatter) { |
| String contextType = (String) reference.getProperty(CONTENT_TYPE); |
| if (contextType == null || contextType.length() == 0) { |
| String msg = CONTENT_TYPE + " is missing from formatter object"; |
| log.error(msg); |
| throw new RuntimeException(msg); |
| } |
| if (event.getType() == ServiceEvent.REGISTERED || event.getType() == |
| ServiceEvent.MODIFIED) { |
| MessageFormatter formatter = (MessageFormatter) service; |
| lock.lock(); |
| try { |
| axisConfig.addMessageFormatter(contextType, formatter); |
| } finally { |
| lock.unlock(); |
| } |
| } |
| } else if (service instanceof MessageReceiver) { |
| String mep = (String) reference.getProperty(MEP); |
| if (mep == null || mep.length() == 0) { |
| String msg = MEP + " is missing from message receiver object"; |
| log.error(msg); |
| throw new RuntimeException(msg); |
| } |
| if (event.getType() == ServiceEvent.REGISTERED || event.getType() == |
| ServiceEvent.MODIFIED) { |
| MessageReceiver mr = (MessageReceiver) service; |
| lock.lock(); |
| try { |
| axisConfig.addMessageReceiver(mep, mr); |
| } finally { |
| lock.unlock(); |
| } |
| } |
| } else if (service instanceof AxisObserver) { |
| if (event.getType() == ServiceEvent.REGISTERED || event.getType() == |
| ServiceEvent.MODIFIED) { |
| AxisObserver axisObserver = (AxisObserver) service; |
| lock.lock(); |
| try { |
| axisObserver.init(axisConfig); |
| axisConfig.addObservers(axisObserver); |
| } finally { |
| lock.unlock(); |
| } |
| } |
| } else if (service instanceof TransportSender) { |
| //TODO: TBD |
| } else if (service instanceof Deployer) { |
| // TODO: TBD, there is no Axis2 API yet available to add deployers. |
| } |
| } |
| } |
| |
| } |