View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.internal.serverfactory;
20  
21  import java.util.HashMap;
22  import java.util.Map;
23  import java.util.Properties;
24  
25  import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
26  import org.eclipse.jetty.server.Server;
27  import org.eclipse.jetty.util.log.Log;
28  import org.eclipse.jetty.util.log.Logger;
29  import org.osgi.framework.Bundle;
30  import org.osgi.framework.ServiceEvent;
31  import org.osgi.framework.ServiceListener;
32  import org.osgi.framework.ServiceReference;
33  
34  /**
35   * JettyServerServiceTracker
36   * 
37   * Tracks instances of Jetty Servers, and configures them so that they can deploy 
38   * webapps or ContextHandlers discovered from the OSGi environment.
39   * 
40   */
41  public class JettyServerServiceTracker implements ServiceListener, IManagedJettyServerRegistry
42  {
43      private static Logger LOG = Log.getLogger(JettyServerServiceTracker.class.getName());
44  
45      /**
46       * Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin
47       * service.
48       */
49      private Map<String, ServerInstanceWrapper> _serversIndexedByName = new HashMap<String, ServerInstanceWrapper>();
50  
51      /** The context-handler to deactivate indexed by ServerInstanceWrapper */
52      private Map<ServiceReference, ServerInstanceWrapper> _indexByServiceReference = new HashMap<ServiceReference, ServerInstanceWrapper>();
53  
54      /**
55       * Stops each one of the registered servers.
56       */
57      public void stop()
58      {
59          // not sure that this is really useful but here we go.
60          for (ServerInstanceWrapper wrapper : _serversIndexedByName.values())
61          {
62              try
63              {
64                  wrapper.stop();
65              }
66              catch (Throwable t)
67              {
68                  LOG.warn(t);
69              }
70          }
71      }
72  
73      /**
74       * Receives notification that a service has had a lifecycle change.
75       * 
76       * @param ev The <code>ServiceEvent</code> object.
77       */
78      public void serviceChanged(ServiceEvent ev)
79      {
80          ServiceReference sr = ev.getServiceReference();
81          switch (ev.getType())
82          {
83              case ServiceEvent.MODIFIED:
84              case ServiceEvent.UNREGISTERING:
85              {
86                  ServerInstanceWrapper instance = unregisterInIndex(ev.getServiceReference());
87                  if (instance != null)
88                  {
89                      try
90                      {
91                          instance.stop();
92                      }
93                      catch (Exception e)
94                      {
95                          LOG.warn(e);
96                      }
97                  }
98  
99                  if (ev.getType() == ServiceEvent.UNREGISTERING)
100                 {
101                     break;
102                 }
103                 else
104                 {
105                     // modified, meaning: we reload it. now that we stopped it;
106                     // we can register it.
107                 }
108             }
109             case ServiceEvent.REGISTERED:
110             {
111                 try
112                 {
113                     Bundle contributor = sr.getBundle();
114                     Server server = (Server) contributor.getBundleContext().getService(sr);
115                     ServerInstanceWrapper wrapper = registerInIndex(server, sr);
116                     Properties props = new Properties();
117                     for (String key : sr.getPropertyKeys())
118                     {
119                         Object value = sr.getProperty(key);
120                         props.put(key, value);
121                     }
122                     wrapper.start(server, props);
123                 }
124                 catch (Exception e)
125                 {
126                     LOG.warn(e);
127                 }
128                 break;
129             }
130         }
131     }
132 
133     private ServerInstanceWrapper registerInIndex(Server server, ServiceReference sr)
134     {
135         String name = (String) sr.getProperty(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
136         if (name == null) { throw new IllegalArgumentException("The property " + OSGiServerConstants.MANAGED_JETTY_SERVER_NAME + " is mandatory"); }
137         ServerInstanceWrapper wrapper = new ServerInstanceWrapper(name);
138         _indexByServiceReference.put(sr, wrapper);
139         _serversIndexedByName.put(name, wrapper);
140         return wrapper;
141     }
142 
143     /**
144      * Returns the ContextHandler to stop.
145      * 
146      * @param reg
147      * @return the ContextHandler to stop.
148      */
149     private ServerInstanceWrapper unregisterInIndex(ServiceReference sr)
150     {
151         ServerInstanceWrapper handler = _indexByServiceReference.remove(sr);
152         if (handler == null)
153         {
154             // a warning?
155             return null;
156         }
157         String name = handler.getManagedServerName();
158         if (name != null)
159         {
160             _serversIndexedByName.remove(name);
161         }
162         return handler;
163     }
164 
165     /**
166      * @param managedServerName The server name
167      * @return the corresponding jetty server wrapped with its deployment
168      *         properties.
169      */
170     public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
171     {
172         return _serversIndexedByName.get(managedServerName == null ? OSGiServerConstants.MANAGED_JETTY_SERVER_DEFAULT_NAME : managedServerName);
173     }
174 
175 }