This is an automated email from the ASF dual-hosted git repository.
penghui pushed a commit to branch branch-2.7
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/branch-2.7 by this push:
new 801c286665e Validate rack name (#16850)
801c286665e is described below
commit 801c286665efa6fac80829f20a0c8423b85c1a52
Author: JiangHaiting <[email protected]>
AuthorDate: Wed Aug 3 09:28:38 2022 +0800
Validate rack name (#16850)
---
.../org/apache/pulsar/broker/admin/v2/Bookies.java | 18 +++++++--
.../apache/pulsar/broker/admin/BookiesApiTest.java | 46 +++++++++++++++++++++-
2 files changed, 60 insertions(+), 4 deletions(-)
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Bookies.java
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Bookies.java
index 164cb0175c0..4f626599c5f 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Bookies.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v2/Bookies.java
@@ -22,10 +22,8 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
-
import java.util.Map.Entry;
import java.util.Optional;
-
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
@@ -35,7 +33,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;
-
+import org.apache.commons.lang3.StringUtils;
import org.apache.pulsar.broker.admin.AdminResource;
import org.apache.pulsar.broker.web.RestException;
import org.apache.pulsar.common.policies.data.BookieInfo;
@@ -51,6 +49,7 @@ import org.slf4j.LoggerFactory;
@Api(value = "/bookies", description = "Configure bookies rack placement",
tags = "bookies")
@Produces(MediaType.APPLICATION_JSON)
public class Bookies extends AdminResource {
+ private static final String PATH_SEPARATOR = "/";
@GET
@Path("/racks-info")
@@ -126,6 +125,19 @@ public class Bookies extends AdminResource {
throw new RestException(Status.PRECONDITION_FAILED, "Bookie
'group' parameters is missing");
}
+ // validate rack name
+ int separatorCnt = StringUtils.countMatches(
+ StringUtils.strip(bookieInfo.getRack(), PATH_SEPARATOR),
PATH_SEPARATOR);
+ boolean isRackEnabled =
pulsar().getConfiguration().isBookkeeperClientRackawarePolicyEnabled();
+ boolean isRegionEnabled =
pulsar().getConfiguration().isBookkeeperClientRegionawarePolicyEnabled();
+ if (isRackEnabled && ((isRegionEnabled && separatorCnt != 1) ||
(!isRegionEnabled && separatorCnt != 0))) {
+ throw new RestException(Status.PRECONDITION_FAILED, "Bookie 'rack'
parameter is invalid, "
+ + "When `RackawareEnsemblePlacementPolicy` is enabled, the
rack name is not allowed to contain "
+ + "slash (`/`) except for the beginning and end of the
rack name string. "
+ + "When `RegionawareEnsemblePlacementPolicy` is enabled,
the rack name can only contain "
+ + "one slash (`/`) except for the beginning and end of the
rack name string.");
+ }
+
Optional<Entry<BookiesRackConfiguration, Stat>> entry = localZkCache()
.getEntry(ZkBookieRackAffinityMapping.BOOKIE_INFO_ROOT_PATH,
(key, content) -> ObjectMapperFactory
.getThreadLocal().readValue(content,
BookiesRackConfiguration.class));
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/BookiesApiTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/BookiesApiTest.java
index 3160b328130..4684431edc1 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/BookiesApiTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/BookiesApiTest.java
@@ -18,12 +18,13 @@
*/
package org.apache.pulsar.broker.admin;
+import static org.mockito.Mockito.doReturn;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
-
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
+import org.apache.pulsar.broker.ServiceConfiguration;
import org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest;
import org.apache.pulsar.client.admin.PulsarAdminException;
import org.apache.pulsar.common.policies.data.BookieInfo;
@@ -109,6 +110,49 @@ public class BookiesApiTest extends
MockedPulsarServiceBaseTest {
conf = admin.bookies().getBookiesRackInfo();
assertTrue(conf.isEmpty());
+
+ // test invalid rack name
+ // use rack aware placement policy
+ String errorMsg = "Bookie 'rack' parameter is invalid, When
`RackawareEnsemblePlacementPolicy` is enabled, "
+ + "the rack name is not allowed to contain slash (`/`) except
for the beginning and end of the rack name "
+ + "string. When `RegionawareEnsemblePlacementPolicy` is
enabled, the rack name can only contain "
+ + "one slash (`/`) except for the beginning and end of the
rack name string.";
+
+ BookieInfo newInfo3 = new BookieInfo("/rack/a","127.0.0.2");
+ try {
+ admin.bookies().updateBookieRackInfo(bookie0, "default", newInfo3);
+ fail();
+ } catch (PulsarAdminException e) {
+ assertEquals(412, e.getStatusCode());
+ assertEquals(errorMsg, e.getMessage());
+ }
+
+ BookieInfo newInfo4 = new BookieInfo("/rack","127.0.0.2");
+ try {
+ admin.bookies().updateBookieRackInfo(bookie0, "default", newInfo4);
+ } catch (PulsarAdminException e) {
+ fail();
+ }
+
+ // enable region aware placement policy
+ ServiceConfiguration configuration = new ServiceConfiguration();
+ configuration.setBookkeeperClientRegionawarePolicyEnabled(true);
+ doReturn(configuration).when(pulsar).getConfiguration();
+ BookieInfo newInfo5 = new BookieInfo("/region/rack/a", "127.0.0.2");
+ try {
+ admin.bookies().updateBookieRackInfo(bookie0, "default", newInfo5);
+ fail();
+ } catch (PulsarAdminException e) {
+ assertEquals(412, e.getStatusCode());
+ assertEquals(errorMsg, e.getMessage());
+ }
+
+ BookieInfo newInfo6 = new BookieInfo("/region/rack/", "127.0.0.2");
+ try {
+ admin.bookies().updateBookieRackInfo(bookie0, "default", newInfo6);
+ } catch (PulsarAdminException e) {
+ fail();
+ }
}
}