|
103 | 103 | import org.apache.pulsar.common.util.Codec;
|
104 | 104 | import org.apache.pulsar.common.util.FutureUtil;
|
105 | 105 | import org.apache.pulsar.metadata.api.MetadataStoreException;
|
106 |
| -import org.apache.pulsar.metadata.api.MetadataStoreException.AlreadyExistsException; |
107 | 106 | import org.apache.pulsar.metadata.api.MetadataStoreException.BadVersionException;
|
108 | 107 | import org.apache.pulsar.metadata.api.MetadataStoreException.NotFoundException;
|
109 | 108 | import org.slf4j.Logger;
|
110 | 109 | import org.slf4j.LoggerFactory;
|
111 | 110 |
|
112 | 111 | public abstract class NamespacesBase extends AdminResource {
|
113 | 112 |
|
114 |
| - protected List<String> internalGetTenantNamespaces(String tenant) { |
115 |
| - checkNotNull(tenant, "Tenant should not be null"); |
| 113 | + protected CompletableFuture<List<String>> internalGetTenantNamespaces(String tenant) { |
| 114 | + if (tenant == null) { |
| 115 | + return FutureUtil.failedFuture(new RestException(Status.BAD_REQUEST, "Tenant should not be null")); |
| 116 | + } |
116 | 117 | try {
|
117 | 118 | NamedEntity.checkName(tenant);
|
118 | 119 | } catch (IllegalArgumentException e) {
|
119 | 120 | log.warn("[{}] Tenant name is invalid {}", clientAppId(), tenant, e);
|
120 |
| - throw new RestException(Status.PRECONDITION_FAILED, "Tenant name is not valid"); |
121 |
| - } |
122 |
| - validateTenantOperation(tenant, TenantOperation.LIST_NAMESPACES); |
123 |
| - |
124 |
| - try { |
125 |
| - if (!tenantResources().tenantExists(tenant)) { |
126 |
| - throw new RestException(Status.NOT_FOUND, "Tenant not found"); |
127 |
| - } |
128 |
| - |
129 |
| - return tenantResources().getListOfNamespaces(tenant); |
130 |
| - } catch (Exception e) { |
131 |
| - log.error("[{}] Failed to get namespaces list: {}", clientAppId(), e); |
132 |
| - throw new RestException(e); |
| 121 | + return FutureUtil.failedFuture(new RestException(Status.PRECONDITION_FAILED, "Tenant name is not valid")); |
133 | 122 | }
|
| 123 | + return validateTenantOperationAsync(tenant, TenantOperation.LIST_NAMESPACES) |
| 124 | + .thenCompose(__ -> tenantResources().tenantExistsAsync(tenant)) |
| 125 | + .thenCompose(existed -> { |
| 126 | + if (!existed) { |
| 127 | + throw new RestException(Status.NOT_FOUND, "Tenant not found"); |
| 128 | + } |
| 129 | + return tenantResources().getListOfNamespacesAsync(tenant); |
| 130 | + }); |
134 | 131 | }
|
135 | 132 |
|
136 |
| - protected void internalCreateNamespace(Policies policies) { |
137 |
| - validateTenantOperation(namespaceName.getTenant(), TenantOperation.CREATE_NAMESPACE); |
138 |
| - validatePoliciesReadOnlyAccess(); |
139 |
| - validatePolicies(namespaceName, policies); |
140 |
| - |
141 |
| - try { |
142 |
| - int maxNamespacesPerTenant = pulsar().getConfiguration().getMaxNamespacesPerTenant(); |
143 |
| - // no distributed locks are added here.In a concurrent scenario, the threshold will be exceeded. |
144 |
| - if (maxNamespacesPerTenant > 0) { |
145 |
| - List<String> namespaces = tenantResources().getListOfNamespaces(namespaceName.getTenant()); |
146 |
| - if (namespaces != null && namespaces.size() > maxNamespacesPerTenant) { |
147 |
| - throw new RestException(Status.PRECONDITION_FAILED, |
148 |
| - "Exceed the maximum number of namespace in tenant :" + namespaceName.getTenant()); |
149 |
| - } |
150 |
| - } |
151 |
| - namespaceResources().createPolicies(namespaceName, policies); |
152 |
| - log.info("[{}] Created namespace {}", clientAppId(), namespaceName); |
153 |
| - } catch (AlreadyExistsException e) { |
154 |
| - log.warn("[{}] Failed to create namespace {} - already exists", clientAppId(), namespaceName); |
155 |
| - throw new RestException(Status.CONFLICT, "Namespace already exists"); |
156 |
| - } catch (Exception e) { |
157 |
| - log.error("[{}] Failed to create namespace {}", clientAppId(), namespaceName, e); |
158 |
| - throw new RestException(e); |
159 |
| - } |
| 133 | + protected CompletableFuture<Void> internalCreateNamespace(Policies policies) { |
| 134 | + return validateTenantOperationAsync(namespaceName.getTenant(), TenantOperation.CREATE_NAMESPACE) |
| 135 | + .thenCompose(__ -> validatePoliciesReadOnlyAccessAsync()) |
| 136 | + .thenAccept(__ -> validatePolicies(namespaceName, policies)) |
| 137 | + .thenCompose(__ -> { |
| 138 | + CompletableFuture<Void> ret = CompletableFuture.completedFuture(null); |
| 139 | + int maxNamespacesPerTenant = pulsar().getConfiguration().getMaxNamespacesPerTenant(); |
| 140 | + // no distributed locks are added here.In a concurrent scenario, the threshold will be exceeded. |
| 141 | + if (maxNamespacesPerTenant > 0) { |
| 142 | + ret = tenantResources().getListOfNamespacesAsync(namespaceName.getTenant()) |
| 143 | + .thenAccept(namespaces -> { |
| 144 | + if (namespaces != null && namespaces.size() > maxNamespacesPerTenant) { |
| 145 | + throw new RestException(Status.PRECONDITION_FAILED, |
| 146 | + "Exceed the maximum number of namespace in tenant :" |
| 147 | + + namespaceName.getTenant()); |
| 148 | + } |
| 149 | + }); |
| 150 | + } |
| 151 | + return ret; |
| 152 | + }) |
| 153 | + .thenCompose(__ -> namespaceResources().createPoliciesAsync(namespaceName, policies)) |
| 154 | + .thenAccept(__ -> log.info("[{}] Created namespace {}", clientAppId(), namespaceName)); |
160 | 155 | }
|
161 | 156 |
|
162 | 157 | protected void internalDeleteNamespace(AsyncResponse asyncResponse, boolean authoritative, boolean force) {
|
|
0 commit comments