1 /**
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one or more
4 * contributor license agreements. See the NOTICE file distributed with
5 * this work for additional information regarding copyright ownership.
6 * The ASF licenses this file to You under the Apache License, Version 2.0
7 * (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package org.apache.geronimo.jetty;
19
20 import java.util.ArrayList;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Set;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.geronimo.gbean.AbstractName;
28 import org.apache.geronimo.gbean.AbstractNameQuery;
29 import org.apache.geronimo.gbean.GBeanData;
30 import org.apache.geronimo.gbean.GBeanInfo;
31 import org.apache.geronimo.gbean.GBeanInfoBuilder;
32 import org.apache.geronimo.gbean.ReferencePatterns;
33 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
34 import org.apache.geronimo.jetty.connector.AJP13Connector;
35 import org.apache.geronimo.jetty.connector.HTTPConnector;
36 import org.apache.geronimo.jetty.connector.HTTPSConnector;
37 import org.apache.geronimo.jetty.connector.JettyConnector;
38 import org.apache.geronimo.jetty.requestlog.JettyLogManager;
39 import org.apache.geronimo.kernel.GBeanNotFoundException;
40 import org.apache.geronimo.kernel.Kernel;
41 import org.apache.geronimo.kernel.config.ConfigurationUtil;
42 import org.apache.geronimo.kernel.config.EditableConfigurationManager;
43 import org.apache.geronimo.kernel.config.InvalidConfigException;
44 import org.apache.geronimo.kernel.proxy.ProxyManager;
45 import org.apache.geronimo.management.geronimo.KeystoreManager;
46 import org.apache.geronimo.management.geronimo.NetworkConnector;
47 import org.apache.geronimo.management.geronimo.WebAccessLog;
48 import org.apache.geronimo.management.geronimo.WebConnector;
49 import org.apache.geronimo.management.geronimo.WebContainer;
50 import org.apache.geronimo.management.geronimo.WebManager;
51
52 /**
53 * Jetty implementation of WebManager. Knows how to manipulate
54 * other Jetty objects for management purposes.
55 *
56 * @version $Rev:386276 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
57 */
58 public class JettyManagerImpl implements WebManager {
59 private final static Log log = LogFactory.getLog(JettyManagerImpl.class);
60 private final Kernel kernel;
61
62 public JettyManagerImpl(Kernel kernel) {
63 this.kernel = kernel;
64 }
65
66 public String getProductName() {
67 return "Jetty";
68 }
69
70 /**
71 * Creates a new connector, and returns the ObjectName for it. Note that
72 * the connector may well require further customization before being fully
73 * functional (e.g. SSL settings for an HTTPS connector).
74 */
75 public WebConnector addConnector(WebContainer container, String uniqueName, String protocol, String host, int port) {
76 AbstractName containerName = kernel.getAbstractNameFor(container);
77 AbstractName name = kernel.getNaming().createSiblingName(containerName, uniqueName, NameFactory.GERONIMO_SERVICE);
78 GBeanData connector;
79 if (protocol.equals(PROTOCOL_HTTP)) {
80 connector = new GBeanData(name, HTTPConnector.GBEAN_INFO);
81 } else if (protocol.equals(PROTOCOL_HTTPS)) {
82 connector = new GBeanData(name, HTTPSConnector.GBEAN_INFO);
83 AbstractNameQuery query = new AbstractNameQuery(KeystoreManager.class.getName());
84 connector.setReferencePattern("KeystoreManager", query);
85
86 } else if (protocol.equals(PROTOCOL_AJP)) {
87 connector = new GBeanData(name, AJP13Connector.GBEAN_INFO);
88 } else {
89 throw new IllegalArgumentException("Invalid protocol '" + protocol + "'");
90 }
91 connector.setAttribute("host", host);
92 connector.setAttribute("port", new Integer(port));
93 connector.setAttribute("minThreads", new Integer(10));
94 connector.setAttribute("maxThreads", new Integer(50));
95 connector.setReferencePattern(JettyConnector.CONNECTOR_CONTAINER_REFERENCE, containerName);
96 EditableConfigurationManager mgr = ConfigurationUtil.getEditableConfigurationManager(kernel);
97 if(mgr != null) {
98 try {
99 mgr.addGBeanToConfiguration(containerName.getArtifact(), connector, false);
100 return (WebConnector) kernel.getProxyManager().createProxy(name, JettyWebConnector.class.getClassLoader());
101 } catch (InvalidConfigException e) {
102 log.error("Unable to add GBean", e);
103 return null;
104 } finally {
105 ConfigurationUtil.releaseConfigurationManager(kernel, mgr);
106 }
107 } else {
108 log.warn("The ConfigurationManager in the kernel does not allow editing");
109 return null;
110 }
111 }
112
113 /**
114 * Get a list of containers for this web implementation.
115 */
116 public Object[] getContainers() {
117 ProxyManager proxyManager = kernel.getProxyManager();
118 AbstractNameQuery query = new AbstractNameQuery(JettyContainer.class.getName());
119 Set names = kernel.listGBeans(query);
120 JettyContainer[] results = new JettyContainer[names.size()];
121 int i=0;
122 for (Iterator it = names.iterator(); it.hasNext(); i++) {
123 AbstractName name = (AbstractName) it.next();
124 results[i] = (JettyContainer) proxyManager.createProxy(name, JettyContainer.class.getClassLoader());
125 }
126 return results;
127 }
128
129 /**
130 * Gets the protocols that this web container supports (that you can create
131 * connectors for).
132 */
133 public String[] getSupportedProtocols() {
134 return new String[]{PROTOCOL_HTTP, PROTOCOL_HTTPS, PROTOCOL_AJP};
135 }
136
137 /**
138 * Removes a connector. This shuts it down if necessary, and removes it
139 * from the server environment. It must be a connector that this container
140 * is responsible for.
141 * @param connectorName
142 */
143 public void removeConnector(AbstractName connectorName) {
144 try {
145 GBeanInfo info = kernel.getGBeanInfo(connectorName);
146 boolean found = false;
147 Set intfs = info.getInterfaces();
148 for (Iterator it = intfs.iterator(); it.hasNext();) {
149 String intf = (String) it.next();
150 if (intf.equals(JettyWebConnector.class.getName())) {
151 found = true;
152 }
153 }
154 if (!found) {
155 throw new GBeanNotFoundException(connectorName);
156 }
157 EditableConfigurationManager mgr = ConfigurationUtil.getEditableConfigurationManager(kernel);
158 if(mgr != null) {
159 try {
160 mgr.removeGBeanFromConfiguration(connectorName.getArtifact(), connectorName);
161 } catch (InvalidConfigException e) {
162 log.error("Unable to add GBean", e);
163 } finally {
164 ConfigurationUtil.releaseConfigurationManager(kernel, mgr);
165 }
166 } else {
167 log.warn("The ConfigurationManager in the kernel does not allow editing");
168 }
169 } catch (GBeanNotFoundException e) {
170 log.warn("No such GBean '" + connectorName + "'");
171 } catch (Exception e) {
172 log.error(e);
173 }
174 }
175
176 /**
177 * Gets the ObjectNames of any existing connectors for the specified
178 * protocol.
179 *
180 * @param protocol A protocol as returned by getSupportedProtocols
181 */
182 public NetworkConnector[] getConnectors(String protocol) {
183 if(protocol == null) {
184 return getConnectors();
185 }
186 List result = new ArrayList();
187 ProxyManager proxyManager = kernel.getProxyManager();
188 AbstractNameQuery query = new AbstractNameQuery(JettyWebConnector.class.getName());
189 Set names = kernel.listGBeans(query);
190 for (Iterator it = names.iterator(); it.hasNext();) {
191 AbstractName name = (AbstractName) it.next();
192 try {
193 if (kernel.getAttribute(name, "protocol").equals(protocol)) {
194 result.add(proxyManager.createProxy(name, JettyWebConnector.class.getClassLoader()));
195 }
196 } catch (Exception e) {
197 log.error("Unable to check the protocol for a connector", e);
198 }
199 }
200 return (JettyWebConnector[]) result.toArray(new JettyWebConnector[names.size()]);
201 }
202
203 public WebAccessLog getAccessLog(WebContainer container) {
204 AbstractNameQuery query = new AbstractNameQuery(JettyLogManager.class.getName());
205 Set names = kernel.listGBeans(query);
206 if(names.size() == 0) {
207 return null;
208 } else if(names.size() > 1) {
209 throw new IllegalStateException("Should not be more than one Jetty access log manager");
210 }
211 return (WebAccessLog) kernel.getProxyManager().createProxy((AbstractName)names.iterator().next(), JettyLogManager.class.getClassLoader());
212 }
213
214 /**
215 * Gets the ObjectNames of any existing connectors.
216 */
217 public NetworkConnector[] getConnectors() {
218 ProxyManager proxyManager = kernel.getProxyManager();
219 AbstractNameQuery query = new AbstractNameQuery(JettyWebConnector.class.getName());
220 Set names = kernel.listGBeans(query);
221 JettyWebConnector[] results = new JettyWebConnector[names.size()];
222 int i=0;
223 for (Iterator it = names.iterator(); it.hasNext(); i++) {
224 AbstractName name = (AbstractName) it.next();
225 results[i] = (JettyWebConnector) proxyManager.createProxy(name, JettyWebConnector.class.getClassLoader());
226 }
227 return results;
228 }
229
230 public NetworkConnector[] getConnectorsForContainer(Object container, String protocol) {
231 if(protocol == null) {
232 return getConnectorsForContainer(container);
233 }
234 AbstractName containerName = kernel.getAbstractNameFor(container);
235 ProxyManager mgr = kernel.getProxyManager();
236 try {
237 List results = new ArrayList();
238 AbstractNameQuery query = new AbstractNameQuery(JettyWebConnector.class.getName());
239 Set set = kernel.listGBeans(query);
240 for (Iterator it = set.iterator(); it.hasNext();) {
241 AbstractName name = (AbstractName) it.next();
242 GBeanData data = kernel.getGBeanData(name);
243 ReferencePatterns refs = data.getReferencePatterns(JettyConnector.CONNECTOR_CONTAINER_REFERENCE);
244 if(containerName.equals(refs.getAbstractName())) {
245 try {
246 String testProtocol = (String) kernel.getAttribute(name, "protocol");
247 if(testProtocol != null && testProtocol.equals(protocol)) {
248 results.add(mgr.createProxy(name, JettyWebConnector.class.getClassLoader()));
249 }
250 } catch (Exception e) {
251 log.error("Unable to look up protocol for connector '"+name+"'",e);
252 }
253 break;
254 }
255 }
256 return (JettyWebConnector[]) results.toArray(new JettyWebConnector[results.size()]);
257 } catch (Exception e) {
258 throw (IllegalArgumentException)new IllegalArgumentException("Unable to look up connectors for Jetty container '"+containerName +"': ").initCause(e);
259 }
260 }
261
262 public NetworkConnector[] getConnectorsForContainer(Object container) {
263 AbstractName containerName = kernel.getAbstractNameFor(container);
264 ProxyManager mgr = kernel.getProxyManager();
265 try {
266 List results = new ArrayList();
267 AbstractNameQuery query = new AbstractNameQuery(JettyWebConnector.class.getName());
268 Set set = kernel.listGBeans(query);
269 for (Iterator it = set.iterator(); it.hasNext();) {
270 AbstractName name = (AbstractName) it.next();
271 GBeanData data = kernel.getGBeanData(name);
272 ReferencePatterns refs = data.getReferencePatterns(JettyConnector.CONNECTOR_CONTAINER_REFERENCE);
273 if (containerName.equals(refs.getAbstractName())) {
274 results.add(mgr.createProxy(name, JettyWebConnector.class.getClassLoader()));
275 }
276 }
277 return (JettyWebConnector[]) results.toArray(new JettyWebConnector[results.size()]);
278 } catch (Exception e) {
279 throw (IllegalArgumentException) new IllegalArgumentException("Unable to look up connectors for Jetty container '"+containerName+"'").initCause(e);
280 }
281 }
282
283 public static final GBeanInfo GBEAN_INFO;
284
285 static {
286 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("Jetty Web Manager", JettyManagerImpl.class);
287 infoFactory.addAttribute("kernel", Kernel.class, false);
288 infoFactory.addInterface(WebManager.class);
289 infoFactory.setConstructor(new String[] {"kernel"});
290 GBEAN_INFO = infoFactory.getBeanInfo();
291 }
292
293 public static GBeanInfo getGBeanInfo() {
294 return GBEAN_INFO;
295 }
296 }