/** * Copyright 2016 Yahoo Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.yahoo.pulsar.common.policies.impl; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.core.type.TypeReference; import org.testng.annotations.Test; import com.yahoo.pulsar.common.naming.NamespaceName; import com.yahoo.pulsar.common.policies.NamespaceIsolationPolicy; import com.yahoo.pulsar.common.policies.data.AutoFailoverPolicyData; import com.yahoo.pulsar.common.policies.data.AutoFailoverPolicyType; import com.yahoo.pulsar.common.policies.data.BrokerStatus; import com.yahoo.pulsar.common.policies.data.NamespaceIsolationData; import com.yahoo.pulsar.common.util.ObjectMapperFactory; @Test public class NamespaceIsolationPoliciesTest { private final String defaultJson = "{\"policy1\":{\"namespaces\":[\"pulsar/use/test.*\"],\"primary\":[\"prod1-broker[1-3].messaging.use.example.com\"],\"secondary\":[\"prod1-broker.*.use.example.com\"],\"auto_failover_policy\":{\"policy_type\":\"min_available\",\"parameters\":{\"min_limit\":\"3\",\"usage_threshold\":\"100\"}}}}"; @Test public void testJsonSerialization() throws Exception { // deserialize JSON string NamespaceIsolationPolicies policies = this.getDefaultTestPolicies(); // serialize the object to JSON string ObjectMapper jsonMapperForWriter = ObjectMapperFactory.create(); NamespaceIsolationPolicy nsPolicy = policies.getPolicyByName("policy1"); assertNotNull(nsPolicy); List<String> primaryBrokers = nsPolicy.getPrimaryBrokers(); byte[] primaryBrokersJson = jsonMapperForWriter.writeValueAsBytes(primaryBrokers); assertEquals(new String(primaryBrokersJson), "[\"prod1-broker[1-3].messaging.use.example.com\"]"); List<String> secondaryBrokers = nsPolicy.getSecondaryBrokers(); byte[] secondaryBrokersJson = jsonMapperForWriter.writeValueAsBytes(secondaryBrokers); assertEquals(new String(secondaryBrokersJson), "[\"prod1-broker.*.use.example.com\"]"); byte[] outJson = jsonMapperForWriter.writeValueAsBytes(policies.getPolicies()); assertEquals(new String(outJson), this.defaultJson); NamespaceIsolationData nsPolicyData = new NamespaceIsolationData(); nsPolicyData.namespaces = new ArrayList<String>(); nsPolicyData.namespaces.add("other/use/other.*"); nsPolicyData.primary = new ArrayList<String>(); nsPolicyData.primary.add("prod1-broker[4-6].messaging.use.example.com"); nsPolicyData.secondary = new ArrayList<String>(); nsPolicyData.secondary.add("prod1-broker.*.messaging.use.example.com"); nsPolicyData.auto_failover_policy = new AutoFailoverPolicyData(); nsPolicyData.auto_failover_policy.policy_type = AutoFailoverPolicyType.min_available; nsPolicyData.auto_failover_policy.parameters = new HashMap<String, String>(); nsPolicyData.auto_failover_policy.parameters.put("min_limit", "1"); nsPolicyData.auto_failover_policy.parameters.put("usage_threshold", "100"); policies.setPolicy("otherPolicy", nsPolicyData); byte[] morePolicyJson = jsonMapperForWriter.writeValueAsBytes(policies.getPolicies()); ObjectMapper jsonParser = ObjectMapperFactory.create(); Map<String, NamespaceIsolationData> policiesMap = jsonParser.readValue(morePolicyJson, new TypeReference<Map<String, NamespaceIsolationData>>() { }); assertEquals(policiesMap.size(), 2); } @Test public void testDefaultConstructor() throws Exception { NamespaceIsolationPolicies policies = new NamespaceIsolationPolicies(); assertTrue(policies.getPolicies().isEmpty()); byte[] outJson = ObjectMapperFactory.create().writeValueAsBytes(policies.getPolicies()); assertEquals(new String(outJson), "{}"); } @Test public void testDeletePolicy() throws Exception { NamespaceIsolationPolicies policies = this.getDefaultTestPolicies(); policies.deletePolicy("non-existing-policy"); assertTrue(!policies.getPolicies().isEmpty()); policies.deletePolicy("policy1"); assertTrue(policies.getPolicies().isEmpty()); } @Test public void testGetNamespaceIsolationPolicyByName() throws Exception { NamespaceIsolationPolicies policies = this.getDefaultTestPolicies(); NamespaceIsolationPolicy nsPolicy = policies.getPolicyByName("non-existing-policy"); assertTrue(nsPolicy == null); nsPolicy = policies.getPolicyByName("policy1"); assertNotNull(nsPolicy); assertEquals(new NamespaceIsolationPolicyImpl(policies.getPolicies().get("policy1")), nsPolicy); } @Test public void testGetNamespaceIsolationPolicyByNamespace() throws Exception { NamespaceIsolationPolicies policies = this.getDefaultTestPolicies(); NamespaceIsolationPolicy nsPolicy = policies.getPolicyByNamespace(new NamespaceName("no/such/namespace")); assertTrue(nsPolicy == null); nsPolicy = policies.getPolicyByNamespace(new NamespaceName("pulsar/use/testns-1")); assertNotNull(nsPolicy); assertEquals(new NamespaceIsolationPolicyImpl(policies.getPolicies().get("policy1")), nsPolicy); } @Test public void testSetPolicy() throws Exception { NamespaceIsolationPolicies policies = this.getDefaultTestPolicies(); // set a new policy String newPolicyJson = "{\"namespaces\":[\"pulsar/use/TESTNS.*\"],\"primary\":[\"prod1-broker[45].messaging.use.example.com\"],\"secondary\":[\"prod1-broker.*.use.example.com\"],\"auto_failover_policy\":{\"policy_type\":\"min_available\",\"parameters\":{\"min_limit\":2,\"usage_threshold\":80}}}"; String newPolicyName = "policy2"; ObjectMapper jsonMapper = ObjectMapperFactory.create(); NamespaceIsolationData nsPolicyData = jsonMapper.readValue(newPolicyJson.getBytes(), NamespaceIsolationData.class); policies.setPolicy(newPolicyName, nsPolicyData); assertEquals(policies.getPolicies().size(), 2); assertEquals(policies.getPolicyByName(newPolicyName), new NamespaceIsolationPolicyImpl(nsPolicyData)); assertTrue(!policies.getPolicyByName(newPolicyName).equals(policies.getPolicyByName("policy1"))); assertEquals(policies.getPolicyByNamespace(new NamespaceName("pulsar/use/TESTNS.1")), new NamespaceIsolationPolicyImpl(nsPolicyData)); } @SuppressWarnings("unchecked") private NamespaceIsolationPolicies getDefaultTestPolicies() throws Exception { ObjectMapper jsonMapper = ObjectMapperFactory.create(); return new NamespaceIsolationPolicies((Map<String, NamespaceIsolationData>) jsonMapper .readValue(this.defaultJson.getBytes(), new TypeReference<Map<String, NamespaceIsolationData>>() { })); } @Test public void testBrokerAssignment() throws Exception { NamespaceIsolationPolicies policies = this.getDefaultTestPolicies(); NamespaceName ns = new NamespaceName("pulsar/use/testns-1"); SortedSet<BrokerStatus> primaryCandidates = new TreeSet<>(); BrokerStatus primary = new BrokerStatus("prod1-broker1.messaging.use.example.com", true, 0); BrokerStatus secondary = new BrokerStatus("prod1-broker4.use.example.com", true, 0); BrokerStatus shared = new BrokerStatus("use.example.com", true, 0); SortedSet<BrokerStatus> secondaryCandidates = new TreeSet<>(); SortedSet<BrokerStatus> sharedCandidates = new TreeSet<>(); policies.assignBroker(ns, primary, primaryCandidates, secondaryCandidates, sharedCandidates); assertEquals(primaryCandidates.size(), 1); assertEquals(secondaryCandidates.size(), 0); assertEquals(sharedCandidates.size(), 0); assertTrue(primaryCandidates.first().equals(primary)); policies.assignBroker(ns, secondary, primaryCandidates, secondaryCandidates, sharedCandidates); assertEquals(primaryCandidates.size(), 1); assertEquals(secondaryCandidates.size(), 1); assertEquals(sharedCandidates.size(), 0); assertTrue(secondaryCandidates.first().equals(secondary)); policies.assignBroker(new NamespaceName("pulsar/use1/testns-1"), shared, primaryCandidates, secondaryCandidates, sharedCandidates); assertEquals(primaryCandidates.size(), 1); assertEquals(secondaryCandidates.size(), 1); assertEquals(sharedCandidates.size(), 1); assertTrue(sharedCandidates.first().equals(shared)); } }