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

shenwenbing pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git


The following commit(s) were added to refs/heads/master by this push:
     new 1d9e35dc1f Prevent bookie shutdown due to rest api when bookie 
prohibits readOnlyMode (#3972)
1d9e35dc1f is described below

commit 1d9e35dc1f27af8e615e16e5e4a8ef979382e013
Author: wenbingshen <oliver.shen...@gmail.com>
AuthorDate: Mon Apr 29 11:13:34 2024 +0800

    Prevent bookie shutdown due to rest api when bookie prohibits readOnlyMode 
(#3972)
---
 .../bookkeeper/bookie/BookieStateManager.java      |  5 +++
 .../org/apache/bookkeeper/bookie/StateManager.java |  5 +++
 .../http/service/BookieStateReadOnlyService.java   |  5 +++
 .../bookkeeper/server/http/TestHttpService.java    | 40 +++++++++++++++++++---
 4 files changed, 51 insertions(+), 4 deletions(-)

diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieStateManager.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieStateManager.java
index 6f029e6782..9800d9e063 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieStateManager.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieStateManager.java
@@ -235,6 +235,11 @@ public class BookieStateManager implements StateManager {
         return forceReadOnly.get();
     }
 
+    @Override
+    public boolean isReadOnlyModeEnabled() {
+        return conf.isReadOnlyModeEnabled();
+    }
+
     @Override
     public boolean isAvailableForHighPriorityWrites() {
         return availableForHighPriorityWrites;
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/StateManager.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/StateManager.java
index d279893a8a..7ed3f0b657 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/StateManager.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/StateManager.java
@@ -53,6 +53,11 @@ public interface StateManager extends AutoCloseable {
      */
     boolean isForceReadOnly();
 
+    /**
+     * Check is readOnlyModeEnabled.
+     */
+    boolean isReadOnlyModeEnabled();
+
     /**
      * Check is Running.
      */
diff --git 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieStateReadOnlyService.java
 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieStateReadOnlyService.java
index 23211d5218..d32074e2bb 100644
--- 
a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieStateReadOnlyService.java
+++ 
b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieStateReadOnlyService.java
@@ -60,6 +60,11 @@ public class BookieStateReadOnlyService implements 
HttpEndpointService {
                 }
                 stateManager.transitionToWritableMode().get();
             } else if (!stateManager.isReadOnly() && inState.isReadOnly()) {
+                if (!stateManager.isReadOnlyModeEnabled()) {
+                    response.setCode(HttpServer.StatusCode.BAD_REQUEST);
+                    response.setBody("Bookie is disabled ReadOnly mode, cannot 
transit to readOnly mode");
+                    return response;
+                }
                 stateManager.transitionToReadOnlyMode().get();
             }
         } else if (!HttpServer.Method.GET.equals(request.getMethod())) {
diff --git 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
index 847c1118f5..2ea869e9da 100644
--- 
a/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
+++ 
b/bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java
@@ -1023,11 +1023,43 @@ public class TestHttpService extends 
BookKeeperClusterTestCase {
         assertFalse(readOnlyState.isReadOnly());
 
         //forceReadonly to writable
-        baseConf.setForceReadOnlyBookie(true);
-        baseConf.setReadOnlyModeEnabled(true);
-        restartBookies();
+        MetadataBookieDriver metadataDriver = 
BookieResources.createMetadataDriver(
+                baseConf, NullStatsLogger.INSTANCE);
+        restartBookies(c -> {
+            c.setForceReadOnlyBookie(true);
+            c.setReadOnlyModeEnabled(true);
+            return c;
+        });
+        // the old bkHttpServiceProvider has an old bookie instance who has 
been shutdown
+        // so we need create a new bkHttpServiceProvider2 to contains a new 
bookie which has created by restart.
+        BKHttpServiceProvider bkHttpServiceProvider2 = new 
BKHttpServiceProvider.Builder()
+                .setBookieServer(serverByIndex(numberOfBookies - 1))
+                .setServerConfiguration(baseConf)
+                
.setLedgerManagerFactory(metadataDriver.getLedgerManagerFactory())
+                .build();
+        HttpEndpointService bookieReadOnlyService2 = bkHttpServiceProvider2
+                
.provideHttpEndpointService(HttpServer.ApiType.BOOKIE_STATE_READONLY);
+
         request = new HttpServiceRequest(JsonUtil.toJson(new 
ReadOnlyState(false)), HttpServer.Method.PUT,  null);
-        response = bookieReadOnlyService.handle(request);
+        response = bookieReadOnlyService2.handle(request);
+        assertEquals(400, response.getStatusCode());
+
+        // disable readOnly mode
+        restartBookies(c -> {
+            c.setForceReadOnlyBookie(false);
+            c.setReadOnlyModeEnabled(false);
+            return c;
+        });
+        bkHttpServiceProvider2 = new BKHttpServiceProvider.Builder()
+                .setBookieServer(serverByIndex(numberOfBookies - 1))
+                .setServerConfiguration(baseConf)
+                
.setLedgerManagerFactory(metadataDriver.getLedgerManagerFactory())
+                .build();
+        bookieReadOnlyService2 = bkHttpServiceProvider2
+                
.provideHttpEndpointService(HttpServer.ApiType.BOOKIE_STATE_READONLY);
+
+        request = new HttpServiceRequest(JsonUtil.toJson(new 
ReadOnlyState(true)), HttpServer.Method.PUT,  null);
+        response = bookieReadOnlyService2.handle(request);
         assertEquals(400, response.getStatusCode());
     }
 

Reply via email to