View Javadoc

1   package org.apache.helix.model;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Date;
23  import java.util.HashMap;
24  import java.util.Map;
25  import java.util.Set;
26  import java.util.TreeMap;
27  
28  import org.apache.helix.TestHelper;
29  import org.apache.helix.ZNRecord;
30  import org.apache.helix.ZkUnitTestBase;
31  import org.apache.helix.PropertyKey.Builder;
32  import org.apache.helix.manager.zk.ZKHelixDataAccessor;
33  import org.apache.helix.manager.zk.ZkBaseDataAccessor;
34  import org.apache.helix.model.ClusterConstraints;
35  import org.apache.helix.model.Message;
36  import org.apache.helix.model.ClusterConstraints.ConstraintAttribute;
37  import org.apache.helix.model.ClusterConstraints.ConstraintType;
38  import org.apache.helix.model.Message.MessageType;
39  import org.apache.log4j.Logger;
40  import org.testng.Assert;
41  import org.testng.annotations.Test;
42  
43  
44  public class TestConstraint extends ZkUnitTestBase
45  {
46    private static Logger LOG = Logger.getLogger(TestConstraint.class);
47  
48    @Test
49    public void testMsgConstraint()
50    {
51      String className = getShortClassName();
52      System.out.println("START testMsgConstraint() at "
53          + new Date(System.currentTimeMillis()));
54  
55      String clusterName = "CLUSTER_" + className + "_msg";
56      TestHelper.setupEmptyCluster(_gZkClient, clusterName);
57      ZNRecord record = new ZNRecord("testMsgConstraint");
58  
59      // constraint0:
60      // "MESSAGE_TYPE=STATE_TRANSITION,CONSTRAINT_VALUE=ANY"
61      record.setMapField("constraint0", new TreeMap<String, String>());
62      record.getMapField("constraint0").put("MESSAGE_TYPE", "STATE_TRANSITION");
63      record.getMapField("constraint0").put("CONSTRAINT_VALUE", "ANY");
64      ConstraintItem constraint0 = new ConstraintItem(record.getMapField("constraint0"));
65  
66      // constraint1:
67      // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,CONSTRAINT_VALUE=ANY"
68      record.setMapField("constraint1", new TreeMap<String, String>());
69      record.getMapField("constraint1").put("MESSAGE_TYPE", "STATE_TRANSITION");
70      record.getMapField("constraint1").put("TRANSITION", "OFFLINE-SLAVE");
71      record.getMapField("constraint1").put("CONSTRAINT_VALUE", "50");
72      ConstraintItem constraint1 = new ConstraintItem(record.getMapField("constraint1"));
73  
74      // constraint2:
75      // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,INSTANCE=.*,RESOURCE=TestDB,CONSTRAINT_VALUE=2";
76      record.setMapField("constraint2", new TreeMap<String, String>());
77      record.getMapField("constraint2").put("MESSAGE_TYPE", "STATE_TRANSITION");
78      record.getMapField("constraint2").put("TRANSITION", "OFFLINE-SLAVE");
79      record.getMapField("constraint2").put("INSTANCE", ".*");
80      record.getMapField("constraint2").put("RESOURCE", "TestDB");
81      record.getMapField("constraint2").put("CONSTRAINT_VALUE", "2");
82      ConstraintItem constraint2 = new ConstraintItem(record.getMapField("constraint2"));
83  
84      // constraint3:
85      // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,INSTANCE=localhost_12918,RESOURCE=.*,CONSTRAINT_VALUE=1";
86      record.setMapField("constraint3", new TreeMap<String, String>());
87      record.getMapField("constraint3").put("MESSAGE_TYPE", "STATE_TRANSITION");
88      record.getMapField("constraint3").put("TRANSITION", "OFFLINE-SLAVE");
89      record.getMapField("constraint3").put("INSTANCE", "localhost_12919");
90      record.getMapField("constraint3").put("RESOURCE", ".*");
91      record.getMapField("constraint3").put("CONSTRAINT_VALUE", "1");
92      ConstraintItem constraint3 = new ConstraintItem(record.getMapField("constraint3"));
93  
94      // constraint4:
95      // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,INSTANCE=.*,RESOURCE=.*,CONSTRAINT_VALUE=10"
96      record.setMapField("constraint4", new TreeMap<String, String>());
97      record.getMapField("constraint4").put("MESSAGE_TYPE", "STATE_TRANSITION");
98      record.getMapField("constraint4").put("TRANSITION", "OFFLINE-SLAVE");
99      record.getMapField("constraint4").put("INSTANCE", ".*");
100     record.getMapField("constraint4").put("RESOURCE", ".*");
101     record.getMapField("constraint4").put("CONSTRAINT_VALUE", "10");
102     ConstraintItem constraint4 = new ConstraintItem(record.getMapField("constraint4"));
103 
104     // constraint5:
105     // "MESSAGE_TYPE=STATE_TRANSITION,TRANSITION=OFFLINE-SLAVE,INSTANCE=localhost_12918,RESOURCE=TestDB,CONSTRAINT_VALUE=5"
106     record.setMapField("constraint5", new TreeMap<String, String>());
107     record.getMapField("constraint5").put("MESSAGE_TYPE", "STATE_TRANSITION");
108     record.getMapField("constraint5").put("TRANSITION", "OFFLINE-SLAVE");
109     record.getMapField("constraint5").put("INSTANCE", "localhost_12918");
110     record.getMapField("constraint5").put("RESOURCE", "TestDB");
111     record.getMapField("constraint5").put("CONSTRAINT_VALUE", "5");
112     ConstraintItem constraint5 = new ConstraintItem(record.getMapField("constraint5"));
113 
114     ZKHelixDataAccessor accessor =
115         new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(_gZkClient));
116     Builder keyBuilder = accessor.keyBuilder();
117 
118     accessor.setProperty(keyBuilder.constraint(ConstraintType.MESSAGE_CONSTRAINT.toString()),
119                          new ClusterConstraints(record));
120 
121     record =
122         accessor.getProperty(keyBuilder.constraint(ConstraintType.MESSAGE_CONSTRAINT.toString()))
123                 .getRecord();
124     ClusterConstraints constraint = new ClusterConstraints(record);
125     // System.out.println("constraint: " + constraint);
126 
127     // message1
128     Message msg1 =
129         createMessage(MessageType.STATE_TRANSITION,
130                       "msgId-001",
131                       "OFFLINE",
132                       "SLAVE",
133                       "TestDB",
134                       "localhost_12918");
135 
136     Map<ConstraintAttribute, String> msgAttr =
137         ClusterConstraints.toConstraintAttributes(msg1);
138     Set<ConstraintItem> matches = constraint.match(msgAttr);
139     System.out.println(msg1 + " matches(" + matches.size() + "): " + matches);
140     Assert.assertEquals(matches.size(), 5);
141     Assert.assertTrue(contains(matches, constraint0));
142     Assert.assertTrue(contains(matches, constraint1));
143     Assert.assertTrue(contains(matches, constraint2));
144     Assert.assertTrue(contains(matches, constraint4));
145     Assert.assertTrue(contains(matches, constraint5));
146 
147     // message2
148     Message msg2 =
149         createMessage(MessageType.STATE_TRANSITION,
150                       "msgId-002",
151                       "OFFLINE",
152                       "SLAVE",
153                       "TestDB",
154                       "localhost_12919");
155 
156     msgAttr = ClusterConstraints.toConstraintAttributes(msg2);
157     matches = constraint.match(msgAttr);
158     System.out.println(msg2 + " matches(" + matches.size() + "): " + matches);
159     Assert.assertEquals(matches.size(), 5);
160     Assert.assertTrue(contains(matches, constraint0));
161     Assert.assertTrue(contains(matches, constraint1));
162     Assert.assertTrue(contains(matches, constraint2));
163     Assert.assertTrue(contains(matches, constraint3));
164     Assert.assertTrue(contains(matches, constraint4));
165 
166     System.out.println("END testMsgConstraint() at "
167         + new Date(System.currentTimeMillis()));
168   }
169 
170   @Test
171   public void testStateConstraint()
172   {
173     String className = getShortClassName();
174     System.out.println("START testStateConstraint() at "
175         + new Date(System.currentTimeMillis()));
176 
177     String clusterName = "CLUSTER_" + className + "_state";
178     TestHelper.setupEmptyCluster(_gZkClient, clusterName);
179     ZNRecord record = new ZNRecord("testStateConstraint");
180 
181     // constraint0:
182     // "STATE=MASTER,CONSTRAINT_VALUE=1"
183     record.setMapField("constraint0", new TreeMap<String, String>());
184     record.getMapField("constraint0").put("STATE", "MASTER");
185     record.getMapField("constraint0").put("CONSTRAINT_VALUE", "1");
186     ConstraintItem constraint0 = new ConstraintItem(record.getMapField("constraint0"));
187 
188     // constraint1:
189     // "STATE=MASTER,RESOURCE=TestDB,CONSTRAINT_VALUE=5"
190     record.setMapField("constraint1", new TreeMap<String, String>());
191     record.getMapField("constraint1").put("STATE", "MASTER");
192     record.getMapField("constraint1").put("RESOURCE", "TestDB");
193     record.getMapField("constraint1").put("CONSTRAINT_VALUE", "1");
194     ConstraintItem constraint1 = new ConstraintItem(record.getMapField("constraint1"));
195 
196     // constraint2:
197     // "STATE=MASTER,RESOURCE=.*,CONSTRAINT_VALUE=2"
198     record.setMapField("constraint2", new TreeMap<String, String>());
199     record.getMapField("constraint2").put("STATE", "MASTER");
200     record.getMapField("constraint2").put("RESOURCE", ".*");
201     record.getMapField("constraint2").put("CONSTRAINT_VALUE", "2");
202     ConstraintItem constraint2 = new ConstraintItem(record.getMapField("constraint2"));
203 
204     ZKHelixDataAccessor accessor =
205         new ZKHelixDataAccessor(clusterName, new ZkBaseDataAccessor(_gZkClient));
206     Builder keyBuilder = accessor.keyBuilder();
207 
208     accessor.setProperty(keyBuilder.constraint(ConstraintType.STATE_CONSTRAINT.toString()),
209                          new ClusterConstraints(record));
210 
211     record =
212         accessor.getProperty(keyBuilder.constraint(ConstraintType.STATE_CONSTRAINT.toString()))
213                 .getRecord();
214     ClusterConstraints constraint = new ClusterConstraints(record);
215     // System.out.println("constraint: " + constraint);
216 
217     // state1: hit rule2
218     Map<ConstraintAttribute, String> stateAttr1 =
219         new HashMap<ConstraintAttribute, String>();
220     stateAttr1.put(ConstraintAttribute.STATE, "MASTER");
221     stateAttr1.put(ConstraintAttribute.RESOURCE, "TestDB");
222 
223     Set<ConstraintItem> matches = constraint.match(stateAttr1);
224     System.out.println(stateAttr1 + " matches(" + matches.size() + "): " + matches);
225     Assert.assertEquals(matches.size(), 3);
226     Assert.assertTrue(contains(matches, constraint0));
227     Assert.assertTrue(contains(matches, constraint1));
228     Assert.assertTrue(contains(matches, constraint2));
229 
230     // matches = selectConstraints(matches, stateAttr1);
231     // System.out.println(stateAttr1 + " matches(" + matches.size() + "): " + matches);
232     // Assert.assertEquals(matches.size(), 2);
233     // Assert.assertTrue(contains(matches, constraint0));
234     // Assert.assertTrue(contains(matches, constraint1));
235 
236     // state2: not hit any rules
237     Map<ConstraintAttribute, String> stateAttr2 =
238         new HashMap<ConstraintAttribute, String>();
239     stateAttr2.put(ConstraintAttribute.STATE, "MASTER");
240     stateAttr2.put(ConstraintAttribute.RESOURCE, "MyDB");
241 
242     matches = constraint.match(stateAttr2);
243     System.out.println(stateAttr2 + " matches(" + matches.size() + "): " + matches);
244     Assert.assertEquals(matches.size(), 2);
245     Assert.assertTrue(contains(matches, constraint0));
246     Assert.assertTrue(contains(matches, constraint2));
247 
248     // matches = selectConstraints(matches, stateAttr2);
249     // System.out.println(stateAttr2 + " matches(" + matches.size() + "): " + matches);
250     // Assert.assertEquals(matches.size(), 2);
251     // Assert.assertTrue(contains(matches, constraint0));
252     // Assert.assertTrue(contains(matches, constraint2));
253 
254     System.out.println("END testStateConstraint() at "
255         + new Date(System.currentTimeMillis()));
256   }
257 
258   private boolean contains(Set<ConstraintItem> constraints, ConstraintItem constraint)
259   {
260     for (ConstraintItem item : constraints)
261     {
262       if (item.toString().equals(constraint.toString()))
263       {
264         return true;
265       }
266     }
267     return false;
268   }
269 }