Skip to content

Commit 341f7d7

Browse files
authored
Delete cookie as part of decommission API (#4592)
Implement the logic in [BP-68:](#4500) Delete cookie as part of decommission API.
1 parent d71cd1e commit 341f7d7

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/DecommissionService.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919
package org.apache.bookkeeper.server.http.service;
2020

2121
import static com.google.common.base.Preconditions.checkNotNull;
22+
import static org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithRegistrationManager;
2223

2324
import java.util.HashMap;
2425
import java.util.concurrent.ExecutorService;
26+
import org.apache.bookkeeper.bookie.BookieException;
27+
import org.apache.bookkeeper.bookie.Cookie;
2528
import org.apache.bookkeeper.client.BookKeeperAdmin;
2629
import org.apache.bookkeeper.common.util.JsonUtil;
2730
import org.apache.bookkeeper.conf.ServerConfiguration;
@@ -30,6 +33,7 @@
3033
import org.apache.bookkeeper.http.service.HttpServiceRequest;
3134
import org.apache.bookkeeper.http.service.HttpServiceResponse;
3235
import org.apache.bookkeeper.net.BookieId;
36+
import org.apache.bookkeeper.versioning.Versioned;
3337
import org.slf4j.Logger;
3438
import org.slf4j.LoggerFactory;
3539

@@ -74,12 +78,30 @@ public HttpServiceResponse handle(HttpServiceRequest request) throws Exception {
7478
if (configMap != null && configMap.containsKey("bookie_src")) {
7579
try {
7680
BookieId bookieSrc = BookieId.parse(configMap.get("bookie_src"));
81+
boolean deleteCookie = Boolean.parseBoolean(configMap.getOrDefault("delete_cookie", "false"));
7782

7883
executor.execute(() -> {
7984
try {
8085
LOG.info("Start decommissioning bookie.");
8186
bka.decommissionBookie(bookieSrc);
8287
LOG.info("Complete decommissioning bookie.");
88+
if (deleteCookie) {
89+
runFunctionWithRegistrationManager(conf, rm -> {
90+
try {
91+
Versioned<Cookie> cookie = Cookie.readFromRegistrationManager(rm, bookieSrc);
92+
cookie.getValue().deleteFromRegistrationManager(rm, bookieSrc,
93+
cookie.getVersion());
94+
LOG.info("Cookie of the decommissioned bookie: {} is deleted successfully",
95+
bookieSrc);
96+
} catch (BookieException.CookieNotFoundException nne) {
97+
LOG.warn("No cookie to remove for the decommissioning bookie: {}, "
98+
+ "it could be deleted already", bookieSrc, nne);
99+
} catch (BookieException be) {
100+
LOG.error("Error deleting cookie: {}.", bookieSrc, be);
101+
}
102+
return true;
103+
});
104+
}
83105
} catch (Exception e) {
84106
LOG.error("Error handling decommissionBookie: {}.", bookieSrc, e);
85107
}

bookkeeper-server/src/test/java/org/apache/bookkeeper/server/http/TestHttpService.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.apache.bookkeeper.server.http;
2020

2121
import static org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithLedgerManagerFactory;
22+
import static org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithRegistrationManager;
2223
import static org.junit.jupiter.api.Assertions.assertEquals;
2324
import static org.junit.jupiter.api.Assertions.assertFalse;
2425
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -37,8 +38,11 @@
3738
import java.util.List;
3839
import java.util.Map;
3940
import java.util.concurrent.Future;
41+
import java.util.concurrent.TimeUnit;
4042
import lombok.Cleanup;
43+
import org.apache.bookkeeper.bookie.BookieException;
4144
import org.apache.bookkeeper.bookie.BookieResources;
45+
import org.apache.bookkeeper.bookie.Cookie;
4246
import org.apache.bookkeeper.bookie.LedgerStorage;
4347
import org.apache.bookkeeper.client.BookKeeper;
4448
import org.apache.bookkeeper.client.ClientUtil;
@@ -55,6 +59,7 @@
5559
import org.apache.bookkeeper.meta.LedgerManagerFactory;
5660
import org.apache.bookkeeper.meta.LedgerUnderreplicationManager;
5761
import org.apache.bookkeeper.meta.MetadataBookieDriver;
62+
import org.apache.bookkeeper.net.BookieId;
5863
import org.apache.bookkeeper.net.BookieSocketAddress;
5964
import org.apache.bookkeeper.proto.BookieServer;
6065
import org.apache.bookkeeper.replication.AuditorElector;
@@ -66,6 +71,8 @@
6671
import org.apache.bookkeeper.server.http.service.ClusterInfoService;
6772
import org.apache.bookkeeper.stats.NullStatsLogger;
6873
import org.apache.bookkeeper.test.BookKeeperClusterTestCase;
74+
import org.apache.bookkeeper.versioning.Versioned;
75+
import org.awaitility.Awaitility;
6976
import org.junit.jupiter.api.AfterEach;
7077
import org.junit.jupiter.api.BeforeEach;
7178
import org.junit.jupiter.api.Test;
@@ -765,15 +772,61 @@ public void testDecommissionService() throws Exception {
765772
assertEquals(HttpServer.StatusCode.NOT_FOUND.getValue(), response2.getStatusCode());
766773

767774
//3, PUT, with body, should success.
768-
String putBody3 = "{\"bookie_src\": \"" + getBookie(1).toString() + "\"}";
775+
BookieId bookieId = getBookie(1);
776+
String putBody3 = "{\"bookie_src\": \"" + bookieId.toString() + "\"}";
769777
HttpServiceRequest request3 = new HttpServiceRequest(putBody3, HttpServer.Method.PUT, null);
770778
// after bookie kill, request should success
771779
killBookie(1);
772780
HttpServiceResponse response3 = decommissionService.handle(request3);
773781
assertEquals(HttpServer.StatusCode.OK.getValue(), response3.getStatusCode());
782+
// wait decommission finish
783+
Awaitility.await().pollDelay(60, TimeUnit.SECONDS).timeout(70, TimeUnit.SECONDS).untilAsserted(() -> {
784+
runFunctionWithRegistrationManager(baseConf, registrationManager -> {
785+
Versioned<Cookie> cookieFromZk = null;
786+
try {
787+
cookieFromZk = Cookie.readFromRegistrationManager(registrationManager,
788+
bookieId);
789+
} catch (BookieException e) {
790+
} finally {
791+
assertTrue(cookieFromZk != null);
792+
}
793+
return true;
794+
});
795+
});
774796
stopAuditorElector();
775797
}
776798

799+
@Test
800+
public void testDecommissionServiceWithDeleteCookie() throws Exception {
801+
baseConf.setMetadataServiceUri(zkUtil.getMetadataServiceUri());
802+
startReplicationService();
803+
804+
HttpEndpointService decommissionService = bkHttpServiceProvider
805+
.provideHttpEndpointService(HttpServer.ApiType.DECOMMISSION);
806+
BookieId bookieId = getBookie(1);
807+
String putBody1 = "{\"bookie_src\": \"" + bookieId.toString() + "\", \"delete_cookie\": \"true\"}";
808+
HttpServiceRequest request1 = new HttpServiceRequest(putBody1, HttpServer.Method.PUT, null);
809+
// after bookie kill, request should success
810+
killBookie(1);
811+
HttpServiceResponse response1 = decommissionService.handle(request1);
812+
assertEquals(HttpServer.StatusCode.OK.getValue(), response1.getStatusCode());
813+
// wait decommission finish
814+
Awaitility.await().pollInterval(10, TimeUnit.SECONDS).timeout(60, TimeUnit.SECONDS).untilAsserted(() -> {
815+
runFunctionWithRegistrationManager(baseConf, registrationManager -> {
816+
Versioned<Cookie> cookieFromZk = null;
817+
try {
818+
cookieFromZk = Cookie.readFromRegistrationManager(registrationManager,
819+
bookieId);
820+
} catch (Exception e) {
821+
} finally {
822+
assertTrue(cookieFromZk == null);
823+
}
824+
return true;
825+
});
826+
});
827+
stopReplicationService();
828+
}
829+
777830
@Test
778831
public void testTriggerGCService() throws Exception {
779832
baseConf.setMetadataServiceUri(zkUtil.getMetadataServiceUri());

0 commit comments

Comments
 (0)