This is an automated email from the ASF dual-hosted git repository.
penghui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/master by this push:
new 9c821cf Support limits the max namespaces per tenant (#8267)
9c821cf is described below
commit 9c821cf940d422d2ea3d47687bd309fe698ab84e
Author: feynmanlin <[email protected]>
AuthorDate: Sat Oct 17 09:50:14 2020 +0800
Support limits the max namespaces per tenant (#8267)
Fixes #8224
### Motivation
Support limits the max namespaces per tenant of the Pulsar cluster. When
the namespaces reach the max namespaces of the tenant, the broker should reject
the new namespace request.
### Modifications
Add maxNamespacePerTenant=0 in the broker.conf and don't limit by default.
### Verifying this change
AdminApiTest2#testMaxNamespacePerTenant
---
conf/broker.conf | 4 +++
deployment/terraform-ansible/templates/broker.conf | 4 +++
.../apache/pulsar/broker/ServiceConfiguration.java | 7 ++++++
.../pulsar/broker/admin/impl/NamespacesBase.java | 10 +++++++-
.../apache/pulsar/broker/admin/AdminApiTest2.java | 29 ++++++++++++++++++++++
5 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/conf/broker.conf b/conf/broker.conf
index bf5eb72..bec34fd 100644
--- a/conf/broker.conf
+++ b/conf/broker.conf
@@ -205,6 +205,10 @@ brokerDeduplicationProducerInactivityTimeoutMinutes=360
# value will be used as the default
defaultNumberOfNamespaceBundles=4
+# The maximum number of namespaces that each tenant can create
+# This configuration is not precise control, in a concurrent scenario, the
threshold will be exceeded
+maxNamespacesPerTenant=0
+
# Enable check for minimum allowed client library version
clientLibraryVersionCheckEnabled=false
diff --git a/deployment/terraform-ansible/templates/broker.conf
b/deployment/terraform-ansible/templates/broker.conf
index d5dc441..7568fe0 100644
--- a/deployment/terraform-ansible/templates/broker.conf
+++ b/deployment/terraform-ansible/templates/broker.conf
@@ -190,6 +190,10 @@ brokerDeduplicationProducerInactivityTimeoutMinutes=360
# value will be used as the default
defaultNumberOfNamespaceBundles=4
+# The maximum number of namespaces that each tenant can create
+# This configuration is not precise control, in a concurrent scenario, the
threshold will be exceeded
+maxNamespacesPerTenant=0
+
# Enable check for minimum allowed client library version
clientLibraryVersionCheckEnabled=false
diff --git
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
index 8b13ca5..3623785 100644
---
a/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
+++
b/pulsar-broker-common/src/main/java/org/apache/pulsar/broker/ServiceConfiguration.java
@@ -430,6 +430,13 @@ public class ServiceConfiguration implements
PulsarConfiguration {
doc = "When a namespace is created without specifying the number of
bundle, this"
+ " value will be used as the default")
private int defaultNumberOfNamespaceBundles = 4;
+
+ @FieldContext(
+ category = CATEGORY_POLICIES,
+ dynamic = true,
+ doc = "The maximum number of namespaces that each tenant can create."
+ + "This configuration is not precise control, in a concurrent
scenario, the threshold will be exceeded")
+ private int maxNamespacesPerTenant = 0;
@FieldContext(
category = CATEGORY_SERVER,
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java
index fe63c96..5d2f994 100644
---
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java
+++
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/NamespacesBase.java
@@ -49,7 +49,6 @@ import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.pulsar.broker.PulsarServerException;
-import org.apache.pulsar.broker.ServiceConfiguration;
import org.apache.pulsar.broker.admin.AdminResource;
import org.apache.pulsar.broker.authorization.AuthorizationService;
import
org.apache.pulsar.broker.service.BrokerServiceException.SubscriptionBusyException;
@@ -133,6 +132,15 @@ public abstract class NamespacesBase extends AdminResource
{
validatePolicies(namespaceName, policies);
try {
+ int maxNamespacesPerTenant =
pulsar().getConfiguration().getMaxNamespacesPerTenant();
+ //no distributed locks are added here.In a concurrent scenario,
the threshold will be exceeded.
+ if (maxNamespacesPerTenant > 0) {
+ List<String> namespaces =
getListOfNamespaces(namespaceName.getTenant());
+ if (namespaces != null && namespaces.size() >
maxNamespacesPerTenant) {
+ throw new RestException(Status.PRECONDITION_FAILED,
+ "Exceed the maximum number of namespace in tenant
:" + namespaceName.getTenant());
+ }
+ }
policiesCache().invalidate(path(POLICIES,
namespaceName.toString()));
zkCreateOptimistic(path(POLICIES, namespaceName.toString()),
jsonMapper().writeValueAsBytes(policies));
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiTest2.java
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiTest2.java
index 77edc9f..8974cd6 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiTest2.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminApiTest2.java
@@ -1294,4 +1294,33 @@ public class AdminApiTest2 extends
MockedPulsarServiceBaseTest {
admin.clusters().updateCluster(clusterName, cluster);
Assert.assertEquals(admin.clusters().getCluster(clusterName), cluster);
}
+
+ @Test
+ public void testMaxNamespacesPerTenant() throws Exception {
+ super.internalCleanup();
+ conf.setMaxNamespacesPerTenant(2);
+ super.internalSetup();
+ admin.clusters().createCluster("test", new
ClusterData(brokerUrl.toString()));
+ TenantInfo tenantInfo = new TenantInfo(Sets.newHashSet("role1",
"role2"), Sets.newHashSet("test"));
+ admin.tenants().createTenant("testTenant", tenantInfo);
+ admin.namespaces().createNamespace("testTenant/ns1",
Sets.newHashSet("test"));
+ admin.namespaces().createNamespace("testTenant/ns2",
Sets.newHashSet("test"));
+ try {
+ admin.namespaces().createNamespace("testTenant/ns3",
Sets.newHashSet("test"));
+ } catch (PulsarAdminException e) {
+ Assert.assertEquals(e.getStatusCode(), 412);
+ Assert.assertEquals(e.getHttpError(), "Exceed the maximum number
of namespace in tenant :testTenant");
+ }
+
+ //unlimited
+ super.internalCleanup();
+ conf.setMaxNamespacesPerTenant(0);
+ super.internalSetup();
+ admin.clusters().createCluster("test", new
ClusterData(brokerUrl.toString()));
+ admin.tenants().createTenant("testTenant", tenantInfo);
+ for (int i = 0; i < 10; i++) {
+ admin.namespaces().createNamespace("testTenant/ns-" + i,
Sets.newHashSet("test"));
+ }
+
+ }
}