This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new 2eb711b5c2 FELIX-6706 : Avoid Jetty restart in case of a required 
configuration
2eb711b5c2 is described below

commit 2eb711b5c2e79d6e089725b3463f4fd661cd93f1
Author: Carsten Ziegeler <cziege...@apache.org>
AuthorDate: Wed May 8 09:38:13 2024 +0200

    FELIX-6706 : Avoid Jetty restart in case of a required configuration
---
 .../felix/http/jetty/internal/JettyConfig.java     |  6 ++
 .../felix/http/jetty/internal/JettyService.java    | 71 +++++++++++++++-------
 .../felix/http/jetty/internal/JettyConfig.java     |  7 +++
 .../felix/http/jetty/internal/JettyService.java    | 70 ++++++++++++++-------
 4 files changed, 112 insertions(+), 42 deletions(-)

diff --git 
a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
 
b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
index bba6ef7794..bb94561c84 100644
--- 
a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
+++ 
b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
@@ -274,6 +274,8 @@ public final class JettyConfig
     /** Felix specific property to control whether to enable they 
Jetty-specific WebSocket APIs */
     public static final String FELIX_JETTY_WEBSOCKET_ENABLE = 
"org.apache.felix.jetty.websocket.enable";
 
+    /** Felix specific property to control whether an OSGi configuration is 
required */
+    private static final String FELIX_REQUIRE_OSGI_CONFIG = 
"org.apache.felix.http.require.config";
 
     private static String validateContextPath(String ctxPath)
     {
@@ -964,4 +966,8 @@ public final class JettyConfig
             return dflt;
         }
     }
+
+    public boolean isRequireConfiguration() {
+        return this.getBooleanProperty(FELIX_REQUIRE_OSGI_CONFIG, false);
+    }
 }
diff --git 
a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
 
b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
index 4b2e62c6b5..123deefc2e 100644
--- 
a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
+++ 
b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
@@ -83,32 +83,57 @@ public final class JettyService
     private volatile FileRequestLog fileRequestLog;
     private volatile LoadBalancerCustomizerFactoryTracker 
loadBalancerCustomizerTracker;
     private volatile CustomizerWrapper customizerWrapper;
-    private boolean registerManagedService = true;
+
+    private final boolean registerManagedService;
     private final String jettyVersion;
+    private final boolean immediatelyStartJetty;
 
-    public JettyService(final BundleContext context,
-            final HttpServiceController controller)
-    {
+    /**
+     * Shared constructor for JettyService instances.
+     * @param context The bundle context
+     * @param controller The HTTP service controller
+     * @param registerManagedService Whether to register the managed service
+     */
+    private JettyService(final BundleContext context,
+            final HttpServiceController controller,
+            final boolean registerManagedService) {
         this.jettyVersion = fixJettyVersion(context);
 
         this.context = context;
         this.config = new JettyConfig(this.context);
         this.controller = controller;
+        this.registerManagedService = registerManagedService;
+        this.immediatelyStartJetty = !registerManagedService || 
!this.config.isRequireConfiguration();
     }
 
+    /**
+     * Constructor for the managed service jetty service.
+     * @param context The bundle context
+     * @param controller The HTTP service controller
+     */
+    public JettyService(final BundleContext context,
+            final HttpServiceController controller) {
+        this(context, controller, true);
+    }
+
+    /**
+     * Constructor for the managed service factory jetty service.
+     * @param context The bundle context
+     * @param controller The HTTP service controller
+     * @param props The configuration properties
+     */
     public JettyService(final BundleContext context,
             final HttpServiceController controller,
-            final Dictionary<String,?> props)
-    {
-        this(context, controller);
+            final Dictionary<String,?> props) {
+        this(context, controller, false);
            this.config.update(props);
-           this.registerManagedService = false;
     }
 
-    public void start() throws Exception
-    {
-        // FELIX-4422: start Jetty synchronously...
-        startJetty();
+    public void start() throws Exception {
+        if ( this.immediatelyStartJetty) {
+            // FELIX-4422: start Jetty synchronously...
+            startJetty();
+        }
 
         if (this.registerManagedService) {
                        final Dictionary<String, Object> props = new 
Hashtable<>();
@@ -134,11 +159,14 @@ public final class JettyService
         }
     }
 
-    public void stop() throws Exception
-    {
-        if (this.configServiceReg != null)
-        {
-            this.configServiceReg.unregister();
+    public void stop() throws Exception {
+        if (this.configServiceReg != null) {
+            try {
+                // ignore potential exception on shutdown
+                this.configServiceReg.unregister();
+            } catch (final IllegalStateException e) {
+                // ignore
+            }
             this.configServiceReg = null;
         }
 
@@ -157,10 +185,11 @@ public final class JettyService
         return props;
     }
 
-    public void updated(final Dictionary<String, ?> props)
-    {
-        if (this.config.update(props))
-        {
+    public void updated(final Dictionary<String, ?> props) {
+        final boolean changed = this.config.update(props);
+        if (props == null && !this.immediatelyStartJetty) { // null is only 
passed for the managed service
+            stopJetty();
+        } else if (changed) {
             // Something changed in our configuration, restart Jetty...
             stopJetty();
             startJetty();
diff --git 
a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
 
b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
index 568c0efa84..a859d226f7 100644
--- 
a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
+++ 
b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
@@ -277,6 +277,9 @@ public final class JettyConfig
     /** Felix specific property to control whether to enable they 
Jetty-specific WebSocket APIs */
     public static final String FELIX_JETTY_WEBSOCKET_ENABLE = 
"org.apache.felix.jetty.websocket.enable";
 
+    /** Felix specific property to control whether an OSGi configuration is 
required */
+    private static final String FELIX_REQUIRE_OSGI_CONFIG = 
"org.apache.felix.http.require.config";
+
     private static String validateContextPath(String ctxPath)
     {
         // undefined, empty, or root context path
@@ -966,4 +969,8 @@ public final class JettyConfig
             return dflt;
         }
     }
+
+    public boolean isRequireConfiguration() {
+        return this.getBooleanProperty(FELIX_REQUIRE_OSGI_CONFIG, false);
+    }
 }
diff --git 
a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
 
b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
index 19d686b414..b52adc5a5b 100644
--- 
a/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
+++ 
b/http/jetty12/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
@@ -85,32 +85,56 @@ public final class JettyService
     private volatile FileRequestLog fileRequestLog;
     private volatile LoadBalancerCustomizerFactoryTracker 
loadBalancerCustomizerTracker;
     private volatile CustomizerWrapper customizerWrapper;
-    private boolean registerManagedService = true;
+    private final boolean registerManagedService;
     private final String jettyVersion;
+    private final boolean immediatelyStartJetty;
 
-    public JettyService(final BundleContext context,
-            final HttpServiceController controller)
-    {
+    /**
+     * Shared constructor for JettyService instances.
+     * @param context The bundle context
+     * @param controller The HTTP service controller
+     * @param registerManagedService Whether to register the managed service
+     */
+    private JettyService(final BundleContext context,
+            final HttpServiceController controller,
+            final boolean registerManagedService) {
         this.jettyVersion = fixJettyVersion(context);
 
         this.context = context;
         this.config = new JettyConfig(this.context);
         this.controller = controller;
+        this.registerManagedService = registerManagedService;
+        this.immediatelyStartJetty = !registerManagedService || 
!this.config.isRequireConfiguration();
+    }
+
+    /**
+     * Constructor for the managed service jetty service.
+     * @param context The bundle context
+     * @param controller The HTTP service controller
+     */
+    public JettyService(final BundleContext context,
+            final HttpServiceController controller) {
+        this(context, controller, true);
     }
 
+    /**
+     * Constructor for the managed service factory jetty service.
+     * @param context The bundle context
+     * @param controller The HTTP service controller
+     * @param props The configuration properties
+     */
     public JettyService(final BundleContext context,
             final HttpServiceController controller,
-            final Dictionary<String,?> props)
-    {
-        this(context, controller);
+            final Dictionary<String,?> props) {
+        this(context, controller, false);
            this.config.update(props);
-           this.registerManagedService = false;
     }
 
-    public void start() throws Exception
-    {
-        // FELIX-4422: start Jetty synchronously...
-        startJetty();
+    public void start() throws Exception {
+        if ( this.immediatelyStartJetty) {
+            // FELIX-4422: start Jetty synchronously...
+            startJetty();
+        }
 
         if (this.registerManagedService) {
                        final Dictionary<String, Object> props = new 
Hashtable<>();
@@ -136,11 +160,14 @@ public final class JettyService
         }
     }
 
-    public void stop() throws Exception
-    {
-        if (this.configServiceReg != null)
-        {
-            this.configServiceReg.unregister();
+    public void stop() throws Exception {
+        if (this.configServiceReg != null) {
+            try {
+                // ignore potential exception on shutdown
+                this.configServiceReg.unregister();
+            } catch (final IllegalStateException e) {
+                // ignore
+            }
             this.configServiceReg = null;
         }
 
@@ -159,10 +186,11 @@ public final class JettyService
         return props;
     }
 
-    public void updated(final Dictionary<String, ?> props)
-    {
-        if (this.config.update(props))
-        {
+    public void updated(final Dictionary<String, ?> props) {
+        final boolean changed = this.config.update(props);
+        if (props == null && !this.immediatelyStartJetty) { // null is only 
passed for the managed service
+            stopJetty();
+        } else if (changed) {
             // Something changed in our configuration, restart Jetty...
             stopJetty();
             startJetty();

Reply via email to