View Javadoc

1   package org.apache.helix;
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.ArrayList;
23  import java.util.Collections;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Random;
27  import java.util.Set;
28  import java.util.TreeMap;
29  
30  import org.apache.helix.ZNRecord;
31  import org.apache.helix.controller.ExternalViewGenerator;
32  import org.apache.helix.model.Message;
33  import org.apache.helix.model.CurrentState.CurrentStateProperty;
34  import org.testng.AssertJUnit;
35  import org.testng.annotations.Test;
36  
37  
38  public class TestZKRoutingInfoProvider
39  {
40    public Map<String, List<ZNRecord>> createCurrentStates(String[] dbNames,
41        String[] nodeNames, int[] partitions, int[] replicas)
42    {
43      Map<String, List<ZNRecord>> currentStates = new TreeMap<String, List<ZNRecord>>();
44      Map<String, Map<String, ZNRecord>> currentStates2 = new TreeMap<String, Map<String, ZNRecord>>();
45  
46      Map<String, String> stateMaster = new TreeMap<String, String>();
47      stateMaster.put(CurrentStateProperty.CURRENT_STATE.toString(), "MASTER");
48  
49      Map<String, String> stateSlave = new TreeMap<String, String>();
50      stateSlave.put(CurrentStateProperty.CURRENT_STATE.toString(), "SLAVE");
51  
52      for (int i = 0; i < nodeNames.length; i++)
53      {
54        currentStates.put(nodeNames[i], new ArrayList<ZNRecord>());
55        currentStates2.put(nodeNames[i], new TreeMap<String, ZNRecord>());
56        for (int j = 0; j < dbNames.length; j++)
57        {
58          ZNRecord dbPartitionState = new ZNRecord(dbNames[j]);
59          currentStates2.get(nodeNames[i]).put(dbNames[j], dbPartitionState);
60        }
61      }
62  
63      Random rand = new Random(1234);
64      for (int j = 0; j < dbNames.length; j++)
65      {
66        int partition = partitions[j];
67        ArrayList<Integer> randomArray = new ArrayList<Integer>();
68        for (int i = 0; i < partition; i++)
69        {
70          randomArray.add(i);
71        }
72        Collections.shuffle(randomArray, rand);
73  
74        for (int i = 0; i < partition; i++)
75        {
76          stateMaster.put(Message.Attributes.RESOURCE_NAME.toString(),
77              dbNames[j]);
78          stateSlave.put(Message.Attributes.RESOURCE_NAME.toString(),
79              dbNames[j]);
80          int nodes = nodeNames.length;
81          int master = randomArray.get(i) % nodes;
82          String partitionName = dbNames[j] + ".partition-" + i;
83          Map<String, Map<String, String>> map = (currentStates2
84              .get(nodeNames[master]).get(dbNames[j]).getMapFields());
85          assert (map != null);
86          map.put(partitionName, stateMaster);
87  
88          for (int k = 1; k <= replicas[j]; k++)
89          {
90            int slave = (master + k) % nodes;
91            Map<String, Map<String, String>> map2 = currentStates2
92                .get(nodeNames[slave]).get(dbNames[j]).getMapFields();
93  
94            map2.put(partitionName, stateSlave);
95          }
96        }
97      }
98      for (String nodeName : currentStates2.keySet())
99      {
100       Map<String, ZNRecord> recMap = currentStates2.get(nodeName);
101       List<ZNRecord> list = new ArrayList<ZNRecord>();
102       for (ZNRecord rec : recMap.values())
103       {
104         list.add(rec);
105       }
106       currentStates.put(nodeName, list);
107     }
108     return currentStates;
109   }
110 
111   private void verify(Map<String, List<ZNRecord>> currentStates,
112       Map<String, Map<String, Set<String>>> routingMap)
113   {
114     int counter1 = 0;
115     int counter2 = 0;
116     for (String nodeName : currentStates.keySet())
117     {
118       List<ZNRecord> dbStateList = currentStates.get(nodeName);
119       for (ZNRecord dbState : dbStateList)
120       {
121         Map<String, Map<String, String>> dbStateMap = dbState.getMapFields();
122         for (String partitionName : dbStateMap.keySet())
123         {
124           Map<String, String> stateMap = dbStateMap
125               .get(partitionName);
126           String state = stateMap
127               .get(CurrentStateProperty.CURRENT_STATE.toString());
128           AssertJUnit.assertTrue(routingMap.get(partitionName).get(state)
129               .contains(nodeName));
130           counter1++;
131         }
132       }
133     }
134 
135     for (String partitionName : routingMap.keySet())
136     {
137       Map<String, Set<String>> partitionState = routingMap.get(partitionName);
138       for (String state : partitionState.keySet())
139       {
140         counter2 += partitionState.get(state).size();
141       }
142     }
143     AssertJUnit.assertTrue(counter2 == counter1);
144   }
145 
146   // public static void main(String[] args)
147   @Test ()
148   public void testInvocation() throws Exception
149   {
150     String[] dbNames = new String[3];
151     for (int i = 0; i < dbNames.length; i++)
152     {
153       dbNames[i] = "DB_" + i;
154     }
155     String[] nodeNames = new String[6];
156     for (int i = 0; i < nodeNames.length; i++)
157     {
158       nodeNames[i] = "LOCALHOST_100" + i;
159     }
160 
161     int[] partitions = new int[dbNames.length];
162     for (int i = 0; i < partitions.length; i++)
163     {
164       partitions[i] = (i + 1) * 10;
165     }
166 
167     int[] replicas = new int[dbNames.length];
168     for (int i = 0; i < replicas.length; i++)
169     {
170       replicas[i] = 3;
171     }
172     Map<String, List<ZNRecord>> currentStates = createCurrentStates(dbNames,
173         nodeNames, partitions, replicas);
174     ExternalViewGenerator provider = new ExternalViewGenerator();
175 
176     List<ZNRecord> mockIdealStates = new ArrayList<ZNRecord>();
177     for (String dbName : dbNames)
178     {
179       ZNRecord rec = new ZNRecord(dbName);
180       mockIdealStates.add(rec);
181     }
182     List<ZNRecord> externalView = provider.computeExternalView(currentStates,
183         mockIdealStates);
184 
185     Map<String, Map<String, Set<String>>> routingMap = provider
186         .getRouterMapFromExternalView(externalView);
187 
188     verify(currentStates, routingMap);
189 
190     /* write current state and external view to ZK */
191     /*
192      * String clusterName = "test-cluster44"; ZkClient zkClient = new
193      * ZkClient("localhost:2181"); zkClient.setZkSerializer(new
194      * ZNRecordSerializer());
195      *
196      * for(String nodeName : currentStates.keySet()) {
197      * if(zkClient.exists(CMUtil.getCurrentStatePath(clusterName, nodeName))) {
198      * zkClient.deleteRecursive(CMUtil.getCurrentStatePath(clusterName,
199      * nodeName)); } ZKUtil.createChildren(zkClient,CMUtil.getCurrentStatePath
200      * (clusterName, nodeName), currentStates.get(nodeName)); }
201      *
202      * //List<ZNRecord> externalView =
203      * ZKRoutingInfoProvider.computeExternalView(currentStates); String
204      * routingTablePath = CMUtil.getExternalViewPath(clusterName);
205      * if(zkClient.exists(routingTablePath)) {
206      * zkClient.deleteRecursive(routingTablePath); }
207      *
208      * ZKUtil.createChildren(zkClient, CMUtil.getExternalViewPath(clusterName),
209      * externalView);
210      */
211   }
212 }