View Javadoc

1   // ========================================================================
2   // Copyright (c) 2009 Intalio, Inc.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // Contributors:
13  //    Hugues Malphettes - initial API and implementation
14  // ========================================================================
15  package org.eclipse.jetty.osgi.boot.internal.serverfactory;
16  
17  import java.net.URL;
18  import java.util.Dictionary;
19  import java.util.HashMap;
20  import java.util.Hashtable;
21  import java.util.Map;
22  import java.util.StringTokenizer;
23  
24  import org.eclipse.jetty.osgi.boot.OSGiServerConstants;
25  import org.eclipse.jetty.osgi.boot.OSGiWebappConstants;
26  import org.eclipse.jetty.server.Server;
27  import org.osgi.framework.Bundle;
28  import org.osgi.framework.ServiceReference;
29  import org.osgi.service.cm.Configuration;
30  import org.osgi.service.cm.ConfigurationAdmin;
31  import org.osgi.service.cm.ConfigurationException;
32  import org.osgi.service.cm.ManagedServiceFactory;
33  
34  /**
35   * Manages the deployment of jetty server instances.
36   * Not sure this is bringing much compared to the JettyServerServiceTracker.
37   * 
38   * @author hmalphettes
39   */
40  public class JettyServersManagedFactory implements ManagedServiceFactory, IManagedJettyServerRegistry
41  {
42  
43      /**
44       * key to configure the server according to a jetty home folder. the value
45       * is the corresponding java.io.File
46       */
47      public static final String JETTY_HOME = "jettyhome";
48      /** key to configure the server according to a jetty.xml file */
49      public static final String JETTY_CONFIG_XML = "jettyxml";
50  
51      /**
52       * invoke jetty-factory class. the value of this property is the instance of
53       * that class to call back.
54       */
55      public static final String JETTY_FACTORY = "jettyfactory";
56  
57      /**
58       * default property in jetty.xml that is used as the value of the http port.
59       */
60      public static final String JETTY_HTTP_PORT = "jetty.http.port";
61      /**
62       * default property in jetty.xml that is used as the value of the https
63       * port.
64       */
65      public static final String JETTY_HTTPS_PORT = "jetty.http.port";
66  
67      /**
68       * Servers indexed by PIDs. PIDs are generated by the ConfigurationAdmin service.
69       */
70      private Map<String, ServerInstanceWrapper> _serversIndexedByPID = new HashMap<String, ServerInstanceWrapper>();
71      /**
72       * PID -> {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME}
73       */
74      private Map<String, String> _serversNameIndexedByPID = new HashMap<String, String>();
75      /**
76       * {@link OSGiWebappConstants#MANAGED_JETTY_SERVER_NAME} -> PID
77       */
78      private Map<String, String> _serversPIDIndexedByName = new HashMap<String, String>();
79  
80      /**
81       * Return a descriptive name of this factory.
82       * 
83       * @return the name for the factory, which might be localized
84       */
85      public String getName()
86      {
87          return getClass().getName();
88      }
89  
90      public void updated(String pid, Dictionary properties) throws ConfigurationException
91      {
92      	ServerInstanceWrapper serverInstanceWrapper = getServerByPID(pid);
93          deleted(pid);
94          // do we need to collect the currently deployed http services and
95          // webapps
96          // to be able to re-deploy them later?
97          // probably not. simply restart and see the various service trackers
98          // do everything that is needed.
99          String name = (String)properties.get(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME);
100         if (name == null)
101         {
102         	throw new ConfigurationException(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME,
103         			"The name of the server is mandatory");
104         }
105         serverInstanceWrapper = new ServerInstanceWrapper(name);
106         _serversIndexedByPID.put(pid, serverInstanceWrapper);
107         _serversNameIndexedByPID.put(pid, name);
108         _serversPIDIndexedByName.put(name, pid);
109         serverInstanceWrapper.start(new Server(), properties);
110     }
111 
112     public synchronized void deleted(String pid)
113     {
114     	ServerInstanceWrapper server = (ServerInstanceWrapper)_serversIndexedByPID.remove(pid);
115         String name = _serversNameIndexedByPID.remove(pid);
116         if (name != null)
117         {
118         	_serversPIDIndexedByName.remove(name);
119         }
120         else
121         {
122         	//something incorrect going on.
123         }
124         if (server != null)
125         {
126             try
127             {
128             	server.stop();
129             }
130             catch (Exception e)
131             {
132                 e.printStackTrace();
133             }
134         }
135     }
136 
137     public synchronized ServerInstanceWrapper getServerByPID(String pid)
138     {
139     	return _serversIndexedByPID.get(pid);
140     }
141     
142     /**
143      * @param managedServerName The server name
144      * @return the corresponding jetty server wrapped with its deployment properties.
145      */
146 	public ServerInstanceWrapper getServerInstanceWrapper(String managedServerName)
147     {
148     	String pid = _serversPIDIndexedByName.get(managedServerName);
149     	return pid != null ? _serversIndexedByPID.get(pid) : null;
150     }
151         
152     /**
153      * Helper method to create and configure a new Jetty Server via the ManagedServiceFactory
154      * @param contributor
155      * @param serverName
156      * @param urlsToJettyXml
157      * @throws Exception
158      */
159     public static void createNewServer(Bundle contributor, String serverName, String urlsToJettyXml) throws Exception
160     {
161         ServiceReference configurationAdminReference =
162         	contributor.getBundleContext().getServiceReference( ConfigurationAdmin.class.getName() );
163 
164         ConfigurationAdmin confAdmin = (ConfigurationAdmin) contributor.getBundleContext()
165         				.getService( configurationAdminReference );   
166 
167         Configuration configuration = confAdmin.createFactoryConfiguration(
168         		OSGiServerConstants.MANAGED_JETTY_SERVER_FACTORY_PID, contributor.getLocation() );
169         Dictionary properties = new Hashtable();
170         properties.put(OSGiServerConstants.MANAGED_JETTY_SERVER_NAME, serverName);
171         
172         StringBuilder actualBundleUrls = new StringBuilder();
173         StringTokenizer tokenizer = new StringTokenizer(urlsToJettyXml, ",", false);
174         while (tokenizer.hasMoreTokens())
175         {
176         	if (actualBundleUrls.length() != 0)
177         	{
178         		actualBundleUrls.append(",");
179         	}
180         	String token = tokenizer.nextToken();
181         	if (token.indexOf(':') != -1)
182         	{
183         		//a complete url. no change needed:
184         		actualBundleUrls.append(token);
185         	}
186         	else if (token.startsWith("/"))
187         	{
188         		//url relative to the contributor bundle:
189         		URL url = contributor.getEntry(token);
190         		if (url == null)
191         		{
192         			actualBundleUrls.append(token);
193         		}
194         		else
195         		{
196         			actualBundleUrls.append(url.toString());
197         		}
198         	}
199         		
200         }
201         
202         properties.put(OSGiServerConstants.MANAGED_JETTY_XML_CONFIG_URLS, actualBundleUrls.toString());
203         configuration.update(properties);
204 
205     }
206     
207 }