This is an automated email from the ASF dual-hosted git repository. lhotari pushed a commit to branch branch-4.15 in repository https://gitbox.apache.org/repos/asf/bookkeeper.git
commit a893a38f42f85e0c1a4882acc9f9aa1aa386fba3 Author: wenbingshen <[email protected]> AuthorDate: Mon Apr 29 11:13:34 2024 +0800 Prevent bookie shutdown due to rest api when bookie prohibits readOnlyMode (#3972) (cherry picked from commit 1d9e35dc1f27af8e615e16e5e4a8ef979382e013) --- .../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 6f4f5fe7b5..a89e8e5719 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 @@ -197,6 +197,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 a3f1065fb2..2403f3d6e3 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 @@ -54,6 +54,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 b0defc819c..6f8cf647b5 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 @@ -997,11 +997,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()); } }
