more code in progress to support multiple instances of jetty
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2030 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
5e2110d894
commit
dacfcc8903
|
@ -14,13 +14,10 @@
|
|||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Dictionary;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.JettyServersManagedFactory;
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.JettyContextHandlerServiceTracker;
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.WebBundleTrackerCustomizer;
|
||||
import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
|
||||
|
@ -30,11 +27,7 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
|||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.cm.Configuration;
|
||||
import org.osgi.service.cm.ConfigurationAdmin;
|
||||
import org.osgi.service.cm.ManagedServiceFactory;
|
||||
import org.osgi.util.tracker.BundleTracker;
|
||||
|
||||
/**
|
||||
|
@ -74,7 +67,7 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
private PackageAdminServiceTracker _packageAdminServiceTracker;
|
||||
private BundleTracker _webBundleTracker;
|
||||
|
||||
private ServiceRegistration _jettyServerFactoryService;
|
||||
// private ServiceRegistration _jettyServerFactoryService;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -94,11 +87,11 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
_packageAdminServiceTracker = new PackageAdminServiceTracker(context);
|
||||
|
||||
//Register the Jetty Server Factory as a ManagedServiceFactory:
|
||||
Properties jettyServerMgdFactoryServiceProps = new Properties();
|
||||
jettyServerMgdFactoryServiceProps.put("pid", OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID);
|
||||
_jettyServerFactoryService = context.registerService(
|
||||
ManagedServiceFactory.class.getName(), new JettyServersManagedFactory(),
|
||||
jettyServerMgdFactoryServiceProps);
|
||||
// Properties jettyServerMgdFactoryServiceProps = new Properties();
|
||||
// jettyServerMgdFactoryServiceProps.put("pid", OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID);
|
||||
// _jettyServerFactoryService = context.registerService(
|
||||
// ManagedServiceFactory.class.getName(), new JettyServersManagedFactory(),
|
||||
// jettyServerMgdFactoryServiceProps);
|
||||
|
||||
|
||||
// todo: replace all this by the ManagedFactory so that we can start
|
||||
|
@ -277,53 +270,5 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
// todo
|
||||
}
|
||||
|
||||
public static void createNewServer(Bundle contributor, String serverName, String urlsToJettyXml) throws Exception
|
||||
{
|
||||
ServiceReference configurationAdminReference =
|
||||
contributor.getBundleContext().getServiceReference( ConfigurationAdmin.class.getName() );
|
||||
|
||||
ConfigurationAdmin confAdmin = (ConfigurationAdmin) contributor.getBundleContext()
|
||||
.getService( configurationAdminReference );
|
||||
|
||||
Configuration configuration = confAdmin.createFactoryConfiguration(
|
||||
OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID, contributor.getLocation() );
|
||||
Dictionary properties = new Hashtable();
|
||||
properties.put(OSGiWebappConstants.MANAGED_JETTY_SERVER_NAME, serverName);
|
||||
|
||||
StringBuilder actualBundleUrls = new StringBuilder();
|
||||
StringTokenizer tokenizer = new StringTokenizer(urlsToJettyXml, ",", false);
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
if (actualBundleUrls.length() != 0)
|
||||
{
|
||||
actualBundleUrls.append(",");
|
||||
}
|
||||
String token = tokenizer.nextToken();
|
||||
if (token.indexOf(':') != -1)
|
||||
{
|
||||
//a complete url. no change needed:
|
||||
actualBundleUrls.append(token);
|
||||
}
|
||||
else if (token.startsWith("/"))
|
||||
{
|
||||
//url relative to the contributor bundle:
|
||||
URL url = contributor.getEntry(token);
|
||||
if (url == null)
|
||||
{
|
||||
actualBundleUrls.append(token);
|
||||
}
|
||||
else
|
||||
{
|
||||
actualBundleUrls.append(url.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
properties.put(OSGiWebappConstants.MANAGED_JETTY_XML_CONFIG_URLS, actualBundleUrls.toString());
|
||||
configuration.update(properties);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009-2010 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.serverfactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.ServiceEvent;
|
||||
import org.osgi.framework.ServiceListener;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
||||
/**
|
||||
* Deploy the jetty server instances when they are registered as an OSGi service.
|
||||
*/
|
||||
public class JettyServerServiceTracker implements ServiceListener
|
||||
{
|
||||
|
||||
/**
|
||||
* Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin service.
|
||||
*/
|
||||
private Map<String, ServerInstanceWrapper> _serversIndexedByName = new HashMap<String, ServerInstanceWrapper>();
|
||||
/** The context-handler to deactivate indexed by ServerInstanceWrapper */
|
||||
private Map<ServiceReference, ServerInstanceWrapper> _indexByServiceReference = new HashMap<ServiceReference, ServerInstanceWrapper>();
|
||||
|
||||
/**
|
||||
* Receives notification that a service has had a lifecycle change.
|
||||
*
|
||||
* @param ev
|
||||
* The <code>ServiceEvent</code> object.
|
||||
*/
|
||||
public void serviceChanged(ServiceEvent ev)
|
||||
{
|
||||
ServiceReference sr = ev.getServiceReference();
|
||||
switch (ev.getType())
|
||||
{
|
||||
case ServiceEvent.MODIFIED:
|
||||
case ServiceEvent.UNREGISTERING:
|
||||
{
|
||||
ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference());
|
||||
if (instance != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
instance.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ev.getType() == ServiceEvent.UNREGISTERING)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// modified, meaning: we reload it. now that we stopped it;
|
||||
// we can register it.
|
||||
}
|
||||
case ServiceEvent.REGISTERED:
|
||||
{
|
||||
Bundle contributor = sr.getBundle();
|
||||
Server server = (Server)contributor.getBundleContext().getService(sr);
|
||||
ServerInstanceWrapper wrapper = registerInIndex(server, sr);
|
||||
Properties props = new Properties();
|
||||
for (String key : sr.getPropertyKeys())
|
||||
{
|
||||
Object value = sr.getProperty(key);
|
||||
props.put(key, value);
|
||||
}
|
||||
wrapper.start(server, props);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ServerInstanceWrapper registerInIndex(Server server, ServiceReference sr)
|
||||
{
|
||||
String name = (String)sr.getProperty(OSGiWebappConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
if (name == null)
|
||||
{
|
||||
throw new IllegalArgumentException("The property " +
|
||||
OSGiWebappConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory");
|
||||
}
|
||||
ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name);
|
||||
_indexByServiceReference.put(sr,wrapper);
|
||||
_serversIndexedByName.put(name,wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ContextHandler to stop.
|
||||
*
|
||||
* @param reg
|
||||
* @return the ContextHandler to stop.
|
||||
*/
|
||||
private ServerInstanceWrapper unregisterInIndex(ServiceReference sr)
|
||||
{
|
||||
ServerInstanceWrapper handler = _indexByServiceReference.remove(sr);
|
||||
if (handler == null)
|
||||
{
|
||||
// a warning?
|
||||
return null;
|
||||
}
|
||||
String name = handler.getManagedServerName();
|
||||
if (name != null)
|
||||
{
|
||||
_serversIndexedByName.remove(name);
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
}
|
|
@ -14,42 +14,25 @@
|
|||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.serverfactory;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.service.cm.Configuration;
|
||||
import org.osgi.service.cm.ConfigurationAdmin;
|
||||
import org.osgi.service.cm.ConfigurationException;
|
||||
import org.osgi.service.cm.ManagedServiceFactory;
|
||||
|
||||
/**
|
||||
* This is a work in progress. <br/>
|
||||
* In particular there is a lot of work required during the update of the
|
||||
* configuration of a server. It might not be practical to in fact support that
|
||||
* and re-deploy the webapps in the same state than before the server was
|
||||
* stopped.
|
||||
* <p>
|
||||
* jetty servers are managed as OSGi services registered here. try to find out
|
||||
* if a configuration will fail (ports already opened etc).
|
||||
* </p>
|
||||
* <p>
|
||||
* Try to enable the creation and configuration of jetty servers in all the
|
||||
* usual standard ways. The configuration of the server is defined by the
|
||||
* properties passed to the service:
|
||||
* <ol>
|
||||
* <li>First look for jettyfactory. If the value is a jetty server, use that
|
||||
* server</li>
|
||||
* <li>Then look for jettyhome key. The value should be a java.io.File or a
|
||||
* String that is a path to the folder It is required that a etc/jetty.xml file
|
||||
* will be loated from that folder.</li>
|
||||
* <li>Then look for a jettyxml key. The value should be a java.io.File or an
|
||||
* InputStream that contains a jetty configuration file.</li>
|
||||
* <li>TODO: More ways to configure a jetty server? (other IOCs like spring,
|
||||
* equinox properties...)</li>
|
||||
* <li>Throw an exception if none of the relevant parameters are found</li>
|
||||
* </ol>
|
||||
* </p>
|
||||
* Manages the deployment of jetty server instances.
|
||||
* Not sure this is bringing much compared to the JettyServerServiceTracker.
|
||||
*
|
||||
* @author hmalphettes
|
||||
*/
|
||||
|
@ -161,4 +144,59 @@ public class JettyServersManagedFactory implements ManagedServiceFactory
|
|||
return pid != null ? _serversIndexedByPID.get(pid) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to create and configure a new Jetty Server via the ManagedServiceFactory
|
||||
* @param contributor
|
||||
* @param serverName
|
||||
* @param urlsToJettyXml
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void createNewServer(Bundle contributor, String serverName, String urlsToJettyXml) throws Exception
|
||||
{
|
||||
ServiceReference configurationAdminReference =
|
||||
contributor.getBundleContext().getServiceReference( ConfigurationAdmin.class.getName() );
|
||||
|
||||
ConfigurationAdmin confAdmin = (ConfigurationAdmin) contributor.getBundleContext()
|
||||
.getService( configurationAdminReference );
|
||||
|
||||
Configuration configuration = confAdmin.createFactoryConfiguration(
|
||||
OSGiWebappConstants.MANAGED_JETTY_SERVER_FACTORY_PID, contributor.getLocation() );
|
||||
Dictionary properties = new Hashtable();
|
||||
properties.put(OSGiWebappConstants.MANAGED_JETTY_SERVER_NAME, serverName);
|
||||
|
||||
StringBuilder actualBundleUrls = new StringBuilder();
|
||||
StringTokenizer tokenizer = new StringTokenizer(urlsToJettyXml, ",", false);
|
||||
while (tokenizer.hasMoreTokens())
|
||||
{
|
||||
if (actualBundleUrls.length() != 0)
|
||||
{
|
||||
actualBundleUrls.append(",");
|
||||
}
|
||||
String token = tokenizer.nextToken();
|
||||
if (token.indexOf(':') != -1)
|
||||
{
|
||||
//a complete url. no change needed:
|
||||
actualBundleUrls.append(token);
|
||||
}
|
||||
else if (token.startsWith("/"))
|
||||
{
|
||||
//url relative to the contributor bundle:
|
||||
URL url = contributor.getEntry(token);
|
||||
if (url == null)
|
||||
{
|
||||
actualBundleUrls.append(token);
|
||||
}
|
||||
else
|
||||
{
|
||||
actualBundleUrls.append(url.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
properties.put(OSGiWebappConstants.MANAGED_JETTY_XML_CONFIG_URLS, actualBundleUrls.toString());
|
||||
configuration.update(properties);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -84,6 +84,29 @@ public class ServerInstanceWrapper {
|
|||
{
|
||||
_managedServerName = managedServerName;
|
||||
}
|
||||
|
||||
public String getManagedServerName()
|
||||
{
|
||||
return _managedServerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The classloader that should be the parent classloader for
|
||||
* each webapp deployed on this server.
|
||||
* @return
|
||||
*/
|
||||
public ClassLoader getParentClassLoaderForWebapps()
|
||||
{
|
||||
return _commonParentClassLoaderForWebapps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The deployment manager registered on this server.
|
||||
*/
|
||||
public DeploymentManager getDeploymentManager()
|
||||
{
|
||||
return _deploymentManager;
|
||||
}
|
||||
|
||||
|
||||
public void start(Server server, Dictionary props)
|
||||
|
|
|
@ -146,15 +146,15 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
}
|
||||
}
|
||||
}
|
||||
if (ev.getType() == ServiceEvent.UNREGISTERING)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// modified, meaning: we reload it. now that we stopped it;
|
||||
// we can register it.
|
||||
}
|
||||
if (ev.getType() == ServiceEvent.UNREGISTERING)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// modified, meaning: we reload it. now that we stopped it;
|
||||
// we can register it.
|
||||
}
|
||||
case ServiceEvent.REGISTERED:
|
||||
{
|
||||
Bundle contributor = sr.getBundle();
|
||||
|
|
Loading…
Reference in New Issue