You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by pe...@apache.org on 2022/06/12 11:28:41 UTC

[pulsar] branch branch-2.10 updated: [fix] [admin] fix reach max tenants error if the tenant already exists (#15961)

This is an automated email from the ASF dual-hosted git repository.

penghui pushed a commit to branch branch-2.10
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/branch-2.10 by this push:
     new a1d327e5378 [fix] [admin] fix reach max tenants error if the tenant already exists (#15961)
a1d327e5378 is described below

commit a1d327e5378c66766b4dd583257cdbea165a995f
Author: fengyubiao <yu...@streamnative.io>
AuthorDate: Sun Jun 12 19:28:34 2022 +0800

    [fix] [admin] fix reach max tenants error if the tenant already exists (#15961)
---
 .../pulsar/broker/admin/impl/TenantsBase.java      | 33 +++++++++++-----------
 .../org/apache/pulsar/broker/admin/AdminTest.java  | 33 ++++++++++++++++++++++
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/TenantsBase.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/TenantsBase.java
index 4f1bad29736..5bd9dc8bd0f 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/TenantsBase.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/impl/TenantsBase.java
@@ -136,27 +136,26 @@ public class TenantsBase extends PulsarWebResource {
             return;
         }
 
-        tenantResources().listTenantsAsync().whenComplete((tenants, e) -> {
-            if (e != null) {
-                log.error("[{}] Failed to create tenant ", clientAppId, e.getCause());
-                asyncResponse.resume(new RestException(e));
+        tenantResources().tenantExistsAsync(tenant).thenAccept(exist -> {
+            if (exist) {
+                asyncResponse.resume(new RestException(Status.CONFLICT, "Tenant already exist"));
                 return;
             }
-
-            int maxTenants = pulsar().getConfiguration().getMaxTenants();
-            // Due to the cost of distributed locks, no locks are added here.
-            // In a concurrent scenario, the threshold will be exceeded.
-            if (maxTenants > 0) {
-                if (tenants != null && tenants.size() >= maxTenants) {
-                    asyncResponse.resume(
-                            new RestException(Status.PRECONDITION_FAILED, "Exceed the maximum number of tenants"));
+            tenantResources().listTenantsAsync().whenComplete((tenants, e) -> {
+                if (e != null) {
+                    log.error("[{}] Failed to create tenant ", clientAppId, e.getCause());
+                    asyncResponse.resume(new RestException(e));
                     return;
                 }
-            }
-            tenantResources().tenantExistsAsync(tenant).thenAccept(exist -> {
-                if (exist) {
-                    asyncResponse.resume(new RestException(Status.CONFLICT, "Tenant already exist"));
-                    return;
+                int maxTenants = pulsar().getConfiguration().getMaxTenants();
+                // Due to the cost of distributed locks, no locks are added here.
+                // In a concurrent scenario, the threshold will be exceeded.
+                if (maxTenants > 0) {
+                    if (tenants != null && tenants.size() >= maxTenants) {
+                        asyncResponse.resume(
+                                new RestException(Status.PRECONDITION_FAILED, "Exceed the maximum number of tenants"));
+                        return;
+                    }
                 }
                 tenantResources().createTenantAsync(tenant, tenantInfo).thenAccept((r) -> {
                     log.info("[{}] Created tenant {}", clientAppId(), tenant);
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminTest.java
index f506feedd33..0a8eceddf10 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/admin/AdminTest.java
@@ -118,6 +118,12 @@ public class AdminTest extends MockedPulsarServiceBaseTest {
         super();
     }
 
+    @Override
+    protected void doInitConf() throws Exception {
+        super.doInitConf();
+        conf.setMaxTenants(10);
+    }
+
     @Override
     @BeforeMethod
     public void setup() throws Exception {
@@ -622,6 +628,33 @@ public class AdminTest extends MockedPulsarServiceBaseTest {
             assertEquals(e.getResponse().getStatus(), Status.PRECONDITION_FAILED.getStatusCode());
         }
 
+        // Check max tenant count
+        int maxTenants = pulsar.getConfiguration().getMaxTenants();
+        List<String> tenants = pulsar.getPulsarResources().getTenantResources().listTenants();
+
+        for(int tenantSize = tenants.size();tenantSize < maxTenants; tenantSize++ ){
+            final int tenantIndex = tenantSize;
+            Response obj = (Response)asynRequests(ctx ->
+                    properties.createTenant(ctx, "test-tenant-" + tenantIndex, tenantInfo));
+            Assert.assertTrue(obj.getStatus() < 400 && obj.getStatus() >= 200);
+        }
+        try {
+            response = asynRequests(ctx ->
+                    properties.createTenant(ctx, "test-tenant-" +  maxTenants, tenantInfo));
+            fail("should have failed");
+        } catch (RestException e) {
+            assertEquals(e.getResponse().getStatus(), Status.PRECONDITION_FAILED.getStatusCode());
+        }
+
+        // Check creating existing property when tenant reach max count.
+        try {
+            response = asynRequests(ctx ->
+                    properties.createTenant(ctx, "test-tenant-" +  (maxTenants-1), tenantInfo));
+            fail("should have failed");
+        } catch (RestException e) {
+            assertEquals(e.getResponse().getStatus(), Status.CONFLICT.getStatusCode());
+        }
+
         AsyncResponse response2 = mock(AsyncResponse.class);
         namespaces.deleteNamespace(response2, "my-tenant", "use", "my-namespace", false, false);
         ArgumentCaptor<Response> captor = ArgumentCaptor.forClass(Response.class);