Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: f00174c8a9af5a441c7110efbe8951105532ad9e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*******************************************************************************
 * Copyright (c) 2005, 2017 Cognos Incorporated, IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Cognos Incorporated - initial API and implementation
 *     IBM Corporation - bug fixes and enhancements
 *     Raymond Augé - bug fixes and enhancements
 *******************************************************************************/

package org.eclipse.equinox.http.jetty.internal;

import java.io.File;
import java.util.*;
import org.eclipse.equinox.http.jetty.JettyConstants;
import org.osgi.framework.*;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.service.cm.ManagedServiceFactory;

public class Activator implements BundleActivator {

	private static final String JETTY_WORK_DIR = "jettywork"; //$NON-NLS-1$
	private static final String DEFAULT_PID = "default"; //$NON-NLS-1$
	private static final String MANAGED_SERVICE_FACTORY_PID = "org.eclipse.equinox.http.jetty.config"; //$NON-NLS-1$

	// OSGi Http Service suggest these properties for setting the default ports
	private static final String ORG_OSGI_SERVICE_HTTP_PORT = "org.osgi.service.http.port"; //$NON-NLS-1$
	private static final String ORG_OSGI_SERVICE_HTTP_PORT_SECURE = "org.osgi.service.http.port.secure"; //$NON-NLS-1$

	// controls whether start() should automatically start an Http Service based on BundleContext properties (default is true)
	// Note: only used if the bundle is explicitly started (e.g. not "lazy" activated)
	private static final String AUTOSTART = "org.eclipse.equinox.http.jetty.autostart"; //$NON-NLS-1$

	// Jetty will use a basic stderr logger if no other logging mechanism is provided.
	// This setting can be used to over-ride the stderr logger threshold(and only this default logger)
	// Valid values are in increasing threshold: "debug", "info", "warn", "error", and "off"
	// (default threshold is "warn")
	private static final String LOG_STDERR_THRESHOLD = "org.eclipse.equinox.http.jetty.log.stderr.threshold"; //$NON-NLS-1$

	// The staticServerManager is use by the start and stopServer methods and must be accessed in a static synchronized block
	// to ensure it is correctly handled in terms of the bundle life-cycle.
	private static HttpServerManager staticServerManager;

	private HttpServerManager httpServerManager;
	private ServiceRegistration<ManagedServiceFactory> registration;

	@Override
	public void start(BundleContext context) throws Exception {
		File jettyWorkDir = new File(context.getDataFile(""), JETTY_WORK_DIR); //$NON-NLS-1$
		jettyWorkDir.mkdir();
		EquinoxStdErrLog.setThresholdLogger(context.getProperty(LOG_STDERR_THRESHOLD));
		httpServerManager = new HttpServerManager(jettyWorkDir);

		boolean autostart = Details.getBoolean(context, AUTOSTART, true);
		if (autostart && !isBundleLazyActivationPolicyUsed(context)) {
			Dictionary<String, Object> defaultSettings = createDefaultSettings(context);
			httpServerManager.updated(DEFAULT_PID, defaultSettings);
		}

		Dictionary<String, Object> dictionary = new Hashtable<>();
		dictionary.put(Constants.SERVICE_PID, MANAGED_SERVICE_FACTORY_PID);

		registration = context.registerService(ManagedServiceFactory.class, httpServerManager, dictionary);
		setStaticServerManager(httpServerManager);
	}

	private boolean isBundleLazyActivationPolicyUsed(BundleContext context) {
		if (context.getBundle().adapt(BundleStartLevel.class).isActivationPolicyUsed()) {
			// checking for lazy capability; NOTE this is equinox specific
			// but we fall back to header lookup for other frameworks
			List<BundleCapability> moduleData = context.getBundle().adapt(BundleRevision.class).getDeclaredCapabilities("equinox.module.data"); //$NON-NLS-1$
			String activationPolicy = null;
			if (moduleData.isEmpty()) {
				activationPolicy = context.getBundle().getHeaders("").get(Constants.BUNDLE_ACTIVATIONPOLICY); //$NON-NLS-1$
			} else {
				activationPolicy = (String) moduleData.get(0).getAttributes().get("activation.policy"); //$NON-NLS-1$
			}
			return activationPolicy == null ? false : activationPolicy.startsWith(Constants.ACTIVATION_LAZY);
		}
		return false;
	}

	@Override
	public void stop(BundleContext context) throws Exception {
		setStaticServerManager(null);
		registration.unregister();
		registration = null;

		httpServerManager.shutdown();
		httpServerManager = null;
	}

	private Dictionary<String, Object> createDefaultSettings(BundleContext context) {
		Dictionary<String, Object> defaultSettings = new Hashtable<>();

		// PID
		defaultSettings.put(Constants.SERVICE_PID, DEFAULT_PID);

		// HTTP Enabled (default is true)
		Boolean httpEnabled = Details.getBooleanProp(context, JettyConstants.HTTP_ENABLED, true);
		defaultSettings.put(JettyConstants.HTTP_ENABLED, httpEnabled);

		// HTTP Port
		int httpPort = Details.getIntProp(context, JettyConstants.HTTP_PORT, -1);
		if (httpPort == -1)
			httpPort = Details.getInt(context, ORG_OSGI_SERVICE_HTTP_PORT, 0);
		defaultSettings.put(JettyConstants.HTTP_PORT, Integer.valueOf(httpPort));

		// HTTP Host (default is 0.0.0.0)
		String httpHost = Details.getStringProp(context, JettyConstants.HTTP_HOST, null);
		if (httpHost != null)
			defaultSettings.put(JettyConstants.HTTP_HOST, httpHost);

		// HTTPS Enabled (default is false)
		Boolean httpsEnabled = Details.getBooleanProp(context, JettyConstants.HTTPS_ENABLED, false);
		defaultSettings.put(JettyConstants.HTTPS_ENABLED, httpsEnabled);

		// minimum number of threads
		int minThreads = Details.getIntProp(context, JettyConstants.HTTP_MINTHREADS, 8);
		if (minThreads != -1) {
			defaultSettings.put(JettyConstants.HTTP_MINTHREADS, Integer.valueOf(minThreads));
		}

		// maximum number of threads
		int maxThreads = Details.getIntProp(context, JettyConstants.HTTP_MAXTHREADS, 200);
		if (maxThreads != -1) {
			defaultSettings.put(JettyConstants.HTTP_MAXTHREADS, Integer.valueOf(maxThreads));
		}

		if (httpsEnabled.booleanValue()) {
			// HTTPS Port

			int httpsPort = Details.getIntProp(context, JettyConstants.HTTPS_PORT, -1);
			if (httpsPort == -1)
				httpsPort = Details.getInt(context, ORG_OSGI_SERVICE_HTTP_PORT_SECURE, 443);
			defaultSettings.put(JettyConstants.HTTPS_PORT, Integer.valueOf(httpsPort));

			// HTTPS Host (default is 0.0.0.0)
			String httpsHost = Details.getStringProp(context, JettyConstants.HTTPS_HOST, null);
			if (httpsHost != null)
				defaultSettings.put(JettyConstants.HTTPS_HOST, httpsHost);

			// SSL SETTINGS
			String keystore = Details.getStringProp(context, JettyConstants.SSL_KEYSTORE, null);
			if (keystore != null)
				defaultSettings.put(JettyConstants.SSL_KEYSTORE, keystore);

			String password = Details.getStringProp(context, JettyConstants.SSL_PASSWORD, null);
			if (password != null)
				defaultSettings.put(JettyConstants.SSL_PASSWORD, password);

			String keypassword = Details.getStringProp(context, JettyConstants.SSL_KEYPASSWORD, null);
			if (keypassword != null)
				defaultSettings.put(JettyConstants.SSL_KEYPASSWORD, keypassword);

			String needclientauth = Details.getStringProp(context, JettyConstants.SSL_NEEDCLIENTAUTH, null);
			if (needclientauth != null)
				defaultSettings.put(JettyConstants.SSL_NEEDCLIENTAUTH, Boolean.valueOf(needclientauth));

			String wantclientauth = Details.getStringProp(context, JettyConstants.SSL_WANTCLIENTAUTH, null);
			if (wantclientauth != null)
				defaultSettings.put(JettyConstants.SSL_WANTCLIENTAUTH, Boolean.valueOf(wantclientauth));

			String protocol = Details.getStringProp(context, JettyConstants.SSL_PROTOCOL, null);
			if (protocol != null)
				defaultSettings.put(JettyConstants.SSL_PROTOCOL, protocol);

			String algorithm = Details.getStringProp(context, JettyConstants.SSL_ALGORITHM, null);
			if (algorithm != null)
				defaultSettings.put(JettyConstants.SSL_ALGORITHM, algorithm);

			String keystoretype = Details.getStringProp(context, JettyConstants.SSL_KEYSTORETYPE, null);
			if (keystoretype != null)
				defaultSettings.put(JettyConstants.SSL_KEYSTORETYPE, keystoretype);
		}

		// Servlet Context Path
		String contextpath = Details.getStringProp(context, JettyConstants.CONTEXT_PATH, null);
		if (contextpath != null)
			defaultSettings.put(JettyConstants.CONTEXT_PATH, contextpath);

		// Session Inactive Interval (timeout)
		String sessionInactiveInterval = Details.getStringProp(context, JettyConstants.CONTEXT_SESSIONINACTIVEINTERVAL, null);
		if (sessionInactiveInterval != null) {
			try {
				defaultSettings.put(JettyConstants.CONTEXT_SESSIONINACTIVEINTERVAL, Integer.valueOf(sessionInactiveInterval));
			} catch (NumberFormatException e) {
				//(log this) ignore
			}
		}

		// House Keeper Interval
		String houseKeeperInterval = Details.getStringProp(context, JettyConstants.HOUSEKEEPER_INTERVAL, null);
		if (houseKeeperInterval != null) {
			try {
				defaultSettings.put(JettyConstants.HOUSEKEEPER_INTERVAL, Long.valueOf(houseKeeperInterval));
			} catch (NumberFormatException e) {
				//(log this) ignore
			}
		}

		// Other Info
		String otherInfo = Details.getStringProp(context, JettyConstants.OTHER_INFO, null);
		if (otherInfo != null)
			defaultSettings.put(JettyConstants.OTHER_INFO, otherInfo);

		// customizer
		String customizerClass = Details.getStringProp(context, JettyConstants.CUSTOMIZER_CLASS, null);
		if (customizerClass != null)
			defaultSettings.put(JettyConstants.CUSTOMIZER_CLASS, customizerClass);

		return defaultSettings;
	}

	public synchronized static void startServer(String pid, Dictionary<String, ?> settings) throws Exception {
		if (staticServerManager == null)
			throw new IllegalStateException("Inactive"); //$NON-NLS-1$

		staticServerManager.updated(pid, settings);
	}

	public synchronized static void stopServer(String pid) throws Exception {
		if (staticServerManager != null)
			staticServerManager.deleted(pid);
	}

	private synchronized static void setStaticServerManager(HttpServerManager httpServerManager) {
		staticServerManager = httpServerManager;
	}
}

Back to the top