Skip to content

Commit 694a9c9

Browse files
author
maxlisongsong
committed
Adds the bookie cookie service for http api
1 parent 96c6dc0 commit 694a9c9

File tree

5 files changed

+169
-0
lines changed

5 files changed

+169
-0
lines changed

bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpRouter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public abstract class HttpRouter<Handler> {
5656
public static final String BOOKIE_INFO = "/api/v1/bookie/info";
5757
public static final String CLUSTER_INFO = "/api/v1/bookie/cluster_info";
5858
public static final String ENTRY_LOCATION_COMPACT = "/api/v1/bookie/entry_location_compact";
59+
public static final String BOOKIE_COOKIE = "/api/v1/bookie/cookie";
5960
// autorecovery
6061
public static final String AUTORECOVERY_STATUS = "/api/v1/autorecovery/status";
6162
public static final String RECOVERY_BOOKIE = "/api/v1/autorecovery/bookie";
@@ -100,6 +101,7 @@ public HttpRouter(AbstractHttpHandlerFactory<Handler> handlerFactory) {
100101
handlerFactory.newHandler(HttpServer.ApiType.RESUME_GC_COMPACTION));
101102
this.endpointHandlers.put(ENTRY_LOCATION_COMPACT,
102103
handlerFactory.newHandler(HttpServer.ApiType.TRIGGER_ENTRY_LOCATION_COMPACT));
104+
this.endpointHandlers.put(BOOKIE_COOKIE, handlerFactory.newHandler(HttpServer.ApiType.BOOKIE_COOKIE));
103105

104106
// autorecovery
105107
this.endpointHandlers.put(AUTORECOVERY_STATUS, handlerFactory

bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpServer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ enum ApiType {
9191
RESUME_GC_COMPACTION,
9292
SUSPEND_GC_COMPACTION,
9393
TRIGGER_ENTRY_LOCATION_COMPACT,
94+
BOOKIE_COOKIE,
9495
// autorecovery
9596
AUTORECOVERY_STATUS,
9697
RECOVERY_BOOKIE,

bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/BKHttpServiceProvider.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.apache.bookkeeper.replication.Auditor;
3939
import org.apache.bookkeeper.replication.AutoRecoveryMain;
4040
import org.apache.bookkeeper.server.http.service.AutoRecoveryStatusService;
41+
import org.apache.bookkeeper.server.http.service.BookieCookieService;
4142
import org.apache.bookkeeper.server.http.service.BookieInfoService;
4243
import org.apache.bookkeeper.server.http.service.BookieIsReadyService;
4344
import org.apache.bookkeeper.server.http.service.BookieSanityService;
@@ -238,6 +239,8 @@ public HttpEndpointService provideHttpEndpointService(ApiType type) {
238239
return new ResumeCompactionService(bookieServer);
239240
case TRIGGER_ENTRY_LOCATION_COMPACT:
240241
return new TriggerLocationCompactService(bookieServer);
242+
case BOOKIE_COOKIE:
243+
return new BookieCookieService(configuration);
241244

242245
// autorecovery
243246
case AUTORECOVERY_STATUS:
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.bookkeeper.server.http.service;
20+
21+
import static java.nio.charset.StandardCharsets.UTF_8;
22+
23+
import java.net.UnknownHostException;
24+
import java.util.Map;
25+
import org.apache.bookkeeper.bookie.BookieException;
26+
import org.apache.bookkeeper.bookie.Cookie;
27+
import org.apache.bookkeeper.conf.ServerConfiguration;
28+
import org.apache.bookkeeper.http.HttpServer;
29+
import org.apache.bookkeeper.http.service.HttpEndpointService;
30+
import org.apache.bookkeeper.http.service.HttpServiceRequest;
31+
import org.apache.bookkeeper.http.service.HttpServiceResponse;
32+
import org.apache.bookkeeper.meta.MetadataDrivers;
33+
import org.apache.bookkeeper.net.BookieId;
34+
import org.apache.bookkeeper.net.BookieSocketAddress;
35+
import org.apache.bookkeeper.versioning.LongVersion;
36+
import org.apache.bookkeeper.versioning.Version;
37+
import org.apache.bookkeeper.versioning.Versioned;
38+
import org.slf4j.Logger;
39+
import org.slf4j.LoggerFactory;
40+
41+
public class BookieCookieService implements HttpEndpointService {
42+
static final Logger LOG = LoggerFactory.getLogger(BookieCookieService.class);
43+
private final ServerConfiguration conf;
44+
45+
public BookieCookieService(ServerConfiguration conf) {
46+
this.conf = conf;
47+
}
48+
49+
@Override
50+
public HttpServiceResponse handle(HttpServiceRequest request) throws Exception {
51+
Map<String, String> params = request.getParams();
52+
if (params == null || !params.containsKey("bookie_id")) {
53+
return new HttpServiceResponse("Not found bookie id. Should provide bookie_id=<ip:port>",
54+
HttpServer.StatusCode.BAD_REQUEST);
55+
}
56+
if (request.getMethod() == HttpServer.Method.PUT && !params.containsKey("cookie")) {
57+
return new HttpServiceResponse("Not found cookie. "
58+
+ "Should provide cookie=<cookie string>", HttpServer.StatusCode.BAD_REQUEST);
59+
}
60+
61+
String bookieIdStr = params.get("bookie_id");
62+
try {
63+
new BookieSocketAddress(bookieIdStr);
64+
} catch (UnknownHostException nhe) {
65+
return new HttpServiceResponse("Illegal bookie id. Should provide bookie_id=<ip:port>",
66+
HttpServer.StatusCode.BAD_REQUEST);
67+
}
68+
69+
BookieId bookieId = BookieId.parse(bookieIdStr);
70+
return MetadataDrivers.runFunctionWithRegistrationManager(conf, registrationManager -> {
71+
try {
72+
switch (request.getMethod()) {
73+
case PUT:
74+
Versioned<byte[]> newCookieWithVersion = new Versioned<>(params.get("cookie").getBytes(UTF_8),
75+
Version.NEW);
76+
registrationManager.writeCookie(bookieId, newCookieWithVersion);
77+
return new HttpServiceResponse("Added cookie: " + bookieId, HttpServer.StatusCode.OK);
78+
case GET:
79+
Versioned<Cookie> cookie = Cookie.readFromRegistrationManager(registrationManager, bookieId);
80+
return new HttpServiceResponse(cookie.getValue().toString(), HttpServer.StatusCode.OK);
81+
case DELETE:
82+
registrationManager.removeCookie(bookieId, new LongVersion(-1));
83+
return new HttpServiceResponse("Deleted cookie: " + bookieId, HttpServer.StatusCode.OK);
84+
default:
85+
return new HttpServiceResponse("Method not allowed. Should be GET or DELETE method",
86+
HttpServer.StatusCode.METHOD_NOT_ALLOWED);
87+
}
88+
} catch (BookieException.CookieNotFoundException e) {
89+
return new HttpServiceResponse("Not found cookie: " + bookieId, HttpServer.StatusCode.NOT_FOUND);
90+
} catch (BookieException.CookieExistException e) {
91+
return new HttpServiceResponse("Cookie exist for bookieId: " + bookieId, HttpServer.StatusCode.OK);
92+
} catch (BookieException e) {
93+
LOG.error("Failed to op bookie cookie: ", e);
94+
return new HttpServiceResponse("Request failed, e:" + e.getMessage(),
95+
HttpServer.StatusCode.INTERNAL_ERROR);
96+
}
97+
});
98+
}
99+
}

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

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
*/
1919
package org.apache.bookkeeper.server.http;
2020

21+
import static java.nio.charset.StandardCharsets.UTF_8;
2122
import static org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithLedgerManagerFactory;
23+
import static org.apache.bookkeeper.meta.MetadataDrivers.runFunctionWithRegistrationManager;
2224
import static org.junit.jupiter.api.Assertions.assertEquals;
2325
import static org.junit.jupiter.api.Assertions.assertFalse;
2426
import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -39,6 +41,7 @@
3941
import java.util.concurrent.Future;
4042
import lombok.Cleanup;
4143
import org.apache.bookkeeper.bookie.BookieResources;
44+
import org.apache.bookkeeper.bookie.Cookie;
4245
import org.apache.bookkeeper.bookie.LedgerStorage;
4346
import org.apache.bookkeeper.client.BookKeeper;
4447
import org.apache.bookkeeper.client.ClientUtil;
@@ -55,6 +58,7 @@
5558
import org.apache.bookkeeper.meta.LedgerManagerFactory;
5659
import org.apache.bookkeeper.meta.LedgerUnderreplicationManager;
5760
import org.apache.bookkeeper.meta.MetadataBookieDriver;
61+
import org.apache.bookkeeper.net.BookieId;
5862
import org.apache.bookkeeper.net.BookieSocketAddress;
5963
import org.apache.bookkeeper.proto.BookieServer;
6064
import org.apache.bookkeeper.replication.AuditorElector;
@@ -66,6 +70,7 @@
6670
import org.apache.bookkeeper.server.http.service.ClusterInfoService;
6771
import org.apache.bookkeeper.stats.NullStatsLogger;
6872
import org.apache.bookkeeper.test.BookKeeperClusterTestCase;
73+
import org.apache.bookkeeper.versioning.Versioned;
6974
import org.junit.jupiter.api.AfterEach;
7075
import org.junit.jupiter.api.BeforeEach;
7176
import org.junit.jupiter.api.Test;
@@ -1217,4 +1222,63 @@ public void testTriggerEntryLocationCompactService() throws Exception {
12171222
HttpServiceResponse response7 = triggerEntryLocationCompactService.handle(request7);
12181223
assertEquals(HttpServer.StatusCode.METHOD_NOT_ALLOWED.getValue(), response7.getStatusCode());
12191224
}
1225+
1226+
@SuppressWarnings("checkstyle:RegexpSingleline")
1227+
@Test
1228+
public void testBookieCookieService() throws Exception {
1229+
runFunctionWithRegistrationManager(baseConf, registrationManager -> {
1230+
try {
1231+
String bookieId = getBookie(0).toString();
1232+
Versioned<Cookie> cookieFromZk = Cookie.readFromRegistrationManager(registrationManager,
1233+
BookieId.parse(bookieId));
1234+
HttpEndpointService bookieCookieService = bkHttpServiceProvider.provideHttpEndpointService(
1235+
HttpServer.ApiType.BOOKIE_COOKIE);
1236+
Map<String, String> params = new HashMap<>();
1237+
// empty params
1238+
HttpServiceRequest request = new HttpServiceRequest(null, HttpServer.Method.GET, params);
1239+
HttpServiceResponse response = bookieCookieService.handle(request);
1240+
assertEquals(response.getStatusCode(), HttpServer.StatusCode.BAD_REQUEST.getValue());
1241+
assertEquals(response.getBody(), "Not found bookie id. Should provide bookie_id=<ip:port>");
1242+
// invalid params
1243+
params.put("bookie_id", "bookie_id");
1244+
response = bookieCookieService.handle(request);
1245+
assertEquals(response.getStatusCode(), HttpServer.StatusCode.BAD_REQUEST.getValue());
1246+
assertEquals(response.getBody(), "Illegal bookie id. Should provide bookie_id=<ip:port>");
1247+
1248+
// cookie not found
1249+
params.put("bookie_id", "127.2.1.0:3181");
1250+
response = bookieCookieService.handle(request);
1251+
assertEquals(response.getStatusCode(), HttpServer.StatusCode.NOT_FOUND.getValue());
1252+
1253+
params.put("bookie_id", bookieId);
1254+
// GET cookie
1255+
HttpServiceRequest request1 = new HttpServiceRequest(null, HttpServer.Method.GET, params);
1256+
HttpServiceResponse response1 = bookieCookieService.handle(request1);
1257+
assertEquals(response1.getStatusCode(), HttpServer.StatusCode.OK.getValue());
1258+
assertEquals(cookieFromZk.getValue().toString(), response1.getBody());
1259+
Cookie old = Cookie.parseFromBytes(response1.getBody().getBytes(UTF_8));
1260+
// DELETE cookie
1261+
HttpServiceRequest request2 = new HttpServiceRequest(null, HttpServer.Method.DELETE, params);
1262+
HttpServiceResponse response2 = bookieCookieService.handle(request2);
1263+
assertEquals(response2.getStatusCode(), HttpServer.StatusCode.OK.getValue());
1264+
1265+
// GET cookie
1266+
HttpServiceResponse response3 = bookieCookieService.handle(request1);
1267+
assertEquals(response3.getStatusCode(), HttpServer.StatusCode.NOT_FOUND.getValue());
1268+
1269+
// create cookie
1270+
params.put("cookie", old.toString());
1271+
HttpServiceRequest request3 = new HttpServiceRequest(null, HttpServer.Method.PUT, params);
1272+
HttpServiceResponse response4 = bookieCookieService.handle(request3);
1273+
assertEquals(response4.getStatusCode(), HttpServer.StatusCode.OK.getValue());
1274+
1275+
HttpServiceResponse response5 = bookieCookieService.handle(request1);
1276+
assertEquals(response5.getStatusCode(), HttpServer.StatusCode.OK.getValue());
1277+
assertEquals(cookieFromZk.getValue().toString(), response5.getBody());
1278+
return true;
1279+
} catch (Exception e) {
1280+
throw new RuntimeException(e);
1281+
}
1282+
});
1283+
}
12201284
}

0 commit comments

Comments
 (0)