You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by GitBox <gi...@apache.org> on 2018/04/19 03:52:03 UTC

[GitHub] nkurihar closed pull request #1380: Refactor REST API for namespace policy

nkurihar closed pull request #1380: Refactor REST API for namespace policy
URL: https://github.com/apache/incubator-pulsar/pull/1380
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

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 c71127996..e982696f2 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
@@ -39,6 +39,8 @@
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriBuilder;
 
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.pulsar.broker.PulsarServerException;
 import org.apache.pulsar.broker.ServiceConfiguration;
@@ -1341,28 +1343,85 @@ protected void internalSetMaxConsumersPerSubscription(int maxConsumersPerSubscri
             byte[] content = globalZk().getData(path, null, nodeStat);
             Policies policies = jsonMapper().readValue(content, Policies.class);
             if (maxConsumersPerSubscription < 0) {
-                throw new RestException(Status.PRECONDITION_FAILED,
-                        "maxConsumersPerSubscription must be 0 or more");
+                throw new RestException(Status.PRECONDITION_FAILED, "maxConsumersPerSubscription must be 0 or more");
             }
             policies.max_consumers_per_subscription = maxConsumersPerSubscription;
             globalZk().setData(path, jsonMapper().writeValueAsBytes(policies), nodeStat.getVersion());
             policiesCache().invalidate(path(POLICIES, namespaceName.toString()));
-            log.info("[{}] Successfully updated maxConsumersPerSubscription configuration: namespace={}, value={}", clientAppId(),
-                    namespaceName, policies.max_consumers_per_subscription);
+            log.info("[{}] Successfully updated maxConsumersPerSubscription configuration: namespace={}, value={}",
+                    clientAppId(), namespaceName, policies.max_consumers_per_subscription);
 
         } catch (KeeperException.NoNodeException e) {
-            log.warn("[{}] Failed to update maxConsumersPerSubscription configuration for namespace {}: does not exist", clientAppId(),
-                    namespaceName);
+            log.warn("[{}] Failed to update maxConsumersPerSubscription configuration for namespace {}: does not exist",
+                    clientAppId(), namespaceName);
             throw new RestException(Status.NOT_FOUND, "Namespace does not exist");
         } catch (KeeperException.BadVersionException e) {
-            log.warn("[{}] Failed to update maxConsumersPerSubscription configuration for namespace {}: concurrent modification",
+            log.warn(
+                    "[{}] Failed to update maxConsumersPerSubscription configuration for namespace {}: concurrent modification",
                     clientAppId(), namespaceName);
             throw new RestException(Status.CONFLICT, "Concurrent modification");
         } catch (RestException pfe) {
             throw pfe;
         } catch (Exception e) {
-            log.error("[{}] Failed to update maxConsumersPerSubscription configuration for namespace {}", clientAppId(), namespaceName,
-                    e);
+            log.error("[{}] Failed to update maxConsumersPerSubscription configuration for namespace {}", clientAppId(),
+                    namespaceName, e);
+            throw new RestException(e);
+        }
+    }
+
+    protected void internalSetPolicy(Policies.PolicyProperty policyProperty, String jsonPolicyValue) {
+        if (policyProperty.isOnlySuperUser()) {
+            validateSuperUserAccess();
+        }
+        validatePoliciesReadOnlyAccess();
+
+        try {
+            Stat nodeStat = new Stat();
+            final String path = path(POLICIES, namespaceName.toString());
+            byte[] content = globalZk().getData(path, null, nodeStat);
+            Policies policies = jsonMapper().readValue(content, Policies.class);
+
+            Gson gson = new Gson();
+            Object policyValue = gson.fromJson(jsonPolicyValue, policyProperty.getType());
+
+            // When policyValue is Map instance, update by Map.put
+            if (policyValue instanceof Map) {
+                Map<Object, Object> resources = (Map<Object, Object>) Policies.class.getDeclaredField(policyProperty
+                        .getPropertyName()).get(policies);
+                for (Map.Entry<Object, Object> entry: ((Map<Object, Object>) policyValue).entrySet()) {
+                    resources.put(entry.getKey(), entry.getValue());
+                }
+            } else {
+                if (policyValue instanceof Integer && (Integer) policyValue < 0) {
+                    throw new RestException(Status.PRECONDITION_FAILED,
+                            String.format("%s must be 0 or more", policyProperty.name()));
+                }
+                Policies.class.getDeclaredField(policyProperty.getPropertyName()).set(policies, policyValue);
+            }
+
+            globalZk().setData(path, jsonMapper().writeValueAsBytes(policies), nodeStat.getVersion());
+            policiesCache().invalidate(path(POLICIES, namespaceName.toString()));
+            log.info("[{}] Successfully updated {} configuration: namespace={}, value={}", clientAppId(),
+                    policyProperty.name(), namespaceName,
+                    Policies.class.getDeclaredField(policyProperty.getPropertyName()).get(policies));
+
+        } catch (KeeperException.NoNodeException e) {
+            log.warn("[{}] Failed to update {} configuration for namespace {}: does not exist", clientAppId(),
+                    policyProperty.name(), namespaceName);
+            throw new RestException(Status.NOT_FOUND, "Namespace does not exist");
+        } catch (KeeperException.BadVersionException e) {
+            log.warn("[{}] Failed to update {} configuration for namespace {}: concurrent modification",
+                    clientAppId(), policyProperty.name(), namespaceName);
+            throw new RestException(Status.CONFLICT, "Concurrent modification");
+        } catch (RestException pfe) {
+            throw pfe;
+        } catch (JsonSyntaxException e) {
+            log.warn("[{}] Failed to update {} configuration for namespace {}: Json syntax error {}",
+                    clientAppId(), policyProperty.name(), namespaceName, jsonPolicyValue);
+            throw new RestException(Status.BAD_REQUEST, "Json syntax error" + jsonPolicyValue);
+        } catch (Exception e) {
+            log.error("[{}] Failed to update {} configuration for namespace {}", clientAppId(), policyProperty.name(),
+                    namespaceName, e);
             throw new RestException(e);
         }
     }
diff --git a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v1/Namespaces.java b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v1/Namespaces.java
index e3f5e4338..4d5ee819c 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v1/Namespaces.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/admin/v1/Namespaces.java
@@ -22,10 +22,7 @@
 import static org.apache.pulsar.broker.cache.ConfigurationCacheService.POLICIES;
 import static org.apache.pulsar.broker.cache.ConfigurationCacheService.POLICIES_ROOT;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -40,6 +37,7 @@
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response.Status;
 
+import com.google.gson.Gson;
 import org.apache.pulsar.broker.admin.AdminResource;
 import org.apache.pulsar.broker.admin.impl.NamespacesBase;
 import org.apache.pulsar.broker.web.RestException;
@@ -51,6 +49,7 @@
 import org.apache.pulsar.common.policies.data.DispatchRate;
 import org.apache.pulsar.common.policies.data.PersistencePolicies;
 import org.apache.pulsar.common.policies.data.Policies;
+import org.apache.pulsar.common.policies.data.Policies.PolicyProperty;
 import org.apache.pulsar.common.policies.data.RetentionPolicies;
 import org.apache.pulsar.common.policies.data.SubscriptionAuthMode;
 import org.apache.zookeeper.KeeperException;
@@ -144,6 +143,40 @@ public Policies getPolicies(@PathParam("property") String property, @PathParam("
         return getNamespacePolicies(namespaceName);
     }
 
+    @GET
+    @Path("/{property}/{cluster}/{namespace}/policies/{policyProperty}")
+    @ApiOperation(value = "Get a policy for a namespace.", response = Policies.class)
+    @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"),
+            @ApiResponse(code = 404, message = "Property or cluster or namespace doesn't exist") })
+    public Object getPolicy(@PathParam("property") String property,
+            @PathParam("cluster") String cluster, @PathParam("namespace") String namespace,
+            @PathParam("policyProperty") PolicyProperty policyProperty) {
+        validateAdminAccessOnProperty(property);
+        validateNamespaceName(property, cluster, namespace);
+        Policies policies = getNamespacePolicies(namespaceName);
+        Object result = null;
+        try {
+            result = Policies.class.getDeclaredField(policyProperty.getPropertyName()).get(policies);
+        } catch (Exception e) {
+            throw new RestException(Status.NOT_FOUND, "PolicyProperty does not exist");
+        }
+        if (result == null) throw new RestException(Status.NO_CONTENT, "Object does not exist");
+        return result;
+    }
+
+    @PUT
+    @Path("/{property}/{cluster}/{namespace}/policies/{policyProperty}")
+    @ApiOperation(value = "Set a policy for a namespace.", response = Policies.class)
+    @ApiResponses(value = { @ApiResponse(code = 403, message = "Don't have admin permission"),
+            @ApiResponse(code = 404, message = "Property or cluster or namespace doesn't exist") })
+    public void setPolicy(@PathParam("property") String property,
+            @PathParam("cluster") String cluster, @PathParam("namespace") String namespace,
+            @PathParam("policyProperty") Policies.PolicyProperty policyProperty, String jsonPolicyValue) {
+        validateAdminAccessOnProperty(property);
+        validateNamespaceName(property, cluster, namespace);
+        internalSetPolicy(policyProperty, jsonPolicyValue);
+    }
+
     @SuppressWarnings("deprecation")
     @PUT
     @Path("/{property}/{cluster}/{namespace}")
diff --git a/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/NamespacesImpl.java b/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/NamespacesImpl.java
index 58db21b5c..8d8a69b49 100644
--- a/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/NamespacesImpl.java
+++ b/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/NamespacesImpl.java
@@ -18,6 +18,7 @@
  */
 package org.apache.pulsar.client.admin.internal;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -152,7 +153,8 @@ public void deleteNamespaceBundle(String namespace, String bundleRange) throws P
         try {
             NamespaceName ns = NamespaceName.get(namespace);
             WebTarget path = namespacePath(ns, "permissions");
-            return request(path).get(new GenericType<Map<String, Set<AuthAction>>>() {});
+            return request(path).get(new GenericType<Map<String, Set<AuthAction>>>() {
+            });
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -186,7 +188,8 @@ public void revokePermissionsOnNamespace(String namespace, String role) throws P
         try {
             NamespaceName ns = NamespaceName.get(namespace);
             WebTarget path = namespacePath(ns, "replication");
-            return request(path).get(new GenericType<List<String>>() {});
+            return request(path).get(new GenericType<List<String>>() {
+            });
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -207,8 +210,9 @@ public void setNamespaceReplicationClusters(String namespace, List<String> clust
     public int getNamespaceMessageTTL(String namespace) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "messageTTL");
-            return request(path).get(new GenericType<Integer>() {});
+            WebTarget path = namespacePath(ns, "policies/MessageTtlInSecond");
+            return request(path).get(new GenericType<Integer>() {
+            });
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -218,8 +222,8 @@ public int getNamespaceMessageTTL(String namespace) throws PulsarAdminException
     public void setNamespaceMessageTTL(String namespace, int ttlInSeconds) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "messageTTL");
-            request(path).post(Entity.entity(ttlInSeconds, MediaType.APPLICATION_JSON), ErrorData.class);
+            WebTarget path = namespacePath(ns, "policies/MessageTtlInSeconds");
+            request(path).put(Entity.entity(ttlInSeconds, MediaType.APPLICATION_JSON), ErrorData.class);
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -230,8 +234,8 @@ public void setNamespaceAntiAffinityGroup(String namespace, String namespaceAnti
             throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "antiAffinity");
-            request(path).post(Entity.entity(namespaceAntiAffinityGroup, MediaType.APPLICATION_JSON), ErrorData.class);
+            WebTarget path = namespacePath(ns, "policies/AntiAffinityGroup");
+            request(path).put(Entity.entity(namespaceAntiAffinityGroup, MediaType.APPLICATION_JSON), ErrorData.class);
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -241,8 +245,9 @@ public void setNamespaceAntiAffinityGroup(String namespace, String namespaceAnti
     public String getNamespaceAntiAffinityGroup(String namespace) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "antiAffinity");
-            return request(path).get(new GenericType<String>() {});
+            WebTarget path = namespacePath(ns, "policies/AntiAffinityGroup");
+            return request(path).get(new GenericType<String>() {
+            });
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -253,7 +258,8 @@ public String getNamespaceAntiAffinityGroup(String namespace) throws PulsarAdmin
             throws PulsarAdminException {
         try {
             WebTarget path = adminV2Namespaces.path(cluster).path("antiAffinity").path(namespaceAntiAffinityGroup);
-            return request(path.queryParam("property", property)).get(new GenericType<List<String>>() {});
+            return request(path.queryParam("property", property)).get(new GenericType<List<String>>() {
+            });
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -274,8 +280,8 @@ public void deleteNamespaceAntiAffinityGroup(String namespace) throws PulsarAdmi
     public void setDeduplicationStatus(String namespace, boolean enableDeduplication) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "deduplication");
-            request(path).post(Entity.entity(enableDeduplication, MediaType.APPLICATION_JSON), ErrorData.class);
+            WebTarget path = namespacePath(ns, "policies/DeduplicationEnabled");
+            request(path).put(Entity.entity(enableDeduplication, MediaType.APPLICATION_JSON), ErrorData.class);
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -342,8 +348,8 @@ public PersistencePolicies getPersistence(String namespace) throws PulsarAdminEx
     public void setRetention(String namespace, RetentionPolicies retention) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "retention");
-            request(path).post(Entity.entity(retention, MediaType.APPLICATION_JSON), ErrorData.class);
+            WebTarget path = namespacePath(ns, "policies/RetentionPolicies");
+            request(path).put(Entity.entity(retention, MediaType.APPLICATION_JSON), ErrorData.class);
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -354,7 +360,7 @@ public void setRetention(String namespace, RetentionPolicies retention) throws P
     public RetentionPolicies getRetention(String namespace) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "retention");
+            WebTarget path = namespacePath(ns, "policies/RetentionPolicies");
             return request(path).get(RetentionPolicies.class);
         } catch (Exception e) {
             throw getApiException(e);
@@ -499,11 +505,12 @@ public void unsubscribeNamespaceBundle(String namespace, String bundle, String s
     }
 
     @Override
-    public void setSubscriptionAuthMode(String namespace, SubscriptionAuthMode subscriptionAuthMode) throws PulsarAdminException {
+    public void setSubscriptionAuthMode(String namespace, SubscriptionAuthMode subscriptionAuthMode)
+            throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "subscriptionAuthMode");
-            request(path).post(Entity.entity(subscriptionAuthMode, MediaType.APPLICATION_JSON), ErrorData.class);
+            WebTarget path = namespacePath(ns, "policies/SubscriptionAuthMode");
+            request(path).put(Entity.entity(subscriptionAuthMode, MediaType.APPLICATION_JSON), ErrorData.class);
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -513,8 +520,8 @@ public void setSubscriptionAuthMode(String namespace, SubscriptionAuthMode subsc
     public void setEncryptionRequiredStatus(String namespace, boolean encryptionRequired) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "encryptionRequired");
-            request(path).post(Entity.entity(encryptionRequired, MediaType.APPLICATION_JSON), ErrorData.class);
+            WebTarget path = namespacePath(ns, "policies/EncryptionRequired");
+            request(path).put(Entity.entity(encryptionRequired, MediaType.APPLICATION_JSON), ErrorData.class);
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -524,7 +531,7 @@ public void setEncryptionRequiredStatus(String namespace, boolean encryptionRequ
     public int getMaxProducersPerTopic(String namespace) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "maxProducersPerTopic");
+            WebTarget path = namespacePath(ns, "policies/MaxProducersPerTopic");
             return request(path).get(Integer.class);
         } catch (Exception e) {
             throw getApiException(e);
@@ -535,8 +542,8 @@ public int getMaxProducersPerTopic(String namespace) throws PulsarAdminException
     public void setMaxProducersPerTopic(String namespace, int maxProducersPerTopic) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "maxProducersPerTopic");
-            request(path).post(Entity.entity(maxProducersPerTopic, MediaType.APPLICATION_JSON), ErrorData.class);
+            WebTarget path = namespacePath(ns, "policies/MaxProducersPerTopic");
+            request(path).put(Entity.entity(maxProducersPerTopic, MediaType.APPLICATION_JSON), ErrorData.class);
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -546,7 +553,7 @@ public void setMaxProducersPerTopic(String namespace, int maxProducersPerTopic)
     public int getMaxConsumersPerTopic(String namespace) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "maxConsumersPerTopic");
+            WebTarget path = namespacePath(ns, "policies/MaxConsumersPerTopic");
             return request(path).get(Integer.class);
         } catch (Exception e) {
             throw getApiException(e);
@@ -557,8 +564,8 @@ public int getMaxConsumersPerTopic(String namespace) throws PulsarAdminException
     public void setMaxConsumersPerTopic(String namespace, int maxConsumersPerTopic) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "maxConsumersPerTopic");
-            request(path).post(Entity.entity(maxConsumersPerTopic, MediaType.APPLICATION_JSON), ErrorData.class);
+            WebTarget path = namespacePath(ns, "policies/MaxConsumersPerTopic");
+            request(path).put(Entity.entity(maxConsumersPerTopic, MediaType.APPLICATION_JSON), ErrorData.class);
         } catch (Exception e) {
             throw getApiException(e);
         }
@@ -568,7 +575,7 @@ public void setMaxConsumersPerTopic(String namespace, int maxConsumersPerTopic)
     public int getMaxConsumersPerSubscription(String namespace) throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "maxConsumersPerSubscription");
+            WebTarget path = namespacePath(ns, "policies/MaxConsumersPerSubscription");
             return request(path).get(Integer.class);
         } catch (Exception e) {
             throw getApiException(e);
@@ -576,11 +583,12 @@ public int getMaxConsumersPerSubscription(String namespace) throws PulsarAdminEx
     }
 
     @Override
-    public void setMaxConsumersPerSubscription(String namespace, int maxConsumersPerSubscription) throws PulsarAdminException {
+    public void setMaxConsumersPerSubscription(String namespace, int maxConsumersPerSubscription)
+            throws PulsarAdminException {
         try {
             NamespaceName ns = NamespaceName.get(namespace);
-            WebTarget path = namespacePath(ns, "maxConsumersPerSubscription");
-            request(path).post(Entity.entity(maxConsumersPerSubscription, MediaType.APPLICATION_JSON), ErrorData.class);
+            WebTarget path = namespacePath(ns, "policies/MaxConsumersPerSubscription");
+            request(path).put(Entity.entity(maxConsumersPerSubscription, MediaType.APPLICATION_JSON), ErrorData.class);
         } catch (Exception e) {
             throw getApiException(e);
         }
diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/policies/data/Policies.java b/pulsar-common/src/main/java/org/apache/pulsar/common/policies/data/Policies.java
index 03a8ce3d9..9132205dc 100644
--- a/pulsar-common/src/main/java/org/apache/pulsar/common/policies/data/Policies.java
+++ b/pulsar-common/src/main/java/org/apache/pulsar/common/policies/data/Policies.java
@@ -18,6 +18,7 @@
  */
 package org.apache.pulsar.common.policies.data;
 
+import java.lang.reflect.Type;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -25,8 +26,44 @@
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.reflect.TypeToken;
 
 public class Policies {
+    public enum PolicyProperty {
+        BacklogQuotaMap(new TypeToken<Map<BacklogQuota.BacklogQuotaType, BacklogQuota>>(){}.getType(), "backlog_quota_map", false),
+        DeduplicationEnabled(new TypeToken<Boolean>(){}.getType(), "deduplicationEnabled", false),
+        MessageTtlInSeconds(new TypeToken<Integer>(){}.getType(), "message_ttl_in_seconds", false),
+        RetentionPolicies(new TypeToken<RetentionPolicies>(){}.getType(), "retention_policies", false),
+        AntiAffinityGroup(new TypeToken<String>(){}.getType(), "antiAffinityGroup", false),
+        EncryptionRequired(new TypeToken<Boolean>(){}.getType(), "encryption_required", false),
+        SubscriptionAuthMode(new TypeToken<SubscriptionAuthMode>(){}.getType(), "subscription_auth_mode", false),
+        MaxProducersPerTopic(new TypeToken<Integer>(){}.getType(), "max_producers_per_topic", true),
+        MaxConsumersPerTopic(new TypeToken<Integer>(){}.getType(), "max_consumers_per_topic", true),
+        MaxConsumersPerSubscription(new TypeToken<Integer>(){}.getType(), "max_consumers_per_subscription", true),
+        ;
+
+        private final Type type;
+        private final String propertyName;
+        private final boolean isOnlySuperUser;
+
+        PolicyProperty(final Type type, final String propertyName, boolean isOnlySuperUser) {
+            this.type = type;
+            this.propertyName = propertyName;
+            this.isOnlySuperUser = isOnlySuperUser;
+        }
+
+        public Type getType() {
+            return type;
+        }
+
+        public String getPropertyName() {
+            return propertyName;
+        }
+
+        public boolean isOnlySuperUser() {
+            return isOnlySuperUser;
+        }
+    }
 
     public final AuthPolicies auth_policies = new AuthPolicies();
     public List<String> replication_clusters = Lists.newArrayList();


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services