More refactoring.
This commit is contained in:
parent
98cda498cb
commit
4a312f7cb6
|
@ -0,0 +1,336 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2012 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;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.deploy.AppProvider;
|
||||
import org.eclipse.jetty.deploy.DeploymentManager;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory;
|
||||
import org.eclipse.jetty.osgi.boot.utils.OSGiClassLoader;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.JarResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* AbstractContextProvider
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractContextProvider extends AbstractLifeCycle implements AppProvider
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(AbstractContextProvider.class);
|
||||
|
||||
private DeploymentManager _deploymentManager;
|
||||
|
||||
|
||||
private ServerInstanceWrapper _serverWrapper;
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* BundleApp
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class BundleApp extends App
|
||||
{
|
||||
private String _contextFile;
|
||||
private Bundle _bundle;
|
||||
private ContextHandler _contextHandler;
|
||||
private Dictionary _properties;
|
||||
private boolean _configured = false;
|
||||
|
||||
public BundleApp(DeploymentManager manager, AppProvider provider, String originId, Bundle bundle, String contextFile)
|
||||
{
|
||||
super(manager, provider, originId);
|
||||
_bundle = bundle;
|
||||
_contextFile = contextFile;
|
||||
_properties = bundle.getHeaders();
|
||||
}
|
||||
|
||||
public BundleApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String contextFile, String originId)
|
||||
{
|
||||
super(manager, provider, originId);
|
||||
_contextFile = contextFile;
|
||||
_properties = properties;
|
||||
_bundle = bundle;
|
||||
}
|
||||
|
||||
public String getContextFile ()
|
||||
{
|
||||
return _contextFile;
|
||||
}
|
||||
|
||||
public void setContextHandler(ContextHandler h)
|
||||
{
|
||||
_contextHandler = h;
|
||||
}
|
||||
|
||||
public ContextHandler getContextHandler()
|
||||
throws Exception
|
||||
{
|
||||
configureContextHandler();
|
||||
return _contextHandler;
|
||||
}
|
||||
|
||||
|
||||
public void configureContextHandler()
|
||||
throws Exception
|
||||
{
|
||||
if (_configured)
|
||||
return;
|
||||
|
||||
_configured = true;
|
||||
|
||||
//Override for bundle root may have been set
|
||||
String bundleOverrideLocation = (String)_properties.get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE);
|
||||
if (bundleOverrideLocation == null)
|
||||
bundleOverrideLocation = (String)_properties.get(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE);
|
||||
|
||||
//Location on filesystem of bundle or the bundle override location
|
||||
File bundleLocation = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(_bundle);
|
||||
File root = (bundleOverrideLocation==null?bundleLocation:new File(bundleOverrideLocation));
|
||||
Resource rootResource = Resource.newResource(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(root.toURI().toURL()));
|
||||
|
||||
//try and make sure the rootResource is useable - if its a jar then make it a jar file url
|
||||
if (rootResource.exists()&& !rootResource.isDirectory() && !rootResource.toString().startsWith("jar:"))
|
||||
{
|
||||
Resource jarResource = JarResource.newJarResource(rootResource);
|
||||
if (jarResource.exists() && jarResource.isDirectory())
|
||||
rootResource = jarResource;
|
||||
}
|
||||
|
||||
//Set the base resource of the ContextHandler, if not already set, can also be overridden by the context xml file
|
||||
if (_contextHandler.getBaseResource() == null)
|
||||
{
|
||||
_contextHandler.setBaseResource(rootResource);
|
||||
}
|
||||
|
||||
//Use a classloader that knows about the common jetty parent loader, and also the bundle
|
||||
OSGiClassLoader classLoader = new OSGiClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps(), _bundle);
|
||||
|
||||
//if there is a context file, find it and apply it
|
||||
if (_contextFile == null && _contextHandler == null)
|
||||
throw new IllegalStateException("No context file or ContextHandler");
|
||||
|
||||
if (_contextFile != null)
|
||||
{
|
||||
//apply the contextFile, creating the ContextHandler, the DeploymentManager will register it in the ContextHandlerCollection
|
||||
Resource res = null;
|
||||
|
||||
//try to find the context file in the filesystem
|
||||
if (_contextFile.startsWith("/"))
|
||||
res = getFileAsResource(_contextFile);
|
||||
|
||||
//try to find it relative to jetty home
|
||||
if (res == null)
|
||||
{
|
||||
//See if the specific server we are related to has jetty.home set
|
||||
String jettyHome = (String)getServerInstanceWrapper().getServer().getAttribute(OSGiServerConstants.JETTY_HOME);
|
||||
if (jettyHome != null)
|
||||
res = getFileAsResource(jettyHome, _contextFile);
|
||||
|
||||
//try to see if a SystemProperty for jetty.home is set
|
||||
if (res == null)
|
||||
{
|
||||
jettyHome = System.getProperty(OSGiServerConstants.JETTY_HOME);
|
||||
|
||||
if (jettyHome != null)
|
||||
{
|
||||
if (jettyHome.startsWith("\"") || jettyHome.startsWith("'"))
|
||||
jettyHome = jettyHome.substring(1);
|
||||
if (jettyHome.endsWith("\"") || (jettyHome.endsWith("'")))
|
||||
jettyHome = jettyHome.substring(0,jettyHome.length()-1);
|
||||
|
||||
res = getFileAsResource(jettyHome, _contextFile);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("jetty home context file:"+res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//try to find it relative to an override location that has been specified
|
||||
if (res == null)
|
||||
{
|
||||
if (bundleOverrideLocation != null)
|
||||
{
|
||||
res = getFileAsResource(Resource.newResource(bundleOverrideLocation).getFile(), _contextFile);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Bundle override location context file:"+res);
|
||||
}
|
||||
}
|
||||
|
||||
//try to find it relative to the bundle in which it is being deployed
|
||||
if (res == null)
|
||||
{
|
||||
if (_contextFile.startsWith("./"))
|
||||
_contextFile = _contextFile.substring(1);
|
||||
|
||||
if (!_contextFile.startsWith("/"))
|
||||
_contextFile = "/" + _contextFile;
|
||||
|
||||
URL contextURL = _bundle.getEntry(_contextFile);
|
||||
if (contextURL != null)
|
||||
res = Resource.newResource(contextURL);
|
||||
}
|
||||
|
||||
//apply the context xml file, either to an existing ContextHandler, or letting the
|
||||
//it create the ContextHandler as necessary
|
||||
if (res != null)
|
||||
{
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
LOG.debug("Context classloader = " + cl);
|
||||
try
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
|
||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(res.getInputStream());
|
||||
HashMap properties = new HashMap();
|
||||
//put the server instance in
|
||||
properties.put("Server", getServerInstanceWrapper().getServer());
|
||||
//put in the location of the bundle root
|
||||
properties.put("bundle.root", rootResource.toString());
|
||||
|
||||
// insert the bundle's location as a property.
|
||||
xmlConfiguration.getProperties().putAll(properties);
|
||||
|
||||
if (_contextHandler == null)
|
||||
_contextHandler = (ContextHandler) xmlConfiguration.configure();
|
||||
else
|
||||
xmlConfiguration.configure(_contextHandler);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Set up the class loader we created
|
||||
_contextHandler.setClassLoader(classLoader);
|
||||
|
||||
|
||||
//If a bundle/service property specifies context path, let it override the context xml
|
||||
String contextPath = (String)_properties.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
|
||||
if (contextPath == null)
|
||||
contextPath = (String)_properties.get(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH);
|
||||
if (contextPath != null)
|
||||
_contextHandler.setContextPath(contextPath);
|
||||
}
|
||||
|
||||
|
||||
private Resource getFileAsResource (String dir, String file)
|
||||
{
|
||||
Resource r = null;
|
||||
try
|
||||
{
|
||||
File asFile = new File (dir, file);
|
||||
if (asFile.exists())
|
||||
r = Resource.newResource(asFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
r = null;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private Resource getFileAsResource (String file)
|
||||
{
|
||||
Resource r = null;
|
||||
try
|
||||
{
|
||||
File asFile = new File (file);
|
||||
if (asFile.exists())
|
||||
r = Resource.newResource(asFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
r = null;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private Resource getFileAsResource (File dir, String file)
|
||||
{
|
||||
Resource r = null;
|
||||
try
|
||||
{
|
||||
File asFile = new File (dir, file);
|
||||
if (asFile.exists())
|
||||
r = Resource.newResource(asFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
r = null;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public AbstractContextProvider(ServerInstanceWrapper wrapper)
|
||||
{
|
||||
_serverWrapper = wrapper;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public ServerInstanceWrapper getServerInstanceWrapper()
|
||||
{
|
||||
return _serverWrapper;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.deploy.AppProvider#createContextHandler(org.eclipse.jetty.deploy.App)
|
||||
*/
|
||||
public ContextHandler createContextHandler(App app) throws Exception
|
||||
{
|
||||
if (app == null)
|
||||
return null;
|
||||
if (!(app instanceof BundleApp))
|
||||
throw new IllegalStateException(app+" is not a BundleApp");
|
||||
|
||||
//Create a ContextHandler suitable to deploy in OSGi
|
||||
return ((BundleApp)app).getContextHandler();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setDeploymentManager(DeploymentManager deploymentManager)
|
||||
{
|
||||
_deploymentManager = deploymentManager;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public DeploymentManager getDeploymentManager()
|
||||
{
|
||||
return _deploymentManager;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,15 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2012 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;
|
||||
|
||||
|
||||
|
@ -33,6 +45,11 @@ import org.osgi.service.packageadmin.PackageAdmin;
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* AbstractWebAppProvider
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractWebAppProvider extends AbstractLifeCycle implements AppProvider
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(AbstractWebAppProvider.class);
|
||||
|
@ -165,6 +182,8 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement
|
|||
public void configureWebApp()
|
||||
throws Exception
|
||||
{
|
||||
|
||||
//TODO turn this around and let any context.xml file get applied first, and have the properties override
|
||||
_webApp.setContextPath(_contextPath);
|
||||
|
||||
String overrideBundleInstallLocation = (String)_properties.get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE);
|
||||
|
@ -332,6 +351,7 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement
|
|||
|
||||
Thread.currentThread().setContextClassLoader(_webApp.getClassLoader());
|
||||
|
||||
//TODO replace this with getting the InputStream so we don't cache in URL
|
||||
// find if there is a META-INF/context.xml file
|
||||
URL contextXmlUrl = _bundle.getEntry("/META-INF/jetty-webapp-context.xml");
|
||||
if (contextXmlUrl == null) return;
|
||||
|
@ -363,7 +383,7 @@ public abstract class AbstractWebAppProvider extends AbstractLifeCycle implement
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public AbstractWebAppProvider (ServerInstanceWrapper wrapper)
|
||||
{
|
||||
_serverWrapper = wrapper;
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashMap;
|
||||
|
@ -22,20 +20,11 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.deploy.AppProvider;
|
||||
import org.eclipse.jetty.deploy.DeploymentManager;
|
||||
import org.eclipse.jetty.deploy.util.FileID;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory;
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader;
|
||||
import org.eclipse.jetty.osgi.boot.utils.OSGiClassLoader;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
@ -48,211 +37,26 @@ import org.osgi.framework.ServiceRegistration;
|
|||
*
|
||||
* Handles deploying bundles that define a context xml file for configuring them.
|
||||
*
|
||||
* Also able to deploy non-webapp, generic ContextHandlers that have been registered as an osgi service.
|
||||
*
|
||||
*/
|
||||
public class BundleContextProvider extends AbstractLifeCycle implements AppProvider, BundleProvider, ServiceProvider
|
||||
public class BundleContextProvider extends AbstractContextProvider implements BundleProvider
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(BundleContextProvider.class);
|
||||
private static final Logger LOG = Log.getLogger(AbstractContextProvider.class);
|
||||
|
||||
|
||||
private DeploymentManager _deploymentManager;
|
||||
|
||||
private Map<String, App> _appMap = new HashMap<String, App>();
|
||||
|
||||
private Map<Bundle, List<App>> _bundleMap = new HashMap<Bundle, List<App>>();
|
||||
|
||||
private ServerInstanceWrapper _wrapper;
|
||||
|
||||
private ServiceRegistration _serviceRegForBundles;
|
||||
|
||||
private ServiceRegistration _serviceRegForServices;
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* BundleApp
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class BundleApp extends App
|
||||
{
|
||||
private String _contextFile;
|
||||
private Bundle _bundle;
|
||||
private ContextHandler _contextHandler;
|
||||
private OSGiClassLoader _classloader;
|
||||
|
||||
public BundleApp(DeploymentManager manager, AppProvider provider, String originId, Bundle bundle, String contextFile)
|
||||
{
|
||||
super(manager, provider, originId);
|
||||
_bundle = bundle;
|
||||
_contextFile = contextFile;
|
||||
}
|
||||
|
||||
|
||||
public String getContextFile ()
|
||||
{
|
||||
return _contextFile;
|
||||
}
|
||||
|
||||
|
||||
public ContextHandler getContextHandler()
|
||||
throws Exception
|
||||
{
|
||||
if (_contextHandler != null)
|
||||
return _contextHandler;
|
||||
|
||||
createContextHandler();
|
||||
return _contextHandler;
|
||||
}
|
||||
|
||||
public void createContextHandler()
|
||||
throws Exception
|
||||
{
|
||||
if (_contextFile == null)
|
||||
throw new IllegalStateException ("No contextFile");
|
||||
|
||||
//apply the contextFile, creating the ContextHandler, the DeploymentManager will register it in the ContextHandlerCollection
|
||||
Resource res = null;
|
||||
|
||||
//try to find the context file in the filesystem
|
||||
if (_contextFile.startsWith("/"))
|
||||
res = getFileAsResource(_contextFile);
|
||||
|
||||
//try to find it relative to jetty home
|
||||
if (res == null)
|
||||
{
|
||||
//See if the specific server we are related to has jetty.home set
|
||||
String jettyHome = (String)_wrapper.getServer().getAttribute(OSGiServerConstants.JETTY_HOME);
|
||||
if (jettyHome != null)
|
||||
res = getFileAsResource(jettyHome, _contextFile);
|
||||
|
||||
//try to see if a SystemProperty for jetty.home is set
|
||||
if (res == null)
|
||||
{
|
||||
jettyHome = System.getProperty(OSGiServerConstants.JETTY_HOME);
|
||||
|
||||
if (jettyHome.startsWith("\"") || jettyHome.startsWith("'"))
|
||||
jettyHome = jettyHome.substring(1);
|
||||
if (jettyHome.endsWith("\"") || (jettyHome.endsWith("'")))
|
||||
jettyHome = jettyHome.substring(0,jettyHome.length()-1);
|
||||
|
||||
res = getFileAsResource(jettyHome, _contextFile);
|
||||
}
|
||||
}
|
||||
|
||||
//try to find it relative to the bundle in which it is being deployed
|
||||
if (res == null)
|
||||
{
|
||||
if (_contextFile.startsWith("./"))
|
||||
_contextFile = _contextFile.substring(1);
|
||||
|
||||
if (!_contextFile.startsWith("/"))
|
||||
_contextFile = "/" + _contextFile;
|
||||
|
||||
URL contextURL = _bundle.getEntry(_contextFile);
|
||||
if (contextURL != null)
|
||||
res = Resource.newResource(contextURL);
|
||||
}
|
||||
|
||||
if (res != null)
|
||||
{
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
LOG.debug("Context classloader = " + cl);
|
||||
try
|
||||
{
|
||||
//Use a classloader that knows about the common jetty parent loader, and also the bundle
|
||||
|
||||
OSGiClassLoader classLoader = new OSGiClassLoader(_wrapper.getParentClassLoaderForWebapps(),
|
||||
_bundle);
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(res.getInputStream());
|
||||
HashMap properties = new HashMap();
|
||||
properties.put("Server", _wrapper.getServer());
|
||||
|
||||
// insert the bundle's location as a property.
|
||||
//setThisBundleHomeProperty(_bundle, properties, overrideBundleInstallLocation);
|
||||
xmlConfiguration.getProperties().putAll(properties);
|
||||
|
||||
if (_contextHandler == null)
|
||||
_contextHandler = (ContextHandler) xmlConfiguration.configure();
|
||||
else
|
||||
xmlConfiguration.configure(_contextHandler);
|
||||
|
||||
_contextHandler.setClassLoader(classLoader);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set the property "this.bundle.install" to point to the location
|
||||
* of the bundle. Useful when <SystemProperty name="this.bundle.home"/> is
|
||||
* used.
|
||||
*/
|
||||
private void setThisBundleHomeProperty(Bundle bundle, HashMap<String, Object> properties, String overrideBundleInstallLocation)
|
||||
{
|
||||
try
|
||||
{
|
||||
File location =
|
||||
overrideBundleInstallLocation != null ?
|
||||
new File(overrideBundleInstallLocation) :
|
||||
BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bundle);
|
||||
properties.put("this.bundle.install", location.getCanonicalPath());
|
||||
properties.put("this.bundle.install.url", bundle.getEntry("/").toString());
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
LOG.warn("Unable to set 'this.bundle.install' " + " for the bundle " + bundle.getSymbolicName(), t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Resource getFileAsResource (String dir, String file)
|
||||
{
|
||||
Resource r = null;
|
||||
try
|
||||
{
|
||||
File asFile = new File (dir, file);
|
||||
if (asFile.exists())
|
||||
r = Resource.newResource(asFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
r = null;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private Resource getFileAsResource (String file)
|
||||
{
|
||||
Resource r = null;
|
||||
try
|
||||
{
|
||||
File asFile = new File (file);
|
||||
if (asFile.exists())
|
||||
r = Resource.newResource(asFile);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
r = null;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public BundleContextProvider(ServerInstanceWrapper wrapper)
|
||||
{
|
||||
_wrapper = wrapper;
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
|
||||
|
@ -262,10 +66,8 @@ public class BundleContextProvider extends AbstractLifeCycle implements AppProvi
|
|||
{
|
||||
//register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to
|
||||
Dictionary<String,String> properties = new Hashtable<String,String>();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, _wrapper.getManagedServerName());
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
|
||||
_serviceRegForBundles = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(BundleProvider.class.getName(), this, properties);
|
||||
//register as an osgi service for deploying contexts, advertising the name of the jetty Server instance we are related to
|
||||
_serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties);
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
@ -285,43 +87,10 @@ public class BundleContextProvider extends AbstractLifeCycle implements AppProvi
|
|||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (_serviceRegForServices != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceRegForServices.unregister();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
super.doStop();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setDeploymentManager(DeploymentManager deploymentManager)
|
||||
{
|
||||
_deploymentManager = deploymentManager;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.deploy.AppProvider#createContextHandler(org.eclipse.jetty.deploy.App)
|
||||
*/
|
||||
public ContextHandler createContextHandler(App app) throws Exception
|
||||
{
|
||||
if (app == null)
|
||||
return null;
|
||||
if (!(app instanceof BundleApp))
|
||||
throw new IllegalStateException(app+" is not a BundleApp");
|
||||
|
||||
//Create a ContextHandler suitable to deploy in OSGi
|
||||
return ((BundleApp)app).getContextHandler();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
|
@ -335,6 +104,9 @@ public class BundleContextProvider extends AbstractLifeCycle implements AppProvi
|
|||
return false;
|
||||
|
||||
String contextFiles = (String)bundle.getHeaders().get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH);
|
||||
if (contextFiles == null)
|
||||
contextFiles = (String)bundle.getHeaders().get(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
|
||||
|
||||
if (contextFiles == null)
|
||||
return false;
|
||||
|
||||
|
@ -346,7 +118,7 @@ public class BundleContextProvider extends AbstractLifeCycle implements AppProvi
|
|||
for (String contextFile : tmp)
|
||||
{
|
||||
String originId = bundle.getSymbolicName() + "-" + bundle.getVersion().toString() + "-"+contextFile;
|
||||
BundleApp app = new BundleApp(_deploymentManager, this, originId, bundle, contextFile);
|
||||
BundleApp app = new BundleApp(getDeploymentManager(), this, originId, bundle, contextFile);
|
||||
_appMap.put(originId,app);
|
||||
List<App> apps = _bundleMap.get(bundle);
|
||||
if (apps == null)
|
||||
|
@ -355,7 +127,7 @@ public class BundleContextProvider extends AbstractLifeCycle implements AppProvi
|
|||
_bundleMap.put(bundle, apps);
|
||||
}
|
||||
apps.add(app);
|
||||
_deploymentManager.addApp(app);
|
||||
getDeploymentManager().addApp(app);
|
||||
}
|
||||
|
||||
return added; //true if even 1 context from this bundle was added
|
||||
|
@ -378,32 +150,12 @@ public class BundleContextProvider extends AbstractLifeCycle implements AppProvi
|
|||
for (App app:apps)
|
||||
{
|
||||
_appMap.remove(app.getOriginId());
|
||||
_deploymentManager.removeApp(app);
|
||||
getDeploymentManager().removeApp(app);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
return removed; //true if even 1 context was removed associated with this bundle
|
||||
}
|
||||
|
||||
|
||||
public boolean serviceAdded (ServiceReference serviceRef, ContextHandler context)
|
||||
{
|
||||
//TODO deploy a contexthandler that some other package has created as a service
|
||||
if (context == null || serviceRef == null)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean serviceRemoved (ServiceReference serviceRef, ContextHandler context)
|
||||
{
|
||||
//TODO remove a contexthandler that was a service
|
||||
if (context == null || serviceRef == null)
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.osgi.framework.ServiceRegistration;
|
|||
*/
|
||||
public class BundleWebAppProvider extends AbstractWebAppProvider implements BundleProvider
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(BundleWebAppProvider.class);
|
||||
private static final Logger LOG = Log.getLogger(AbstractWebAppProvider.class);
|
||||
|
||||
/**
|
||||
* Map of Bundle to App. Used when a Bundle contains a webapp.
|
||||
|
|
|
@ -123,7 +123,6 @@ public class JettyBootstrapActivator implements BundleActivator
|
|||
}
|
||||
if (_jettyContextHandlerTracker != null)
|
||||
{
|
||||
_jettyContextHandlerTracker.stop();
|
||||
context.removeServiceListener(_jettyContextHandlerTracker);
|
||||
_jettyContextHandlerTracker = null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
package org.eclipse.jetty.osgi.boot;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.deploy.App;
|
||||
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
/**
|
||||
* ServiceContextProvider
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ServiceContextProvider extends AbstractContextProvider implements ServiceProvider
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(AbstractContextProvider.class);
|
||||
|
||||
private Map<ServiceReference, App> _serviceMap = new HashMap<ServiceReference, App>();
|
||||
|
||||
private ServiceRegistration _serviceRegForServices;
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public ServiceContextProvider(ServerInstanceWrapper wrapper)
|
||||
{
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean serviceAdded (ServiceReference serviceRef, ContextHandler context)
|
||||
{
|
||||
//TODO deploy a contexthandler that some other package has created as a service
|
||||
if (context == null || serviceRef == null)
|
||||
return false;
|
||||
|
||||
ClassLoader cl = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps());
|
||||
try
|
||||
{
|
||||
//See if there is a context file to apply to this pre-made context
|
||||
String contextFile = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH);
|
||||
if (contextFile == null)
|
||||
contextFile = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
|
||||
|
||||
String[] keys = serviceRef.getPropertyKeys();
|
||||
Dictionary properties = new Hashtable<String, Object>();
|
||||
if (keys != null)
|
||||
{
|
||||
for (String key:keys)
|
||||
properties.put(key, serviceRef.getProperty(key));
|
||||
}
|
||||
Bundle bundle = serviceRef.getBundle();
|
||||
String originId = bundle.getSymbolicName() + "-" + bundle.getVersion().toString() + "-"+contextFile;
|
||||
BundleApp app = new BundleApp(getDeploymentManager(), this, bundle, properties, contextFile, originId);
|
||||
app.setContextHandler(context); //set the pre=made ContextHandler instance
|
||||
_serviceMap.put(serviceRef, app);
|
||||
getDeploymentManager().addApp(app);
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean serviceRemoved (ServiceReference serviceRef, ContextHandler context)
|
||||
{
|
||||
|
||||
if (context == null || serviceRef == null)
|
||||
return false;
|
||||
|
||||
App app = _serviceMap.remove(serviceRef);
|
||||
if (app != null)
|
||||
{
|
||||
getDeploymentManager().removeApp(app);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
//register as an osgi service for deploying contexts defined in a bundle, advertising the name of the jetty Server instance we are related to
|
||||
Dictionary<String,String> properties = new Hashtable<String,String>();
|
||||
properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
|
||||
|
||||
//register as an osgi service for deploying contexts, advertising the name of the jetty Server instance we are related to
|
||||
_serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties);
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
//unregister ourselves
|
||||
if (_serviceRegForServices != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceRegForServices.unregister();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
super.doStop();
|
||||
}
|
||||
}
|
|
@ -60,7 +60,6 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser
|
|||
|
||||
|
||||
WebAppContext webApp = (WebAppContext)context;
|
||||
System.err.println("Casting to webapp");
|
||||
Dictionary properties = new Hashtable<String,String>();
|
||||
|
||||
String contextPath = (String)serviceRef.getProperty(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
|
||||
|
|
|
@ -33,6 +33,9 @@ import org.osgi.framework.Bundle;
|
|||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* DefaultJettyAtJettyHomeHelper
|
||||
*
|
||||
*
|
||||
* Called by the {@link JettyBootstrapActivator} during the starting of the
|
||||
* bundle. If the system property 'jetty.home' is defined and points to a
|
||||
* folder, then setup the corresponding jetty server.
|
||||
|
@ -48,8 +51,6 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
*/
|
||||
public static final String JETTY_ETC_FILES = OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Set of config files to apply to a jetty Server instance if none are supplied by SYS_PROP_JETTY_ETC_FILES
|
||||
*/
|
||||
|
@ -59,7 +60,9 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
* Default location within bundle of a jetty home dir.
|
||||
*/
|
||||
public static final String DEFAULT_JETTYHOME = "/jettyhome";
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Called by the JettyBootStrapActivator. If the system property jetty.home
|
||||
* is defined and points to a folder, creates a corresponding jetty
|
||||
|
@ -110,7 +113,6 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
else if (jettyHomeBundleSysProp != null)
|
||||
{
|
||||
jettyHomeBundleSysProp = resolvePropertyValue(jettyHomeBundleSysProp);
|
||||
System.err.println("jetty home bundle sysprop = "+jettyHomeBundleSysProp);
|
||||
for (Bundle b : bundleContext.getBundles())
|
||||
{
|
||||
if (b.getSymbolicName().equals(jettyHomeBundleSysProp))
|
||||
|
@ -151,7 +153,10 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
//register the Server instance as an OSGi service.
|
||||
bundleContext.registerService(Server.class.getName(), server, properties);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Minimum setup for the location of the configuration files given a
|
||||
* jettyhome folder. Reads the system property jetty.etc.config.urls and
|
||||
|
@ -185,7 +190,9 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Minimum setup for the location of the configuration files given a
|
||||
* configuration embedded inside a bundle. Reads the system property
|
||||
|
@ -197,7 +204,6 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
*/
|
||||
private static String getJettyConfigurationURLs(Bundle configurationBundle)
|
||||
{
|
||||
System.err.println("GETTING JETTY PROPS FROM BUNDLE: "+configurationBundle.getSymbolicName());
|
||||
String files = System.getProperty(JETTY_ETC_FILES, DEFAULT_JETTY_ETC_FILES);
|
||||
|
||||
StringTokenizer tokenizer = new StringTokenizer(files, ";,", false);
|
||||
|
@ -214,10 +220,8 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
else
|
||||
{
|
||||
//relative file path
|
||||
System.err.println("Finding "+etcFile+" in bundle "+configurationBundle);
|
||||
Enumeration<URL> enUrls = BundleFileLocatorHelperFactory.getFactory().getHelper().findEntries(configurationBundle, etcFile);
|
||||
|
||||
|
||||
|
||||
// default for org.eclipse.osgi.boot where we look inside
|
||||
// jettyhome for the default embedded configuration.
|
||||
// default inside jettyhome. this way fragments to the bundle
|
||||
|
@ -229,8 +233,6 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
LOG.info("Configuring jetty from bundle: "
|
||||
+ configurationBundle.getSymbolicName()
|
||||
+ " with "+tmp);
|
||||
|
||||
System.err.println(configurationBundle.getEntry(tmp));
|
||||
}
|
||||
if (enUrls == null || !enUrls.hasMoreElements())
|
||||
{
|
||||
|
@ -241,7 +243,6 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
while (enUrls.hasMoreElements())
|
||||
{
|
||||
URL url = BundleFileLocatorHelperFactory.getFactory().getHelper().getFileURL(enUrls.nextElement());
|
||||
System.err.println("Got url: "+url +" from "+url.getClass().getName());
|
||||
appendToCommaSeparatedList(res, url.toString());
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +250,9 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private static void appendToCommaSeparatedList(StringBuilder buffer, String value)
|
||||
{
|
||||
if (buffer.length() != 0)
|
||||
|
@ -258,7 +261,9 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
}
|
||||
buffer.append(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private static void setProperty(Dictionary<String,String> properties, String key, String value)
|
||||
{
|
||||
if (value != null)
|
||||
|
@ -266,7 +271,9 @@ public class DefaultJettyAtJettyHomeHelper
|
|||
properties.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* recursively substitute the ${sysprop} by their actual system property.
|
||||
* ${sysprop,defaultvalue} will use 'defaultvalue' as the value if no
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.eclipse.jetty.osgi.boot.BundleContextProvider;
|
|||
import org.eclipse.jetty.osgi.boot.BundleWebAppProvider;
|
||||
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
import org.eclipse.jetty.osgi.boot.ServiceContextProvider;
|
||||
import org.eclipse.jetty.osgi.boot.ServiceWebAppProvider;
|
||||
import org.eclipse.jetty.osgi.boot.internal.jsp.TldLocatableURLClassloader;
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.BundleFileLocatorHelperFactory;
|
||||
|
@ -79,17 +80,22 @@ public class ServerInstanceWrapper
|
|||
private ClassLoader _commonParentClassLoaderForWebapps;
|
||||
|
||||
private DeploymentManager _deploymentManager;
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public ServerInstanceWrapper(String managedServerName)
|
||||
{
|
||||
_managedServerName = managedServerName;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String getManagedServerName()
|
||||
{
|
||||
return _managedServerName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* The classloader that should be the parent classloader for each webapp
|
||||
* deployed on this server.
|
||||
|
@ -100,7 +106,9 @@ public class ServerInstanceWrapper
|
|||
{
|
||||
return _commonParentClassLoaderForWebapps;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The deployment manager registered on this server.
|
||||
*/
|
||||
|
@ -108,7 +116,9 @@ public class ServerInstanceWrapper
|
|||
{
|
||||
return _deploymentManager;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The app provider registered on this server.
|
||||
*/
|
||||
|
@ -117,7 +127,7 @@ public class ServerInstanceWrapper
|
|||
return _server;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return The collection of context handlers
|
||||
*/
|
||||
|
@ -125,7 +135,9 @@ public class ServerInstanceWrapper
|
|||
{
|
||||
return _ctxtCollection;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void start(Server server, Dictionary props) throws Exception
|
||||
{
|
||||
_server = server;
|
||||
|
@ -140,7 +152,7 @@ public class ServerInstanceWrapper
|
|||
List<File> shared = sharedURLs != null ? extractFiles(sharedURLs) : null;
|
||||
libExtClassLoader = LibExtClassLoaderHelper.createLibExtClassLoader(shared, null, server, JettyBootstrapActivator.class.getClassLoader());
|
||||
|
||||
System.err.println("LibExtClassLoader = "+libExtClassLoader);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("LibExtClassLoader = "+libExtClassLoader);
|
||||
|
||||
Thread.currentThread().setContextClassLoader(libExtClassLoader);
|
||||
|
||||
|
@ -148,16 +160,12 @@ public class ServerInstanceWrapper
|
|||
|
||||
init();
|
||||
|
||||
// now that we have an app provider we can call the registration
|
||||
// customizer.
|
||||
|
||||
URL[] jarsWithTlds = getJarsWithTlds();
|
||||
_commonParentClassLoaderForWebapps = jarsWithTlds == null ? libExtClassLoader : new TldLocatableURLClassloader(libExtClassLoader, jarsWithTlds);
|
||||
|
||||
System.err.println("common classloader = "+_commonParentClassLoaderForWebapps);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("common classloader = "+_commonParentClassLoaderForWebapps);
|
||||
|
||||
server.start();
|
||||
//_webBundleDeployerHelper = new WebBundleDeployerHelper(this);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -180,7 +188,7 @@ public class ServerInstanceWrapper
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void stop()
|
||||
{
|
||||
try
|
||||
|
@ -195,7 +203,9 @@ public class ServerInstanceWrapper
|
|||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* TODO: right now only the jetty-jsp bundle is scanned for common taglibs.
|
||||
* Should support a way to plug more bundles that contain taglibs.
|
||||
|
@ -242,7 +252,9 @@ public class ServerInstanceWrapper
|
|||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void configure(Server server, Dictionary props) throws Exception
|
||||
{
|
||||
String jettyConfigurationUrls = (String) props.get(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS);
|
||||
|
@ -250,8 +262,10 @@ public class ServerInstanceWrapper
|
|||
if (jettyConfigurations == null || jettyConfigurations.isEmpty()) { return; }
|
||||
Map<String, Object> id_map = new HashMap<String, Object>();
|
||||
|
||||
//TODO need to put in the id of the server being configured
|
||||
//Put in a mapping for the id "Server" and the name of the server as the instance being configured
|
||||
id_map.put("Server", server);
|
||||
id_map.put((String)props.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME), server);
|
||||
|
||||
Map<String, String> properties = new HashMap<String, String>();
|
||||
Enumeration<Object> en = props.keys();
|
||||
while (en.hasMoreElements())
|
||||
|
@ -383,10 +397,20 @@ public class ServerInstanceWrapper
|
|||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//TODO add ServiceContextProvider
|
||||
if (!providerClassNames.contains(ServiceContextProvider.class.getName()))
|
||||
{
|
||||
try
|
||||
{
|
||||
ServiceContextProvider contextProvider = new ServiceContextProvider(this);
|
||||
_deploymentManager.addAppProvider(contextProvider);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,42 +43,29 @@ import org.osgi.framework.ServiceReference;
|
|||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
/**
|
||||
* When a {@link ContextHandler} service is activated we look into it and if the
|
||||
* corresponding webapp is actually not configured then we go and register it.
|
||||
* <p>
|
||||
* The idea is to always go through this class when we deploy a new webapp on
|
||||
* jetty.
|
||||
* </p>
|
||||
* <p>
|
||||
* We are exposing each web-application as an OSGi service. This lets us update
|
||||
* the webapps and stop/start them directly at the OSGi layer. It also give us
|
||||
* many ways to declare those services: Declarative Services for example. <br/>
|
||||
* It is a bit different from the way the HttpService works where we would have
|
||||
* a WebappService and we woud register a webapp onto it. <br/>
|
||||
* It does not go against RFC-66 nor does it prevent us from supporting the
|
||||
* WebappContainer semantics.
|
||||
* </p>
|
||||
* JettyContextHandlerServiceTracker
|
||||
*
|
||||
* When a {@link ContextHandler} is activated as an osgi service we find a jetty deployer
|
||||
* for it. The ContextHandler could be either a WebAppContext or any other derivative of
|
||||
* ContextHandler.
|
||||
*
|
||||
* ContextHandlers and WebApps can also be deployed into jetty without creating them as
|
||||
* osgi services. Instead, they can be deployed via manifest headers inside bundles. See
|
||||
* {@link WebBundleTrackerCustomizer}.
|
||||
*/
|
||||
public class JettyContextHandlerServiceTracker implements ServiceListener
|
||||
{
|
||||
private static Logger __logger = Log.getLogger(JettyContextHandlerServiceTracker.class.getName());
|
||||
private static Logger LOG = Log.getLogger(JettyContextHandlerServiceTracker.class);
|
||||
|
||||
public static final String FILTER = "(objectclass=" + ServiceProvider.class.getName() + ")";
|
||||
|
||||
|
||||
/**
|
||||
* The index is the bundle-symbolic-name/path/to/context/file when there is
|
||||
* such thing
|
||||
*/
|
||||
private Map<String, ServiceReference> _indexByContextFile = new HashMap<String, ServiceReference>();
|
||||
|
||||
/** in charge of detecting changes in the osgi contexts home folder. */
|
||||
private Scanner _scanner;
|
||||
|
||||
|
||||
//track all instances of deployers of webapps as bundles
|
||||
ServiceTracker _serviceTracker;
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param registry
|
||||
*/
|
||||
|
@ -90,56 +77,13 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
_serviceTracker.open();
|
||||
}
|
||||
|
||||
public void stop() throws Exception
|
||||
{
|
||||
if (_scanner != null)
|
||||
{
|
||||
_scanner.stop();
|
||||
}
|
||||
// the class that created the server is also in charge of stopping it.
|
||||
// nothing to stop in the WebappRegistrationHelper
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param contextHome Parent folder where the context files can override the
|
||||
* context files defined in the web bundles: equivalent to the
|
||||
* contexts folder in a traditional jetty installation. when
|
||||
* null, just do nothing.
|
||||
* @param managedServerName
|
||||
* @return
|
||||
*/
|
||||
protected void setupContextHomeScanner(File contextHome) throws IOException
|
||||
{
|
||||
if (contextHome == null) { return; }
|
||||
final String osgiContextHomeFolderCanonicalPath = contextHome.getCanonicalPath();
|
||||
_scanner = new Scanner();
|
||||
_scanner.setRecursive(true);
|
||||
_scanner.setReportExistingFilesOnStartup(false);
|
||||
_scanner.addListener(new Scanner.DiscreteListener()
|
||||
{
|
||||
public void fileAdded(String filename) throws Exception
|
||||
{
|
||||
// adding a file does not create a new app,
|
||||
// it just reloads it with the new custom file.
|
||||
// well, if the file does not define a context handler,
|
||||
// then in fact it does remove it.
|
||||
reloadJettyContextHandler(filename, osgiContextHomeFolderCanonicalPath);
|
||||
}
|
||||
|
||||
public void fileChanged(String filename) throws Exception
|
||||
{
|
||||
reloadJettyContextHandler(filename, osgiContextHomeFolderCanonicalPath);
|
||||
}
|
||||
|
||||
public void fileRemoved(String filename) throws Exception
|
||||
{
|
||||
// removing a file does not remove the app:
|
||||
// it just goes back to the default embedded in the bundle.
|
||||
// well, if there was no default then it does remove it.
|
||||
reloadJettyContextHandler(filename, osgiContextHomeFolderCanonicalPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Map<ServiceReference, ServiceProvider> getDeployers(String managedServerName)
|
||||
{
|
||||
if (managedServerName == null)
|
||||
|
@ -164,6 +108,7 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
return candidates;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Receives notification that a service has had a lifecycle change.
|
||||
*
|
||||
|
@ -209,85 +154,32 @@ public class JettyContextHandlerServiceTracker implements ServiceListener
|
|||
}
|
||||
case ServiceEvent.REGISTERED:
|
||||
{
|
||||
System.err.println("New Service registered that could be webapp/context");
|
||||
Bundle contributor = sr.getBundle();
|
||||
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
|
||||
ContextHandler contextHandler = (ContextHandler) context.getService(sr);
|
||||
if (contextHandler.getServer() != null)
|
||||
{
|
||||
// is configured elsewhere.
|
||||
System.err.println("Already configured");
|
||||
return;
|
||||
}
|
||||
|
||||
System.err.println("Service registered from bundle: "+contributor.getSymbolicName());
|
||||
System.err.println("war="+sr.getProperty("war"));
|
||||
|
||||
//Get a jetty deployer targetted to the named server instance, or the default one if not named
|
||||
String serverName = (String)sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
|
||||
Map<ServiceReference, ServiceProvider> candidates = getDeployers(serverName);
|
||||
if (candidates != null)
|
||||
{
|
||||
System.err.println("Got some candidates");
|
||||
boolean added = false;
|
||||
Iterator<Entry<ServiceReference, ServiceProvider>> itor = candidates.entrySet().iterator();
|
||||
while (!added && itor.hasNext())
|
||||
{
|
||||
Entry<ServiceReference, ServiceProvider> e = itor.next();
|
||||
System.err.println("Trying ServiceProvider "+e.getValue());
|
||||
added = e.getValue().serviceAdded(sr, contextHandler);
|
||||
if (added && LOG.isDebugEnabled())
|
||||
LOG.debug("Provider "+e.getValue()+" deployed "+contextHandler);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param sr
|
||||
* @return The key for a context file within the osgi contexts home folder.
|
||||
*/
|
||||
private String getSymbolicNameAndContextFileKey(ServiceReference sr)
|
||||
{
|
||||
String contextFilePath = (String) sr.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_FILE_PATH);
|
||||
if (contextFilePath != null) { return sr.getBundle().getSymbolicName() + "/" + contextFilePath; }
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the scanner when one of the context files is changed.
|
||||
*
|
||||
* @param contextFileFully
|
||||
*/
|
||||
public void reloadJettyContextHandler(String canonicalNameOfFileChanged, String osgiContextHomeFolderCanonicalPath)
|
||||
{
|
||||
String key = getNormalizedRelativePath(canonicalNameOfFileChanged, osgiContextHomeFolderCanonicalPath);
|
||||
if (key == null) { return; }
|
||||
ServiceReference sr = _indexByContextFile.get(key);
|
||||
if (sr == null)
|
||||
{
|
||||
// nothing to do?
|
||||
return;
|
||||
}
|
||||
serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED, sr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param canFilename
|
||||
* @return
|
||||
*/
|
||||
private String getNormalizedRelativePath(String canFilename, String osgiContextHomeFolderCanonicalPath)
|
||||
{
|
||||
if (!canFilename.startsWith(osgiContextHomeFolderCanonicalPath))
|
||||
{
|
||||
// why are we here: this does not look like a child of the osgi
|
||||
// contexts home.
|
||||
// warning?
|
||||
return null;
|
||||
}
|
||||
return canFilename.substring(osgiContextHomeFolderCanonicalPath.length()).replace('\\', '/');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.BundleProvider;
|
||||
import org.eclipse.jetty.osgi.boot.BundleWebAppProvider;
|
||||
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
|
||||
import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -29,8 +28,15 @@ import org.osgi.util.tracker.BundleTrackerCustomizer;
|
|||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
/**
|
||||
* WebBundleTrackerCustomizer
|
||||
*
|
||||
*
|
||||
* Support bundles that declare a webpp or context directly through headers in their
|
||||
* manifest.
|
||||
* manifest. They will be deployed to the default jetty Server instance.
|
||||
*
|
||||
* If you wish to deploy a context or webapp to a different jetty Server instance,
|
||||
* register your context/webapp as an osgi service, and set the property OSGiServerConstants.MANAGED_JETTY_SERVER_NAME
|
||||
* with the name of the Server instance you wish to depoy to.
|
||||
*
|
||||
* @author hmalphettes
|
||||
*/
|
||||
|
@ -164,20 +170,15 @@ public class WebBundleTrackerCustomizer implements BundleTrackerCustomizer
|
|||
Object[] deployers = _serviceTracker.getServices();
|
||||
if (deployers != null)
|
||||
{
|
||||
System.err.println("FOUND "+deployers.length+" FOR "+bundle.getSymbolicName());
|
||||
int i=0;
|
||||
while (!deployed && i<deployers.length)
|
||||
{
|
||||
|
||||
BundleProvider p = (BundleProvider)deployers[i];
|
||||
System.err.println("Trying deployer "+p);
|
||||
deployed = p.bundleAdded(bundle);
|
||||
i++;
|
||||
System.err.println("Deployer "+p+" returned "+deployed);
|
||||
}
|
||||
}
|
||||
else
|
||||
System.err.println("NO DEPLOYER FOUND FOR "+bundle.getSymbolicName());
|
||||
|
||||
return deployed;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
<module>jetty-osgi-httpservice</module>
|
||||
<module>jetty-osgi-equinoxtools</module>
|
||||
<module>test-jetty-osgi-webapp</module>
|
||||
<module>test-jetty-osgi-context</module>
|
||||
<module>test-jetty-osgi</module>
|
||||
</modules>
|
||||
<build>
|
||||
|
@ -73,6 +74,11 @@
|
|||
</build>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-continuation</artifactId>
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>jetty-osgi-project</artifactId>
|
||||
<version>7.6.4-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>test-jetty-osgi-context</artifactId>
|
||||
<name>Jetty :: OSGi :: Context</name>
|
||||
<description>Test Jetty OSGi bundle with a ContextHandler</description>
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.testcontext</bundle-symbolic-name>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-server</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.osgi</groupId>
|
||||
<artifactId>org.eclipse.osgi.services</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/context</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<!--
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-resources</phase>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<copy todir="target/classes/jettyhome">
|
||||
<fileset dir="jettyhome">
|
||||
<exclude name="**/*.log" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</tasks>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>artifact-jar</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-jar</id>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestFile>target/classes/META-INF/MANIFEST.MF</manifestFile>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>bundle-manifest</id>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>manifest</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-SymbolicName>org.eclipse.jetty.osgi.testcontext;singleton:=true</Bundle-SymbolicName>
|
||||
<Bundle-Name>Jetty OSGi Test Context</Bundle-Name>
|
||||
<Bundle-Activator>com.acme.osgi.Activator</Bundle-Activator>
|
||||
<Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
|
||||
<!-- disable the uses directive: jetty will accomodate pretty much any versions
|
||||
of the packages it uses; no need to reflect some tight dependency determined at
|
||||
compilation time. -->
|
||||
<_nouses>true</_nouses>
|
||||
<Import-Package>
|
||||
org.osgi.framework,
|
||||
org.osgi.service.cm;version="1.2.0",
|
||||
org.osgi.service.packageadmin,
|
||||
org.osgi.service.startlevel;version="1.0.o",
|
||||
org.osgi.service.url;version="1.0.0",
|
||||
org.osgi.util.tracker;version="1.3.0",
|
||||
org.slf4j;resolution:=optional,
|
||||
org.slf4j.spi;resolution:=optional,
|
||||
org.slf4j.helpers;resolution:=optional,
|
||||
org.xml.sax,
|
||||
org.xml.sax.helpers,
|
||||
*
|
||||
</Import-Package>
|
||||
<DynamicImport-Package>org.eclipse.jetty.*;version="[7.6,8)"</DynamicImport-Package>
|
||||
<!--Require-Bundle/-->
|
||||
<!-- Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment -->
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<Configure class="org.eclipse.jetty.server.handler.ContextHandler">
|
||||
|
||||
<!-- Get root for static content, could be on file system or this bundle -->
|
||||
<Call id="res" class="org.eclipse.jetty.util.resource.Resource" name="newResource">
|
||||
<Arg><Property name="bundle.root"/></Arg>
|
||||
</Call>
|
||||
|
||||
<Ref id="res">
|
||||
<Call id="base" name="addPath">
|
||||
<Arg>/static/</Arg>
|
||||
</Call>
|
||||
</Ref>
|
||||
|
||||
<Set name="contextPath">/unset</Set>
|
||||
|
||||
<!-- Set up the base resource for static files relative to inside bundle -->
|
||||
<Set name="baseResource">
|
||||
<Ref id="base"/>
|
||||
</Set>
|
||||
|
||||
<Set name="handler">
|
||||
<New class="org.eclipse.jetty.server.handler.ResourceHandler">
|
||||
<Set name="welcomeFiles">
|
||||
<Array type="String">
|
||||
<Item>index.html</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
<Set name="cacheControl">max-age=3600,public</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
</Configure>
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2012 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 com.acme.osgi;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.BundleException;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.util.tracker.BundleTracker;
|
||||
|
||||
/**
|
||||
* Bootstrap a ContextHandler
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class Activator implements BundleActivator
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception
|
||||
{
|
||||
ContextHandler ch = new ContextHandler();
|
||||
Dictionary props = new Hashtable();
|
||||
props.put("contextPath","/acme");
|
||||
props.put("Jetty-ContextFilePath", "acme.xml");
|
||||
context.registerService(ContextHandler.class.getName(),ch,props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the activator.
|
||||
*
|
||||
* @see
|
||||
* org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>Test OSGi Context</h1>
|
||||
<p>ContextHandler registered as a service successfully deployed.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -142,6 +142,15 @@
|
|||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- test osgi contexthandler service -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.osgi</groupId>
|
||||
<artifactId>test-jetty-osgi-context</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.ops4j.pax.exam</groupId>
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 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.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot;
|
||||
|
||||
import static org.ops4j.pax.exam.CoreOptions.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eclipse.jetty.client.ContentExchange;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
import org.eclipse.jetty.http.HttpMethods;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.ops4j.pax.exam.Inject;
|
||||
import org.ops4j.pax.exam.Option;
|
||||
import org.ops4j.pax.exam.container.def.PaxRunnerOptions;
|
||||
import org.ops4j.pax.exam.junit.Configuration;
|
||||
import org.ops4j.pax.exam.junit.JUnit4TestRunner;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* TestJettyOSGiBootContextAsService
|
||||
*
|
||||
* Tests deployment of a ContextHandler as an osgi Service.
|
||||
*
|
||||
* Tests the ServiceContextProvider.
|
||||
*
|
||||
*/
|
||||
@RunWith( JUnit4TestRunner.class )
|
||||
public class JettyOSGiBootContextAsService
|
||||
{
|
||||
private static final boolean LOGGING_ENABLED = false;
|
||||
private static final boolean REMOTE_DEBUGGING = false;
|
||||
|
||||
@Inject
|
||||
BundleContext bundleContext = null;
|
||||
|
||||
@Configuration
|
||||
public static Option[] configure()
|
||||
{
|
||||
ArrayList<Option> options = new ArrayList<Option>();
|
||||
options.addAll(TestJettyOSGiBootCore.provisionCoreJetty());
|
||||
|
||||
File base = MavenTestingUtils.getBasedir();
|
||||
File src = new File (base, "src");
|
||||
File tst = new File (src, "test");
|
||||
File config = new File (tst, "config");
|
||||
|
||||
|
||||
// Enable Logging
|
||||
if(LOGGING_ENABLED) {
|
||||
options.addAll(Arrays.asList(options(
|
||||
// install log service using pax runners profile abstraction (there are more profiles, like DS)
|
||||
// logProfile(),
|
||||
// this is how you set the default log level when using pax logging (logProfile)
|
||||
systemProperty( "org.ops4j.pax.logging.DefaultServiceLog.level" ).value( "INFO" )
|
||||
)));
|
||||
}
|
||||
|
||||
// Remote JDWP Debugging
|
||||
if(REMOTE_DEBUGGING) {
|
||||
options.addAll(Arrays.asList(options(
|
||||
// this just adds all what you write here to java vm argumenents of the (new) osgi process.
|
||||
PaxRunnerOptions.vmOption( "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5006" )
|
||||
)));
|
||||
}
|
||||
|
||||
// Standard Options
|
||||
options.addAll(Arrays.asList(options(
|
||||
PaxRunnerOptions.vmOption("-Djetty.port=9876 -Djetty.home="+config.getAbsolutePath()+" -D" + OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS +
|
||||
"=etc/jetty.xml;etc/jetty-deployer.xml;etc/jetty-selector.xml;etc/jetty-testrealm.xml"),
|
||||
|
||||
/* orbit deps */
|
||||
mavenBundle().groupId( "org.eclipse.jetty.orbit" ).artifactId( "javax.servlet.jsp" ).versionAsInProject(),
|
||||
mavenBundle().groupId( "org.eclipse.jetty.orbit" ).artifactId( "javax.servlet.jsp.jstl" ).versionAsInProject(),
|
||||
mavenBundle().groupId( "org.eclipse.jetty.orbit" ).artifactId( "javax.el" ).versionAsInProject(),
|
||||
mavenBundle().groupId( "org.eclipse.jetty.orbit" ).artifactId( "com.sun.el" ).versionAsInProject(),
|
||||
mavenBundle().groupId( "org.eclipse.jetty.orbit" ).artifactId( "org.apache.jasper.glassfish" ).versionAsInProject(),
|
||||
mavenBundle().groupId( "org.eclipse.jetty.orbit" ).artifactId( "org.apache.taglibs.standard.glassfish" ).versionAsInProject(),
|
||||
mavenBundle().groupId( "org.eclipse.jetty.orbit" ).artifactId( "org.eclipse.jdt.core" ).versionAsInProject(),
|
||||
|
||||
/* jetty-osgi deps */
|
||||
mavenBundle().groupId( "org.eclipse.jetty.osgi" ).artifactId( "jetty-osgi-boot" ).versionAsInProject().start(),
|
||||
mavenBundle().groupId( "org.eclipse.jetty.osgi" ).artifactId( "jetty-osgi-boot-jsp" ).versionAsInProject().start(),
|
||||
|
||||
//a bundle that registers a webapp as a service for the jetty osgi core to pick up and deploy
|
||||
mavenBundle().groupId( "org.eclipse.jetty.osgi" ).artifactId( "test-jetty-osgi-context" ).versionAsInProject().start()
|
||||
// mavenBundle().groupId( "org.eclipse.equinox.http" ).artifactId( "servlet" ).versionAsInProject().start()
|
||||
)));
|
||||
|
||||
return options.toArray(new Option[options.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* You will get a list of bundles installed by default
|
||||
* plus your testcase, wrapped into a bundle called pax-exam-probe
|
||||
*/
|
||||
@Test
|
||||
public void listBundles() throws Exception
|
||||
{
|
||||
Map<String,Bundle> bundlesIndexedBySymbolicName = new HashMap<String, Bundle>();
|
||||
for( Bundle b : bundleContext.getBundles() )
|
||||
{
|
||||
bundlesIndexedBySymbolicName.put(b.getSymbolicName(), b);
|
||||
System.err.println("Got " + b.getSymbolicName() + " " + b.getVersion().toString() + " " + b.getState());
|
||||
}
|
||||
|
||||
Bundle osgiBoot = bundlesIndexedBySymbolicName.get("org.eclipse.jetty.osgi.boot");
|
||||
Assert.assertNotNull("Could not find the org.eclipse.jetty.osgi.boot bundle", osgiBoot);
|
||||
Assert.assertTrue(osgiBoot.getState() == Bundle.ACTIVE);
|
||||
|
||||
Bundle testWebBundle = bundlesIndexedBySymbolicName.get("org.eclipse.jetty.osgi.testcontext");
|
||||
Assert.assertNotNull("Could not find the org.eclipse.jetty.test-jetty-osgi-context.jar bundle", testWebBundle);
|
||||
Assert.assertTrue("The bundle org.eclipse.jetty.testcontext is not correctly resolved", testWebBundle.getState() == Bundle.ACTIVE);
|
||||
|
||||
//now test the context
|
||||
HttpClient client = new HttpClient();
|
||||
client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
|
||||
try
|
||||
{
|
||||
client.start();
|
||||
|
||||
ContentExchange getExchange = new ContentExchange();
|
||||
getExchange.setURL("http://127.0.0.1:9876/acme/index.html");
|
||||
getExchange.setMethod(HttpMethods.GET);
|
||||
|
||||
client.send(getExchange);
|
||||
int state = getExchange.waitForDone();
|
||||
Assert.assertEquals("state should be done", HttpExchange.STATUS_COMPLETED, state);
|
||||
|
||||
String content = null;
|
||||
int responseStatus = getExchange.getResponseStatus();
|
||||
Assert.assertEquals(HttpStatus.OK_200, responseStatus);
|
||||
if (responseStatus == HttpStatus.OK_200) {
|
||||
content = getExchange.getResponseContent();
|
||||
}
|
||||
Assert.assertTrue(content.indexOf("<h1>Test OSGi Context</h1>") != -1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -52,6 +52,13 @@ import org.osgi.service.http.HttpService;
|
|||
|
||||
|
||||
/**
|
||||
* TestJettyOSGiBootCore
|
||||
*
|
||||
* Tests deploying a bundle (org.eclipse.jetty.osgi.httpservice) that contains a context xml file
|
||||
* that starts up the equinox http servlet.
|
||||
*
|
||||
* This tests the BundleContextProvider.
|
||||
*
|
||||
* Pax-Exam to make sure the jetty-osgi-boot can be started along with the httpservice web-bundle.
|
||||
* Then make sure we can deploy an OSGi service on the top of this.
|
||||
*/
|
||||
|
|
|
@ -42,6 +42,12 @@ import org.osgi.framework.Bundle;
|
|||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* TestJettyOSGiBootWebAppAsService
|
||||
*
|
||||
* Tests deployment of a WebAppContext as an osgi Service.
|
||||
*
|
||||
* Tests the ServiceWebAppProvider.
|
||||
*
|
||||
* Pax-Exam to make sure the jetty-osgi-boot can be started along with the httpservice web-bundle.
|
||||
* Then make sure we can deploy an OSGi service on the top of this.
|
||||
*/
|
||||
|
|
|
@ -44,6 +44,12 @@ import org.osgi.framework.Bundle;
|
|||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* TestJettyOSGiBootWithJsp
|
||||
*
|
||||
*
|
||||
* Tests deploying a war (standard jetty test webapp). Tests the BundleWebAppProvider.
|
||||
*
|
||||
*
|
||||
* Pax-Exam to make sure the jetty-osgi-boot can be started along with the httpservice web-bundle.
|
||||
* Then make sure we can deploy an OSGi service on the top of this.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue