View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.osgi.boot;
20  
21  import java.util.Dictionary;
22  import java.util.HashMap;
23  import java.util.Hashtable;
24  import java.util.Map;
25  
26  import org.eclipse.jetty.deploy.App;
27  import org.eclipse.jetty.deploy.AppProvider;
28  import org.eclipse.jetty.deploy.DeploymentManager;
29  import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
30  import org.eclipse.jetty.server.handler.ContextHandler;
31  import org.eclipse.jetty.util.log.Log;
32  import org.eclipse.jetty.util.log.Logger;
33  import org.eclipse.jetty.webapp.WebAppContext;
34  import org.osgi.framework.Bundle;
35  import org.osgi.framework.FrameworkUtil;
36  import org.osgi.framework.ServiceReference;
37  import org.osgi.framework.ServiceRegistration;
38  
39  /**
40   * ServiceWebAppProvider
41   * <p>
42   * Jetty Provider that knows how to deploy a WebApp that has been registered as an OSGi service.
43   */
44  public class ServiceWebAppProvider extends AbstractWebAppProvider implements ServiceProvider
45  {   
46      private static final Logger LOG = Log.getLogger(AbstractWebAppProvider.class);
47      
48      /**
49       * Map of ServiceRef to App. Used when it is an osgi service that is a WebAppContext.
50       */
51      private Map<ServiceReference, App> _serviceMap = new HashMap<ServiceReference, App>();
52      
53      private ServiceRegistration _serviceRegForServices;
54      
55      /**
56       * ServiceApp
57       *
58       *
59       */
60      public class ServiceApp extends OSGiApp
61      {
62  
63          public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId)
64          {
65              super(manager, provider, bundle, properties, originId);
66          }
67  
68          public ServiceApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId)
69          {
70              super(manager, provider, bundle, originId);
71          }
72  
73          @Override
74          public void registerAsOSGiService() throws Exception
75          {
76              //not applicable for apps that are already services
77          }
78  
79          @Override
80          protected void deregisterAsOSGiService() throws Exception
81          {
82              //not applicable for apps that are already services
83          }
84      }
85      
86      
87      
88      /* ------------------------------------------------------------ */
89      public ServiceWebAppProvider (ServerInstanceWrapper wrapper)
90      {
91          super(wrapper);
92      }
93      
94      
95      /* ------------------------------------------------------------ */
96      /**
97       * A webapp that was deployed as an osgi service has been added,
98       * and we want to deploy it.
99       * 
100      * @param context the webapp
101      */
102     public boolean serviceAdded (ServiceReference serviceRef, ContextHandler context)
103     {   
104         if (context == null || !(context instanceof WebAppContext))
105             return false;
106         
107         String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK);
108         if (watermark != null && !"".equals(watermark))
109             return false;  //this service represents a webapp that has already been registered as a service by another of our deployers
110         
111         
112         WebAppContext webApp = (WebAppContext)context;
113         Dictionary properties = new Hashtable<String,String>();
114         
115         String contextPath = (String)serviceRef.getProperty(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
116         if (contextPath == null)
117             contextPath = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH);
118         if (contextPath == null)
119             return false; //No context path
120      
121         String base = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WAR_FOLDER_PATH);
122         if (base == null)
123             base = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WAR_RESOURCE_PATH);
124         if (base == null)
125             base = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_WAR);
126         
127        if (base == null)
128            return false; //No webapp base
129         
130         String webdefaultXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH);
131         if (webdefaultXml == null)
132             webdefaultXml = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_DEFAULT_WEB_XML_PATH);
133         if (webdefaultXml != null)
134             properties.put(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH, webdefaultXml);
135 
136         String webXml = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_WEB_XML_PATH);
137         if (webXml == null)
138             webXml = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_WEB_XML_PATH);
139         if (webXml != null)
140             properties.put(OSGiWebappConstants.JETTY_WEB_XML_PATH, webXml);
141 
142         String extraClassPath = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH);
143         if (extraClassPath == null)
144             extraClassPath = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_EXTRA_CLASSPATH);
145         if (extraClassPath != null)
146             properties.put(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH, extraClassPath);
147 
148         String bundleInstallOverride = (String)serviceRef.getProperty(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE);
149         if (bundleInstallOverride == null)
150             bundleInstallOverride = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE);
151         if (bundleInstallOverride != null)
152             properties.put(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE, bundleInstallOverride);
153 
154         String  requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.REQUIRE_TLD_BUNDLE);
155         if (requiredTlds == null)
156             requiredTlds = (String)serviceRef.getProperty(OSGiWebappConstants.SERVICE_PROP_REQUIRE_TLD_BUNDLE);
157         if (requiredTlds != null)
158             properties.put(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requiredTlds);
159 
160         ClassLoader cl = Thread.currentThread().getContextClassLoader();
161         Thread.currentThread().setContextClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps());
162         try
163         {
164             String originId = getOriginId(serviceRef.getBundle(), base);
165             ServiceApp app = new ServiceApp(getDeploymentManager(), this, serviceRef.getBundle(), properties, originId);
166             app.setContextPath(contextPath);
167             app.setWebAppPath(base);
168             app.setWebAppContext(webApp); //set the pre=made webapp instance
169             _serviceMap.put(serviceRef, app);
170             getDeploymentManager().addApp(app);
171             return true;
172         }
173         finally
174         {
175             Thread.currentThread().setContextClassLoader(cl); 
176         }
177     }
178     
179     
180     
181     /* ------------------------------------------------------------ */
182     /**
183      * @param context the webapp
184      */
185     public boolean serviceRemoved (ServiceReference serviceRef, ContextHandler context)
186     {
187         if (context == null || !(context instanceof WebAppContext))
188             return false;
189         
190         String watermark = (String)serviceRef.getProperty(OSGiWebappConstants.WATERMARK);
191         if (watermark != null && !"".equals(watermark))
192             return false;  //this service represents a contexthandler that will be deregistered as a service by another of our deployers
193         
194         App app = _serviceMap.remove(serviceRef);
195         if (app != null)
196         {
197             getDeploymentManager().removeApp(app);
198             return true;
199         }
200         return false;
201     }
202     
203     
204     /* ------------------------------------------------------------ */
205     /** 
206      * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
207      */
208     protected void doStart() throws Exception
209     {
210         //register as an osgi service for deploying bundles, advertising the name of the jetty Server instance we are related to
211         Dictionary<String,String> properties = new Hashtable<String,String>();
212         properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, getServerInstanceWrapper().getManagedServerName());
213        
214         //register as an osgi service for deploying contexts (discovered as osgi services), advertising the name of the jetty Server instance we are related to
215         _serviceRegForServices = FrameworkUtil.getBundle(this.getClass()).getBundleContext().registerService(ServiceProvider.class.getName(), this, properties);
216         super.doStart();
217     }
218 
219     /* ------------------------------------------------------------ */
220     /** 
221      * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
222      */
223     @Override
224     protected void doStop() throws Exception
225     {
226         //unregister ourselves
227         if (_serviceRegForServices != null)
228         {
229             try
230             {
231                 _serviceRegForServices.unregister();
232             }
233             catch (Exception e)
234             {
235                 LOG.warn(e);
236             }
237         }
238         super.doStop();
239     }
240 
241 }