Skip to content

Commit 2eb711b

Browse files
committed
FELIX-6706 : Avoid Jetty restart in case of a required configuration
1 parent 6a59d8f commit 2eb711b

File tree

4 files changed

+112
-42
lines changed

4 files changed

+112
-42
lines changed

http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ public final class JettyConfig
274274
/** Felix specific property to control whether to enable they Jetty-specific WebSocket APIs */
275275
public static final String FELIX_JETTY_WEBSOCKET_ENABLE = "org.apache.felix.jetty.websocket.enable";
276276

277+
/** Felix specific property to control whether an OSGi configuration is required */
278+
private static final String FELIX_REQUIRE_OSGI_CONFIG = "org.apache.felix.http.require.config";
277279

278280
private static String validateContextPath(String ctxPath)
279281
{
@@ -964,4 +966,8 @@ private long parseLong(String value, long dflt)
964966
return dflt;
965967
}
966968
}
969+
970+
public boolean isRequireConfiguration() {
971+
return this.getBooleanProperty(FELIX_REQUIRE_OSGI_CONFIG, false);
972+
}
967973
}

http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -83,32 +83,57 @@ public final class JettyService
8383
private volatile FileRequestLog fileRequestLog;
8484
private volatile LoadBalancerCustomizerFactoryTracker loadBalancerCustomizerTracker;
8585
private volatile CustomizerWrapper customizerWrapper;
86-
private boolean registerManagedService = true;
86+
87+
private final boolean registerManagedService;
8788
private final String jettyVersion;
89+
private final boolean immediatelyStartJetty;
8890

89-
public JettyService(final BundleContext context,
90-
final HttpServiceController controller)
91-
{
91+
/**
92+
* Shared constructor for JettyService instances.
93+
* @param context The bundle context
94+
* @param controller The HTTP service controller
95+
* @param registerManagedService Whether to register the managed service
96+
*/
97+
private JettyService(final BundleContext context,
98+
final HttpServiceController controller,
99+
final boolean registerManagedService) {
92100
this.jettyVersion = fixJettyVersion(context);
93101

94102
this.context = context;
95103
this.config = new JettyConfig(this.context);
96104
this.controller = controller;
105+
this.registerManagedService = registerManagedService;
106+
this.immediatelyStartJetty = !registerManagedService || !this.config.isRequireConfiguration();
97107
}
98108

109+
/**
110+
* Constructor for the managed service jetty service.
111+
* @param context The bundle context
112+
* @param controller The HTTP service controller
113+
*/
114+
public JettyService(final BundleContext context,
115+
final HttpServiceController controller) {
116+
this(context, controller, true);
117+
}
118+
119+
/**
120+
* Constructor for the managed service factory jetty service.
121+
* @param context The bundle context
122+
* @param controller The HTTP service controller
123+
* @param props The configuration properties
124+
*/
99125
public JettyService(final BundleContext context,
100126
final HttpServiceController controller,
101-
final Dictionary<String,?> props)
102-
{
103-
this(context, controller);
127+
final Dictionary<String,?> props) {
128+
this(context, controller, false);
104129
this.config.update(props);
105-
this.registerManagedService = false;
106130
}
107131

108-
public void start() throws Exception
109-
{
110-
// FELIX-4422: start Jetty synchronously...
111-
startJetty();
132+
public void start() throws Exception {
133+
if ( this.immediatelyStartJetty) {
134+
// FELIX-4422: start Jetty synchronously...
135+
startJetty();
136+
}
112137

113138
if (this.registerManagedService) {
114139
final Dictionary<String, Object> props = new Hashtable<>();
@@ -134,11 +159,14 @@ public void ungetService(Bundle bundle, ServiceRegistration registration, Object
134159
}
135160
}
136161

137-
public void stop() throws Exception
138-
{
139-
if (this.configServiceReg != null)
140-
{
141-
this.configServiceReg.unregister();
162+
public void stop() throws Exception {
163+
if (this.configServiceReg != null) {
164+
try {
165+
// ignore potential exception on shutdown
166+
this.configServiceReg.unregister();
167+
} catch (final IllegalStateException e) {
168+
// ignore
169+
}
142170
this.configServiceReg = null;
143171
}
144172

@@ -157,10 +185,11 @@ private Hashtable<String, Object> getServiceProperties()
157185
return props;
158186
}
159187

160-
public void updated(final Dictionary<String, ?> props)
161-
{
162-
if (this.config.update(props))
163-
{
188+
public void updated(final Dictionary<String, ?> props) {
189+
final boolean changed = this.config.update(props);
190+
if (props == null && !this.immediatelyStartJetty) { // null is only passed for the managed service
191+
stopJetty();
192+
} else if (changed) {
164193
// Something changed in our configuration, restart Jetty...
165194
stopJetty();
166195
startJetty();

http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ public final class JettyConfig
277277
/** Felix specific property to control whether to enable they Jetty-specific WebSocket APIs */
278278
public static final String FELIX_JETTY_WEBSOCKET_ENABLE = "org.apache.felix.jetty.websocket.enable";
279279

280+
/** Felix specific property to control whether an OSGi configuration is required */
281+
private static final String FELIX_REQUIRE_OSGI_CONFIG = "org.apache.felix.http.require.config";
282+
280283
private static String validateContextPath(String ctxPath)
281284
{
282285
// undefined, empty, or root context path
@@ -966,4 +969,8 @@ private long parseLong(String value, long dflt)
966969
return dflt;
967970
}
968971
}
972+
973+
public boolean isRequireConfiguration() {
974+
return this.getBooleanProperty(FELIX_REQUIRE_OSGI_CONFIG, false);
975+
}
969976
}

http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -85,32 +85,56 @@ public final class JettyService
8585
private volatile FileRequestLog fileRequestLog;
8686
private volatile LoadBalancerCustomizerFactoryTracker loadBalancerCustomizerTracker;
8787
private volatile CustomizerWrapper customizerWrapper;
88-
private boolean registerManagedService = true;
88+
private final boolean registerManagedService;
8989
private final String jettyVersion;
90+
private final boolean immediatelyStartJetty;
9091

91-
public JettyService(final BundleContext context,
92-
final HttpServiceController controller)
93-
{
92+
/**
93+
* Shared constructor for JettyService instances.
94+
* @param context The bundle context
95+
* @param controller The HTTP service controller
96+
* @param registerManagedService Whether to register the managed service
97+
*/
98+
private JettyService(final BundleContext context,
99+
final HttpServiceController controller,
100+
final boolean registerManagedService) {
94101
this.jettyVersion = fixJettyVersion(context);
95102

96103
this.context = context;
97104
this.config = new JettyConfig(this.context);
98105
this.controller = controller;
106+
this.registerManagedService = registerManagedService;
107+
this.immediatelyStartJetty = !registerManagedService || !this.config.isRequireConfiguration();
108+
}
109+
110+
/**
111+
* Constructor for the managed service jetty service.
112+
* @param context The bundle context
113+
* @param controller The HTTP service controller
114+
*/
115+
public JettyService(final BundleContext context,
116+
final HttpServiceController controller) {
117+
this(context, controller, true);
99118
}
100119

120+
/**
121+
* Constructor for the managed service factory jetty service.
122+
* @param context The bundle context
123+
* @param controller The HTTP service controller
124+
* @param props The configuration properties
125+
*/
101126
public JettyService(final BundleContext context,
102127
final HttpServiceController controller,
103-
final Dictionary<String,?> props)
104-
{
105-
this(context, controller);
128+
final Dictionary<String,?> props) {
129+
this(context, controller, false);
106130
this.config.update(props);
107-
this.registerManagedService = false;
108131
}
109132

110-
public void start() throws Exception
111-
{
112-
// FELIX-4422: start Jetty synchronously...
113-
startJetty();
133+
public void start() throws Exception {
134+
if ( this.immediatelyStartJetty) {
135+
// FELIX-4422: start Jetty synchronously...
136+
startJetty();
137+
}
114138

115139
if (this.registerManagedService) {
116140
final Dictionary<String, Object> props = new Hashtable<>();
@@ -136,11 +160,14 @@ public void ungetService(Bundle bundle, ServiceRegistration registration, Object
136160
}
137161
}
138162

139-
public void stop() throws Exception
140-
{
141-
if (this.configServiceReg != null)
142-
{
143-
this.configServiceReg.unregister();
163+
public void stop() throws Exception {
164+
if (this.configServiceReg != null) {
165+
try {
166+
// ignore potential exception on shutdown
167+
this.configServiceReg.unregister();
168+
} catch (final IllegalStateException e) {
169+
// ignore
170+
}
144171
this.configServiceReg = null;
145172
}
146173

@@ -159,10 +186,11 @@ private Hashtable<String, Object> getServiceProperties()
159186
return props;
160187
}
161188

162-
public void updated(final Dictionary<String, ?> props)
163-
{
164-
if (this.config.update(props))
165-
{
189+
public void updated(final Dictionary<String, ?> props) {
190+
final boolean changed = this.config.update(props);
191+
if (props == null && !this.immediatelyStartJetty) { // null is only passed for the managed service
192+
stopJetty();
193+
} else if (changed) {
166194
// Something changed in our configuration, restart Jetty...
167195
stopJetty();
168196
startJetty();

0 commit comments

Comments
 (0)