This commit is contained in:
Jan Bartel 2016-07-27 20:12:10 +10:00
parent 2f1d2dac72
commit 37fa778ea0
20 changed files with 588 additions and 706 deletions

View File

@ -27,11 +27,15 @@ import java.util.Map;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.BundleTracker;
/**
* BundleContextProvider
@ -47,6 +51,62 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu
private Map<Bundle, List<App>> _bundleMap = new HashMap<Bundle, List<App>>();
private ServiceRegistration _serviceRegForBundles;
private BundleTracker _tracker;
public class ContextBundleTracker extends BundleTracker
{
protected String _managedServerName;
public ContextBundleTracker (BundleContext bundleContext, String managedServerName)
{
super (bundleContext, Bundle.ACTIVE | Bundle.STOPPING,null);
_managedServerName = managedServerName;
}
/**
* @see org.osgi.util.tracker.BundleTracker#addingBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent)
*/
@Override
public Object addingBundle(Bundle bundle, BundleEvent event)
{
try
{
String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
if ((StringUtil.isBlank(serverName) && _managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME))
|| (!StringUtil.isBlank(serverName) && (serverName.equals(_managedServerName))))
{
if (bundleAdded (bundle))
return bundle;
}
}
catch (Exception e)
{
LOG.warn(e);
}
return null;
}
/**
* @see org.osgi.util.tracker.BundleTracker#removedBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent, java.lang.Object)
*/
@Override
public void removedBundle(Bundle bundle, BundleEvent event, Object object)
{
try
{
bundleRemoved(bundle);
}
catch (Exception e)
{
LOG.warn(e);
}
}
}
/* ------------------------------------------------------------ */
public BundleContextProvider(ServerInstanceWrapper wrapper)
@ -59,6 +119,10 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu
@Override
protected void doStart() throws Exception
{
//Track bundles that are ContextHandlers that should be deployed
_tracker = new ContextBundleTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), getServerInstanceWrapper().getManagedServerName());
_tracker.open();
//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());
@ -70,6 +134,8 @@ public class BundleContextProvider extends AbstractContextProvider implements Bu
@Override
protected void doStop() throws Exception
{
_tracker.close();
//unregister ourselves
if (_serviceRegForBundles != null)
{

View File

@ -26,11 +26,15 @@ import java.util.Map;
import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
import org.eclipse.jetty.osgi.boot.utils.Util;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.BundleTracker;
/**
* BundleWebAppProvider
@ -48,6 +52,62 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund
private ServiceRegistration _serviceRegForBundles;
private WebAppTracker _webappTracker;
public class WebAppTracker extends BundleTracker
{
protected String _managedServerName;
public WebAppTracker (BundleContext bundleContext, String managedServerName)
{
super (bundleContext, Bundle.ACTIVE | Bundle.STOPPING,null);
_managedServerName = managedServerName;
}
/**
* @see org.osgi.util.tracker.BundleTracker#addingBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent)
*/
@Override
public Object addingBundle(Bundle bundle, BundleEvent event)
{
try
{
String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
if ((StringUtil.isBlank(serverName) && _managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME))
|| (!StringUtil.isBlank(serverName) && (serverName.equals(_managedServerName))))
{
if (bundleAdded (bundle))
return bundle;
}
}
catch (Exception e)
{
LOG.warn(e);
}
return null;
}
/**
* @see org.osgi.util.tracker.BundleTracker#removedBundle(org.osgi.framework.Bundle, org.osgi.framework.BundleEvent, java.lang.Object)
*/
@Override
public void removedBundle(Bundle bundle, BundleEvent event, Object object)
{
try
{
bundleRemoved(bundle);
}
catch (Exception e)
{
LOG.warn(e);
}
}
}
/* ------------------------------------------------------------ */
public BundleWebAppProvider (ServerInstanceWrapper wrapper)
@ -61,6 +121,8 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund
*/
protected void doStart() throws Exception
{
_webappTracker = new WebAppTracker(FrameworkUtil.getBundle(this.getClass()).getBundleContext(), getServerInstanceWrapper().getManagedServerName());
_webappTracker.open();
//register as an osgi service for deploying bundles, 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());
@ -75,6 +137,8 @@ public class BundleWebAppProvider extends AbstractWebAppProvider implements Bund
@Override
protected void doStop() throws Exception
{
_webappTracker.close();
//unregister ourselves
if (_serviceRegForBundles != null)
{

View File

@ -20,18 +20,13 @@ package org.eclipse.jetty.osgi.boot;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.DefaultJettyAtJettyHomeHelper;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.JettyServerServiceTracker;
import org.eclipse.jetty.osgi.boot.internal.webapp.BundleWatcher;
import org.eclipse.jetty.osgi.boot.internal.webapp.ServiceWatcher;
import org.eclipse.jetty.osgi.boot.utils.internal.PackageAdminServiceTracker;
import org.eclipse.jetty.server.Server;
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.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.ServiceTracker;
/**
@ -55,14 +50,10 @@ public class JettyBootstrapActivator implements BundleActivator
}
private ServiceRegistration _registeredServer;
private ServiceTracker _contextHandlerTracker;
private PackageAdminServiceTracker _packageAdminServiceTracker;
private BundleTracker _webBundleTracker;
private JettyServerServiceTracker _jettyServerServiceTracker;
private ServiceTracker _jettyServerServiceTracker;
@ -77,7 +68,6 @@ public class JettyBootstrapActivator implements BundleActivator
*/
public void start(final BundleContext context) throws Exception
{
try {
INSTANCE = this;
// track other bundles and fragments attached to this bundle that we
@ -85,27 +75,15 @@ public class JettyBootstrapActivator implements BundleActivator
_packageAdminServiceTracker = new PackageAdminServiceTracker(context);
// track jetty Server instances that we should support as deployment targets
_jettyServerServiceTracker = new JettyServerServiceTracker();
context.addServiceListener(_jettyServerServiceTracker, "(objectclass=" + Server.class.getName() + ")");
_jettyServerServiceTracker = new ServiceTracker(context, context.createFilter("(objectclass=" + Server.class.getName() + ")"), new JettyServerServiceTracker());
_jettyServerServiceTracker.open();
// Create a default jetty instance right now.
Server defaultServer = DefaultJettyAtJettyHomeHelper.startJettyAtJettyHome(context);
// track ContextHandler class instances and deploy them to one of the known Servers
_contextHandlerTracker = new ServiceTracker(context, context.createFilter("(objectclass=" + ContextHandler.class.getName() + ")"), new ServiceWatcher());
_contextHandlerTracker.open();
//Create a bundle tracker to help deploy webapps and ContextHandlers
BundleWatcher bundleTrackerCustomizer = new BundleWatcher();
bundleTrackerCustomizer.setWaitForDefaultServer(defaultServer != null);
_webBundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STOPPING, bundleTrackerCustomizer);
bundleTrackerCustomizer.setBundleTracker(_webBundleTracker);
bundleTrackerCustomizer.open();
} catch (Exception e) { e.printStackTrace();}
}
/* ------------------------------------------------------------ */
/**
* Stop the activator.
@ -117,20 +95,9 @@ public class JettyBootstrapActivator implements BundleActivator
{
try
{
if (_webBundleTracker != null)
{
_webBundleTracker.close();
_webBundleTracker = null;
}
if (_contextHandlerTracker != null)
{
_contextHandlerTracker.close();
_contextHandlerTracker = null;
}
if (_jettyServerServiceTracker != null)
{
_jettyServerServiceTracker.stop();
context.removeServiceListener(_jettyServerServiceTracker);
_jettyServerServiceTracker.close();
_jettyServerServiceTracker = null;
}
if (_packageAdminServiceTracker != null)

View File

@ -27,14 +27,19 @@ 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.utils.Util;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
/**
* ServiceContextProvider
@ -51,6 +56,55 @@ public class ServiceContextProvider extends AbstractContextProvider implements S
private ServiceRegistration _serviceRegForServices;
ServiceTracker _tracker;
/**
* ContextTracker
*
*
*/
public class ContextTracker extends ServiceTracker
{
public ContextTracker (BundleContext bundleContext, Filter filter)
{
super(bundleContext, filter, null);
}
/**
* @see org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
*/
@Override
public Object addingService(ServiceReference reference)
{
ContextHandler h = (ContextHandler)context.getService(reference);
serviceAdded (reference, h);
return h;
}
/**
* @see org.osgi.util.tracker.ServiceTracker#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
*/
@Override
public void modifiedService(ServiceReference reference, Object service)
{
removedService(reference,service);
addingService(reference);
}
/**
* @see org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
*/
@Override
public void removedService(ServiceReference reference, Object service)
{
context.ungetService(reference);
serviceRemoved(reference, (ContextHandler)service);
}
}
/**
* ServiceApp
@ -162,6 +216,15 @@ public class ServiceContextProvider extends AbstractContextProvider implements S
@Override
protected void doStart() throws Exception
{
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
//Start a tracker to find webapps that are osgi services that are targetted to my server name
_tracker = new ContextTracker (bundleContext,
Util.createFilter(bundleContext, ContextHandler.class.getName(), getServerInstanceWrapper().getManagedServerName()));
_tracker.open();
//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());
@ -175,6 +238,9 @@ public class ServiceContextProvider extends AbstractContextProvider implements S
@Override
protected void doStop() throws Exception
{
if (_tracker != null)
_tracker.close();
//unregister ourselves
if (_serviceRegForServices != null)
{

View File

@ -27,14 +27,19 @@ 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.utils.Util;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
/**
* ServiceWebAppProvider
@ -52,6 +57,58 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser
private ServiceRegistration _serviceRegForServices;
private ServiceTracker webappTracker;
/**
* WebAppTracker
*
*
*/
public class WebAppTracker extends ServiceTracker
{
/**
* @param bundleContext the osgi context
* @param filter the osgi filter for the tracker
*/
public WebAppTracker (BundleContext bundleContext, Filter filter)
{
super(bundleContext, filter, null);
}
/**
* @see org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
*/
@Override
public Object addingService(ServiceReference reference)
{
WebAppContext wac = (WebAppContext)context.getService(reference);
serviceAdded (reference, wac);
return wac;
}
/**
* @see org.osgi.util.tracker.ServiceTracker#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
*/
@Override
public void modifiedService(ServiceReference reference, Object service)
{
removedService(reference,service);
addingService(reference);
}
/**
* @see org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
*/
@Override
public void removedService(ServiceReference reference, Object service)
{
serviceRemoved(reference, (WebAppContext)service);
context.ungetService(reference);
}
}
/**
* ServiceApp
*
@ -207,6 +264,13 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser
*/
protected void doStart() throws Exception
{
BundleContext bundleContext = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
//Start a tracker to find webapps that are osgi services that are targetted to my server name
webappTracker = new WebAppTracker (bundleContext,
Util.createFilter(bundleContext, WebAppContext.class.getName(), getServerInstanceWrapper().getManagedServerName()));
webappTracker.open();
//register as an osgi service for deploying bundles, 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());
@ -223,6 +287,8 @@ public class ServiceWebAppProvider extends AbstractWebAppProvider implements Ser
@Override
protected void doStop() throws Exception
{
webappTracker.close();
//unregister ourselves
if (_serviceRegForServices != null)
{

View File

@ -18,8 +18,6 @@
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.OSGiServerConstants;
@ -27,9 +25,8 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* JettyServerServiceTracker
@ -38,116 +35,71 @@ import org.osgi.framework.ServiceReference;
* webapps or ContextHandlers discovered from the OSGi environment.
*
*/
public class JettyServerServiceTracker implements ServiceListener
public class JettyServerServiceTracker implements ServiceTrackerCustomizer
{
private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName());
/** The context-handler to deactivate indexed by ServerInstanceWrapper */
private Map<ServiceReference, ServerInstanceWrapper> _indexByServiceReference = new HashMap<ServiceReference, ServerInstanceWrapper>();
/**
* Stops each one of the registered servers.
/**
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
*/
public void stop()
@Override
public Object addingService(ServiceReference sr)
{
for (ServerInstanceWrapper wrapper : _indexByServiceReference.values())
Bundle contributor = sr.getBundle();
Server server = (Server) contributor.getBundleContext().getService(sr);
String name = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); }
if (LOG.isDebugEnabled()) LOG.debug("Adding Server {}", name);
ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name);
Properties props = new Properties();
for (String key : sr.getPropertyKeys())
{
Object value = sr.getProperty(key);
props.put(key, value);
}
try
{
wrapper.start(server, props);
LOG.info("Started Server {}", name);
return wrapper;
}
catch (Exception e)
{
LOG.warn(e);
return sr.getBundle().getBundleContext().getService(sr);
}
}
/**
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
*/
@Override
public void modifiedService(ServiceReference reference, Object service)
{
removedService(reference, service);
addingService(reference);
}
/**
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
*/
@Override
public void removedService(ServiceReference reference, Object service)
{
if (service instanceof ServerInstanceWrapper)
{
try
{
ServerInstanceWrapper wrapper = (ServerInstanceWrapper)service;
wrapper.stop();
LOG.info("Stopped Server {}",wrapper.getManagedServerName());
}
catch (Throwable t)
catch (Exception e)
{
LOG.warn(t);
LOG.warn(e);
}
}
}
/**
* 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)
{
LOG.warn(e);
}
}
if (ev.getType() == ServiceEvent.UNREGISTERING)
{
break;
}
else
{
// modified, meaning: we reload it. now that we stopped it;
// we can register it.
}
}
case ServiceEvent.REGISTERED:
{
try
{
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);
}
catch (Exception e)
{
LOG.warn(e);
}
break;
}
}
}
private ServerInstanceWrapper registerInIndex(Server server, ServiceReference sr)
{
String name = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); }
ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name);
_indexByServiceReference.put(sr, 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)
{
LOG.warn("Unknown Jetty Server ServiceReference: ", sr);
return null;
}
return handler;
}
}

View File

@ -1,307 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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.webapp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.jetty.osgi.boot.BundleProvider;
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
import org.eclipse.jetty.osgi.boot.utils.TldBundleDiscoverer;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.BundleTrackerCustomizer;
import org.osgi.util.tracker.ServiceTracker;
/**
* BundleWatcher
*
* Tracks the installation and removal of Bundles in the OSGi environment. Any bundles
* that are added are passed to the set of Jetty DeploymentManager providers to see if
* the bundle should be deployed as a webapp or ContextHandler into Jetty.
*/
public class BundleWatcher implements BundleTrackerCustomizer
{
private static final Logger LOG = Log.getLogger(BundleWatcher.class);
public static final Collection<TldBundleDiscoverer> JSP_REGISTRATION_HELPERS = new ArrayList<TldBundleDiscoverer>();
public static final String FILTER = "(objectclass=" + BundleProvider.class.getName() + ")";
private ServiceTracker _serviceTracker;
private BundleTracker _bundleTracker;
private boolean _waitForDefaultServer = true;
private boolean _defaultServerReady = false;
private Bundle _bundle = null;
/* ------------------------------------------------------------ */
public BundleWatcher() throws Exception
{
_bundle = FrameworkUtil.getBundle(this.getClass());
//Track all BundleProviders (Jetty DeploymentManager Providers that can deploy bundles)
_serviceTracker = new ServiceTracker(_bundle.getBundleContext(), FrameworkUtil.createFilter(FILTER),null);
_serviceTracker.open();
}
/* ------------------------------------------------------------ */
public boolean isWaitForDefaultServer()
{
return _waitForDefaultServer;
}
/* ------------------------------------------------------------ */
public void setWaitForDefaultServer(boolean waitForDefaultServer)
{
_waitForDefaultServer = waitForDefaultServer;
}
/* ------------------------------------------------------------ */
public void setBundleTracker (BundleTracker bundleTracker)
{
_bundleTracker = bundleTracker;
}
/* ------------------------------------------------------------ */
public void open () throws Exception
{
if (_waitForDefaultServer && !_defaultServerReady)
{
String filter = "(&(objectclass=" + BundleProvider.class.getName() + ")"+
"("+OSGiServerConstants.MANAGED_JETTY_SERVER_NAME+"="+OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME+"))";
ServiceTracker defaultServerTracker = new ServiceTracker(_bundle.getBundleContext(),
FrameworkUtil.createFilter(filter),null)
{
public Object addingService(ServiceReference reference)
{
try
{
Object object = super.addingService(reference);
LOG.debug("Default Jetty Server registered {}", reference);
_defaultServerReady = true;
openBundleTracker();
return object;
}
catch (Exception e)
{
throw new IllegalStateException(e);
}
}
};
defaultServerTracker.open();
}
else
openBundleTracker();
}
/* ------------------------------------------------------------ */
public Map<ServiceReference, BundleProvider> getDeployers(String managedServerName)
{
if (managedServerName == null)
managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME;
Map<ServiceReference, BundleProvider> candidates = new HashMap<ServiceReference, BundleProvider>();
ServiceReference[] references = _serviceTracker.getServiceReferences();
if (references != null)
{
for (ServiceReference ref:references)
{
String name = (String)ref.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
if (managedServerName.equalsIgnoreCase(name))
{
BundleProvider candidate = (BundleProvider)_serviceTracker.getService(ref);
if (candidate != null)
candidates.put(ref, candidate);
}
}
}
return candidates;
}
/* ------------------------------------------------------------ */
/**
* A bundle is being added to the <code>BundleTracker</code>.
*
* <p>
* This method is called before a bundle which matched the search parameters
* of the <code>BundleTracker</code> is added to the
* <code>BundleTracker</code>. This method should return the object to be
* tracked for the specified <code>Bundle</code>. The returned object is
* stored in the <code>BundleTracker</code> and is available from the
* {@link BundleTracker#getObject(Bundle) getObject} method.
*
* @param bundle The <code>Bundle</code> being added to the
* <code>BundleTracker</code>.
* @param event The bundle event which caused this customizer method to be
* called or <code>null</code> if there is no bundle event
* associated with the call to this method.
* @return The object to be tracked for the specified <code>Bundle</code>
* object or <code>null</code> if the specified <code>Bundle</code>
* object should not be tracked.
*/
public Object addingBundle(Bundle bundle, BundleEvent event)
{
if (bundle.getState() == Bundle.ACTIVE)
{
register(bundle);
}
else if (bundle.getState() == Bundle.STOPPING)
{
unregister(bundle);
}
else
{
// we should not be called in that state as
// we are registered only for ACTIVE and STOPPING
}
return null;
}
/* ------------------------------------------------------------ */
/**
* A bundle tracked by the <code>BundleTracker</code> has been modified.
*
* <p>
* This method is called when a bundle being tracked by the
* <code>BundleTracker</code> has had its state modified.
*
* @param bundle The <code>Bundle</code> whose state has been modified.
* @param event The bundle event which caused this customizer method to be
* called or <code>null</code> if there is no bundle event
* associated with the call to this method.
* @param object The tracked object for the specified bundle.
*/
public void modifiedBundle(Bundle bundle, BundleEvent event, Object object)
{
if (bundle.getState() == Bundle.STOPPING || bundle.getState() == Bundle.ACTIVE)
{
unregister(bundle);
}
if (bundle.getState() == Bundle.ACTIVE)
{
register(bundle);
}
}
/* ------------------------------------------------------------ */
/**
* A bundle tracked by the <code>BundleTracker</code> has been removed.
*
* <p>
* This method is called after a bundle is no longer being tracked by the
* <code>BundleTracker</code>.
*
* @param bundle The <code>Bundle</code> that has been removed.
* @param event The bundle event which caused this customizer method to be
* called or <code>null</code> if there is no bundle event
* associated with the call to this method.
* @param object The tracked object for the specified bundle.
*/
public void removedBundle(Bundle bundle, BundleEvent event, Object object)
{
unregister(bundle);
}
protected void openBundleTracker()
{
_bundleTracker.open();
}
/* ------------------------------------------------------------ */
/**
* @param bundle
* @return true if this bundle can be deployed into Jetty
*/
private boolean register(Bundle bundle)
{
if (bundle == null)
return false;
//It might be a bundle that is deployable by Jetty.
//Use any named Server instance provided, defaulting to the default Server instance if none supplied
boolean deployed = false;
String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
Map<ServiceReference, BundleProvider> candidates = getDeployers(serverName);
if (candidates != null)
{
Iterator<Entry<ServiceReference, BundleProvider>> itor = candidates.entrySet().iterator();
while (!deployed && itor.hasNext())
{
Entry<ServiceReference, BundleProvider> e = itor.next();
try
{
deployed = e.getValue().bundleAdded(bundle);
}
catch (Exception x)
{
LOG.warn("Error deploying bundle for jetty context", x);
}
}
}
return deployed;
}
/* ------------------------------------------------------------ */
/**
* @param bundle
*/
private void unregister(Bundle bundle)
{
boolean undeployed = false;
String serverName = (String)bundle.getHeaders().get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
Map<ServiceReference, BundleProvider> candidates = getDeployers(serverName);
if (candidates != null)
{
Iterator<Entry<ServiceReference, BundleProvider>> itor = candidates.entrySet().iterator();
while (!undeployed && itor.hasNext())
{
Entry<ServiceReference, BundleProvider> e = itor.next();
try
{
undeployed = e.getValue().bundleRemoved(bundle);
}
catch (Exception x)
{
LOG.warn("Error undeploying Bundle representing jetty deployable ", x);
}
}
}
}
}

View File

@ -1,223 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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.webapp;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
import org.eclipse.jetty.osgi.boot.ServiceProvider;
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.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* ServiceWatcher
*
* 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 BundleWatcher}.
*/
public class ServiceWatcher implements ServiceTrackerCustomizer
{
private static Logger LOG = Log.getLogger(ServiceWatcher.class);
public static final String FILTER = "(objectclass=" + ServiceProvider.class.getName() + ")";
//track all instances of deployers of webapps as bundles
ServiceTracker _serviceTracker;
/* ------------------------------------------------------------ */
public ServiceWatcher() throws Exception
{
//track all instances of deployers of webapps
Bundle myBundle = FrameworkUtil.getBundle(this.getClass());
_serviceTracker = new ServiceTracker(myBundle.getBundleContext(), FrameworkUtil.createFilter(FILTER),null);
_serviceTracker.open();
}
/* ------------------------------------------------------------ */
public Map<ServiceReference, ServiceProvider> getDeployers(String managedServerName)
{
if (managedServerName == null)
managedServerName = OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME;
Map<ServiceReference, ServiceProvider> candidates = new HashMap<ServiceReference, ServiceProvider>();
ServiceReference[] references = _serviceTracker.getServiceReferences();
if (references != null)
{
for (ServiceReference ref:references)
{
String name = (String)ref.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
if (managedServerName.equalsIgnoreCase(name))
{
ServiceProvider candidate = (ServiceProvider)_serviceTracker.getService(ref);
if (candidate != null)
candidates.put(ref, candidate);
}
}
}
return candidates;
}
/* ------------------------------------------------------------ */
/**
* A Service that is a ContextHandler is detected.
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
*/
@Override
public Object addingService(ServiceReference reference)
{
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
ContextHandler contextHandler = (ContextHandler) context.getService(reference);
return addService(context, contextHandler, reference);
}
/* ------------------------------------------------------------ */
/**
* A Service that is a ContextHandler has been modified. We
* undeploy and then redeploy the ContextHandler.
*
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
*/
@Override
public void modifiedService(ServiceReference reference, Object service)
{
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
ContextHandler contextHandler = (ContextHandler) context.getService(reference);
removeService (context, contextHandler, reference);
addService (context, contextHandler, reference);
}
/* ------------------------------------------------------------ */
/**
* A Service that is a ContextHandler is being removed.
* @see org.osgi.util.tracker.ServiceTrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
*/
@Override
public void removedService(ServiceReference reference, Object service)
{
BundleContext context = FrameworkUtil.getBundle(JettyBootstrapActivator.class).getBundleContext();
ContextHandler contextHandler = (ContextHandler) context.getService(reference);
removeService (context, contextHandler, reference);
}
/* ------------------------------------------------------------ */
/** Deploy ContextHandler that is a Service.
* @param context the bundle context
* @param contextHandler the context handler
* @param reference the service reference
* @return the object added
*/
public Object addService (BundleContext context, ContextHandler contextHandler, ServiceReference reference)
{
if (contextHandler.getServer() != null)
{
// is configured elsewhere.
return context.getService(reference);
}
String watermark = (String)reference.getProperty(OSGiWebappConstants.WATERMARK);
if (watermark != null && !"".equals(watermark))
return context.getService(reference); //one of our deployers just registered the context as an OSGi service, so we can ignore it
//Get a jetty deployer targetted to the named server instance, or the default one if not named
String serverName = (String)reference.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
Map<ServiceReference, ServiceProvider> candidates = getDeployers(serverName);
if (candidates != null)
{
boolean added = false;
Iterator<Entry<ServiceReference, ServiceProvider>> itor = candidates.entrySet().iterator();
while (!added && itor.hasNext())
{
Entry<ServiceReference, ServiceProvider> e = itor.next();
try
{
added = e.getValue().serviceAdded(reference, contextHandler);
if (added && LOG.isDebugEnabled())
LOG.debug("Provider "+e.getValue()+" deployed "+contextHandler);
}
catch (Exception x)
{
LOG.warn("Error deploying service representing jetty context", x);
}
}
}
return context.getService(reference);
}
/* ------------------------------------------------------------ */
/**
* Undeploy a ContextHandler that is a Service.
* @param context the bundle context
* @param contextHandler the context handler
* @param reference the service reference
*/
public void removeService (BundleContext context, ContextHandler contextHandler, ServiceReference reference)
{
//Get a jetty deployer targetted to the named server instance, or the default one if not named
//The individual deployer will decide if it can remove the context or not
String serverName = (String)reference.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
Map<ServiceReference, ServiceProvider> candidates = getDeployers(serverName);
if (candidates != null)
{
boolean removed = false;
Iterator<Entry<ServiceReference, ServiceProvider>> itor = candidates.entrySet().iterator();
while (!removed && itor.hasNext())
{
Entry<ServiceReference, ServiceProvider> e = itor.next();
try
{
removed = e.getValue().serviceRemoved(reference, contextHandler);
}
catch (Exception x)
{
LOG.warn("Error undeploying service representing jetty context ", x);
}
}
}
}
}

View File

@ -19,13 +19,18 @@
package org.eclipse.jetty.osgi.boot.utils;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.StringTokenizer;
import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
import org.eclipse.jetty.util.StringUtil;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
/**
* Various useful functions utility methods for OSGi wide use.
*/
@ -34,6 +39,31 @@ public class Util
public static final String DEFAULT_DELIMS = ",;";
/**
* Create an osgi filter for the given classname and server name.
*
* @param bundleContext
* @param classname the class to match on the filter
* @param managedServerName the name of the jetty server instance
* @return a new filter
*
* @throws InvalidSyntaxException
*/
public static Filter createFilter (BundleContext bundleContext, String classname, String managedServerName) throws InvalidSyntaxException
{
if (StringUtil.isBlank(managedServerName) || managedServerName.equals(OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME))
{
return bundleContext.createFilter("(&(objectclass=" + classname
+ ")(|(managedServerName="+managedServerName
+")(!(managedServerName=*))))");
}
else
{
return bundleContext.createFilter("(&(objectclass=" + classname+ ")(managedServerName="+managedServerName+"))");
}
}
/**
* Get the value of a manifest header.
*

View File

@ -26,6 +26,7 @@
<module>test-jetty-osgi-webapp</module>
<module>test-jetty-osgi-context</module>
<module>test-jetty-osgi-fragment</module>
<module>test-jetty-osgi-server</module>
<module>jetty-osgi-alpn</module>
<module>test-jetty-osgi</module>
</modules>

View File

@ -27,6 +27,7 @@ import javax.servlet.ServletContextListener;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
/**
* Bootstrap a ContextHandler
@ -36,6 +37,7 @@ import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator
{
private ServiceRegistration _sr;
/**
*
* @param context
@ -48,20 +50,20 @@ public class Activator implements BundleActivator
@Override
public void contextInitialized(ServletContextEvent sce)
{
// System.err.println("Context is initialized");
//System.err.println("Context is initialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce)
{
// System.err.println("CONTEXT IS DESTROYED!");
//System.err.println("CONTEXT IS DESTROYED!");
}
});
Dictionary props = new Hashtable();
props.put("contextPath","/acme");
props.put("Jetty-ContextFilePath", "acme.xml");
context.registerService(ContextHandler.class.getName(),ch,props);
_sr = context.registerService(ContextHandler.class.getName(),ch,props);
}
/**
@ -72,5 +74,6 @@ public class Activator implements BundleActivator
*/
public void stop(BundleContext context) throws Exception
{
_sr.unregister();
}
}

View File

@ -0,0 +1,84 @@
<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>9.4.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-jetty-osgi-server</artifactId>
<name>Jetty :: OSGi :: Server</name>
<description>Test Jetty OSGi bundle with a Server</description>
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.testserver</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-schemas</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<!-- DO NOT DEPLOY (or Release) -->
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${bundle-symbolic-name}</Bundle-SymbolicName>
<Bundle-Name>Jetty OSGi Test Server</Bundle-Name>
<Bundle-Activator>com.acme.osgi.Activator</Bundle-Activator>
<Bundle-RequiredExecutionEnvironment>J2SE-1.5</Bundle-RequiredExecutionEnvironment>
<!-- disable the uses directive: jetty will accommodate 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>
javax.servlet;version="[3.1,3.2)",
javax.servlet.resources;version="[3.1,3.2)",
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="[9.1,10.0)"</DynamicImport-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,68 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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.ContextHandlerCollection;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
/**
* Bootstrap a Server
*
*
*/
public class Activator implements BundleActivator
{
private ServiceRegistration _sr;
/**
*
* @param context
*/
public void start(BundleContext context) throws Exception
{
Server server = new Server(9999);
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);
Dictionary serverProps = new Hashtable();
//define the unique name of the server instance
serverProps.put("managedServerName", "fooServer");
//serverProps.put("jetty.http.port", "9999");
//register as an OSGi Service for Jetty to find
_sr = context.registerService(Server.class.getName(), server, serverProps);
}
/**
* Stop the activator.
*
* @see
* org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception
{
_sr.unregister();
}
}

View File

@ -0,0 +1,6 @@
<html>
<body>
<h1>Test OSGi WebApp</h1>
<p>Webapp registered by bundle as service successfully deployed.</p>
</body>
</html>

View File

@ -31,6 +31,12 @@
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -25,6 +25,7 @@ import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.webapp.WebAppContext;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
/**
* Bootstrap a webapp
@ -34,6 +35,9 @@ import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator
{
private ServiceRegistration _srA;
private ServiceRegistration _srB;
/**
*
* @param context
@ -42,29 +46,24 @@ public class Activator implements BundleActivator
{
String serverName = "defaultJettyServer";
/* Uncomment to create a different server instance to deploy to. Also change
* TestJettyOSGiBootWebAppAsService to use the port 9999
Server server = new Server();
//do any setup on Server in here
serverName = "fooServer";
Dictionary serverProps = new Hashtable();
//define the unique name of the server instance
serverProps.put("managedServerName", serverName);
serverProps.put("jetty.http.port", "9999");
//let Jetty apply some configuration files to the Server instance
serverProps.put("jetty.etc.config.urls", "file:/opt/jetty/etc/jetty.xml,file:/opt/jetty/etc/jetty-selector.xml,file:/opt/jetty/etc/jetty-deployer.xml");
//register as an OSGi Service for Jetty to find
context.registerService(Server.class.getName(), server, serverProps);
*/
//Create a webapp context as a Service and target it at the Server created above
//Create webappA as a Service and target it at the default server
WebAppContext webapp = new WebAppContext();
Dictionary props = new Hashtable();
props.put("war",".");
props.put("war","webappA");
props.put("contextPath","/acme");
props.put("managedServerName", serverName);
context.registerService(ContextHandler.class.getName(),webapp,props);
props.put("managedServerName", "defaultJettyServer");
_srA = context.registerService(WebAppContext.class.getName(),webapp,props);
//Create a second webappB as a Service and target it at a custom Server
//deployed by another bundle
WebAppContext webappB = new WebAppContext();
Dictionary propsB = new Hashtable();
propsB.put("war", "webappB");
propsB.put("contextPath", "/acme");
propsB.put("managedServerName", "fooServer");
_srB = context.registerService(WebAppContext.class.getName(), webappB, propsB);
}
/**
@ -75,5 +74,7 @@ public class Activator implements BundleActivator
*/
public void stop(BundleContext context) throws Exception
{
_srA.unregister();
_srB.unregister();
}
}

View File

@ -0,0 +1,6 @@
<html>
<body>
<h1>Test OSGi WebAppA</h1>
<p>Webapp registered by bundle as service successfully deployed.</p>
</body>
</html>

View File

@ -0,0 +1,6 @@
<html>
<body>
<h1>Test OSGi WebAppB</h1>
<p>Webapp registered by bundle as service successfully deployed.</p>
</body>
</html>

View File

@ -368,7 +368,12 @@
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.osgi</groupId>
<artifactId>test-jetty-osgi-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-mock-resources</artifactId>

View File

@ -83,7 +83,8 @@ public class TestJettyOSGiBootWebAppAsService
options.addAll(Arrays.asList(options(systemProperty("org.ops4j.pax.logging.DefaultServiceLog.level").value(LOG_LEVEL))));
options.addAll(Arrays.asList(options(systemProperty("org.eclipse.jetty.LEVEL").value(LOG_LEVEL))));
options.addAll(jspDependencies());
options.addAll(TestJettyOSGiBootCore.jspDependencies());
options.addAll(testDependencies());
return options.toArray(new Option[options.size()]);
}
@ -107,15 +108,21 @@ public class TestJettyOSGiBootWebAppAsService
return options;
}
public static List<Option> jspDependencies()
public static List<Option> testDependencies()
{
List<Option> res = new ArrayList<Option>();
res.addAll(TestJettyOSGiBootCore.jspDependencies());
// a bundle that registers a webapp as a service for the jetty osgi core
// to pick up and deploy
res.add(mavenBundle().groupId("org.eclipse.jetty.osgi").artifactId("test-jetty-osgi-webapp").versionAsInProject().start());
//a bundle that registers a new named Server instance
res.add(mavenBundle().groupId("org.eclipse.jetty.osgi").artifactId("test-jetty-osgi-server").versionAsInProject().start());
return res;
}
@ -123,10 +130,12 @@ public class TestJettyOSGiBootWebAppAsService
@Test
public void assertAllBundlesActiveOrResolved()
{
TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
//TestOSGiUtil.assertAllBundlesActiveOrResolved(bundleContext);
TestOSGiUtil.debugBundles(bundleContext);
}
@Ignore
@Test
public void testBundle() throws Exception
{
@ -135,22 +144,28 @@ public class TestJettyOSGiBootWebAppAsService
try
{
client.start();
ContentResponse response = client.GET("http://127.0.0.1:" + TestJettyOSGiBootCore.DEFAULT_HTTP_PORT + "/acme/index.html");
assertEquals(HttpStatus.OK_200, response.getStatus());
String content = new String(response.getContent());
assertTrue(content.indexOf("<h1>Test OSGi WebApp</h1>") != -1);
assertTrue(content.indexOf("<h1>Test OSGi WebAppA</h1>") != -1);
response = client.GET("http://127.0.0.1:" + "9999" + "/acme/index.html");
assertEquals(HttpStatus.OK_200, response.getStatus());
content = new String(response.getContent());
assertTrue(content.indexOf("<h1>Test OSGi WebAppB</h1>") != -1);
}
finally
{
client.stop();
}
ServiceReference[] refs = bundleContext.getServiceReferences(ContextHandler.class.getName(), null);
ServiceReference[] refs = bundleContext.getServiceReferences(WebAppContext.class.getName(), null);
assertNotNull(refs);
assertEquals(1, refs.length);
assertEquals(2, refs.length);
WebAppContext wac = (WebAppContext) bundleContext.getService(refs[0]);
assertEquals("/acme", wac.getContextPath());
wac = (WebAppContext) bundleContext.getService(refs[1]);
assertEquals("/acme", wac.getContextPath());
}
}