From 104ece9bba207dbe24762de63ad20f3672f22a71 Mon Sep 17 00:00:00 2001 From: Fretiq <60456830+fretiq@users.noreply.github.com> Date: Wed, 29 Apr 2020 02:53:37 -0500 Subject: [PATCH 1/2] Add /api/v1/bookie/info REST API --- .../apache/bookkeeper/http/HttpRouter.java | 2 + .../apache/bookkeeper/http/HttpServer.java | 1 + .../server/http/BKHttpServiceProvider.java | 3 + .../http/service/BookieInfoService.java | 67 +++++++++++++++++++ .../server/http/TestHttpService.java | 21 ++++++ site/docs/latest/admin/http.md | 18 +++++ 6 files changed, 112 insertions(+) create mode 100644 bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieInfoService.java diff --git a/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpRouter.java b/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpRouter.java index 99d5be685f6..87e27033772 100644 --- a/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpRouter.java +++ b/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpRouter.java @@ -49,6 +49,7 @@ public abstract class HttpRouter { public static final String GC_DETAILS = "/api/v1/bookie/gc_details"; public static final String BOOKIE_STATE = "/api/v1/bookie/state"; public static final String BOOKIE_IS_READY = "/api/v1/bookie/is_ready"; + public static final String BOOKIE_INFO = "/api/v1/bookie/info"; // autorecovery public static final String RECOVERY_BOOKIE = "/api/v1/autorecovery/bookie"; public static final String LIST_UNDER_REPLICATED_LEDGER = "/api/v1/autorecovery/list_under_replicated_ledger"; @@ -81,6 +82,7 @@ public HttpRouter(AbstractHttpHandlerFactory handlerFactory) { this.endpointHandlers.put(GC_DETAILS, handlerFactory.newHandler(HttpServer.ApiType.GC_DETAILS)); this.endpointHandlers.put(BOOKIE_STATE, handlerFactory.newHandler(HttpServer.ApiType.BOOKIE_STATE)); this.endpointHandlers.put(BOOKIE_IS_READY, handlerFactory.newHandler(HttpServer.ApiType.BOOKIE_IS_READY)); + this.endpointHandlers.put(BOOKIE_INFO, handlerFactory.newHandler(HttpServer.ApiType.BOOKIE_INFO)); // autorecovery this.endpointHandlers.put(RECOVERY_BOOKIE, handlerFactory.newHandler(HttpServer.ApiType.RECOVERY_BOOKIE)); diff --git a/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpServer.java b/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpServer.java index c694a076721..4c5c3dbc4e6 100644 --- a/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpServer.java +++ b/bookkeeper-http/http-server/src/main/java/org/apache/bookkeeper/http/HttpServer.java @@ -82,6 +82,7 @@ enum ApiType { GC_DETAILS, BOOKIE_STATE, BOOKIE_IS_READY, + BOOKIE_INFO, // autorecovery RECOVERY_BOOKIE, diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/BKHttpServiceProvider.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/BKHttpServiceProvider.java index 24795e54e83..689d0f182ff 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/BKHttpServiceProvider.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/BKHttpServiceProvider.java @@ -40,6 +40,7 @@ import org.apache.bookkeeper.proto.BookieServer; import org.apache.bookkeeper.replication.Auditor; import org.apache.bookkeeper.replication.AutoRecoveryMain; +import org.apache.bookkeeper.server.http.service.BookieInfoService; import org.apache.bookkeeper.server.http.service.BookieIsReadyService; import org.apache.bookkeeper.server.http.service.BookieStateService; import org.apache.bookkeeper.server.http.service.ConfigurationService; @@ -223,6 +224,8 @@ public HttpEndpointService provideHttpEndpointService(ApiType type) { return new BookieStateService(bookieServer.getBookie()); case BOOKIE_IS_READY: return new BookieIsReadyService(bookieServer.getBookie()); + case BOOKIE_INFO: + return new BookieInfoService(bookieServer.getBookie()); // autorecovery case RECOVERY_BOOKIE: diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieInfoService.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieInfoService.java new file mode 100644 index 00000000000..5e2dbc40da1 --- /dev/null +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieInfoService.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bookkeeper.server.http.service; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.apache.bookkeeper.bookie.Bookie; +import org.apache.bookkeeper.common.util.JsonUtil; +import org.apache.bookkeeper.http.HttpServer; +import org.apache.bookkeeper.http.service.HttpEndpointService; +import org.apache.bookkeeper.http.service.HttpServiceRequest; +import org.apache.bookkeeper.http.service.HttpServiceResponse; + +/** + * HttpEndpointService that returns 200 if the bookie is ready. + */ +@AllArgsConstructor +public class BookieInfoService implements HttpEndpointService { + @NonNull private final Bookie bookie; + + /** + * POJO definition for the bookie state response. + */ + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class BookieInfo { + private long freeSpace; + private long totalSpace; + } + + @Override + public HttpServiceResponse handle(HttpServiceRequest request) throws Exception { + HttpServiceResponse response = new HttpServiceResponse(); + + if (HttpServer.Method.GET != request.getMethod()) { + response.setCode(HttpServer.StatusCode.NOT_FOUND); + response.setBody("Only GET is supported."); + return response; + } + + BookieInfo bi = new BookieInfo(bookie.getTotalFreeSpace(), bookie.getTotalDiskSpace()); + + String jsonResponse = JsonUtil.toJson(bi); + response.setBody(jsonResponse); + response.setCode(HttpServer.StatusCode.OK); + return response; + } +} 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 02aa42b864b..cf839627578 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 @@ -51,6 +51,7 @@ import org.apache.bookkeeper.meta.LedgerUnderreplicationManager; import org.apache.bookkeeper.net.BookieSocketAddress; import org.apache.bookkeeper.replication.AuditorElector; +import org.apache.bookkeeper.server.http.service.BookieInfoService; import org.apache.bookkeeper.server.http.service.BookieStateService.BookieState; import org.apache.bookkeeper.test.BookKeeperClusterTestCase; import org.junit.Before; @@ -866,4 +867,24 @@ public void testGetBookieIsReady() throws Exception { HttpServiceResponse response3 = bookieStateServer.handle(request3); assertEquals(HttpServer.StatusCode.SERVICE_UNAVAILABLE.getValue(), response3.getStatusCode()); } + + @Test + public void testGetBookieInfo() throws Exception { + HttpEndpointService bookieStateServer = bkHttpServiceProvider + .provideHttpEndpointService(HttpServer.ApiType.BOOKIE_INFO); + + HttpServiceRequest request1 = new HttpServiceRequest(null, HttpServer.Method.GET, null); + HttpServiceResponse response1 = bookieStateServer.handle(request1); + assertEquals(HttpServer.StatusCode.OK.getValue(), response1.getStatusCode()); + LOG.info("Get response: {}", response1.getBody()); + + BookieInfoService.BookieInfo bs = JsonUtil.fromJson(response1.getBody(), BookieInfoService.BookieInfo.class); + assertTrue(bs.getFreeSpace() > 0); + assertTrue(bs.getTotalSpace() > 0); + + // Try using POST instead of GET + HttpServiceRequest request2 = new HttpServiceRequest(null, HttpServer.Method.POST, null); + HttpServiceResponse response2 = bookieStateServer.handle(request2); + assertEquals(HttpServer.StatusCode.NOT_FOUND.getValue(), response2.getStatusCode()); + } } diff --git a/site/docs/latest/admin/http.md b/site/docs/latest/admin/http.md index 46dd080f106..50c3a7db01d 100644 --- a/site/docs/latest/admin/http.md +++ b/site/docs/latest/admin/http.md @@ -168,6 +168,24 @@ Currently all the HTTP endpoints could be divided into these 5 components: ## Bookie +### Endpoint: /api/v1/bookie/info +1. Method: GET + * Description: Get bookie info + * Response: + + | Code | Description | + |:-------|:------------| + |200 | Successful operation | + |403 | Permission denied | + |501 | Not implemented | + * Body: + ```json + { + "freeSpace" : 0, + "totalSpace" : 0 + } + ``` + ### Endpoint: /api/v1/bookie/list_bookies/?type=<type>&print_hostnames=<hostnames> 1. Method: GET * Description: Get all the available bookies. From f5914f26322d9d6bd6186df965fb3ff350910dc6 Mon Sep 17 00:00:00 2001 From: Fretiq <60456830+fretiq@users.noreply.github.com> Date: Wed, 29 Apr 2020 02:56:35 -0500 Subject: [PATCH 2/2] Improve comments --- .../server/http/service/BookieInfoService.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieInfoService.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieInfoService.java index 5e2dbc40da1..62b118662d5 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieInfoService.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieInfoService.java @@ -30,14 +30,23 @@ import org.apache.bookkeeper.http.service.HttpServiceResponse; /** - * HttpEndpointService that returns 200 if the bookie is ready. + * HttpEndpointService that exposes the current info of the bookie. + * + *
+ * 
+ * {
+ *  "freeSpace" : 0,
+ *  "totalSpace" : 0
+ * }
+ * 
+ * 
*/ @AllArgsConstructor public class BookieInfoService implements HttpEndpointService { @NonNull private final Bookie bookie; /** - * POJO definition for the bookie state response. + * POJO definition for the bookie info response. */ @Data @NoArgsConstructor