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 91dcb883340..f6e2c58876e 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 AUTORECOVERY_STATUS = "/api/v1/autorecovery/status"; public static final String RECOVERY_BOOKIE = "/api/v1/autorecovery/bookie"; @@ -82,6 +83,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(AUTORECOVERY_STATUS, handlerFactory 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 82c9c33a234..a9426deb9a3 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 @@ -83,6 +83,7 @@ enum ApiType { GC_DETAILS, BOOKIE_STATE, BOOKIE_IS_READY, + BOOKIE_INFO, // autorecovery AUTORECOVERY_STATUS, 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 aeb4d83b1bb..e9ac4142f9b 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 @@ -41,6 +41,7 @@ import org.apache.bookkeeper.replication.Auditor; import org.apache.bookkeeper.replication.AutoRecoveryMain; import org.apache.bookkeeper.server.http.service.AutoRecoveryStatusService; +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; @@ -224,6 +225,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 AUTORECOVERY_STATUS: 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..62b118662d5 --- /dev/null +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/server/http/service/BookieInfoService.java @@ -0,0 +1,76 @@ +/* + * 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 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 info 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.