View Javadoc

1   package org.apache.helix.josql;
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.HashMap;
23  import java.util.HashSet;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Set;
27  import java.util.UUID;
28  
29  import org.apache.helix.HelixException;
30  import org.apache.helix.HelixManager;
31  import org.apache.helix.TestHelper;
32  import org.apache.helix.ZNRecord;
33  import org.apache.helix.integration.ZkStandAloneCMTestBase;
34  import org.apache.helix.josql.ClusterJosqlQueryProcessor;
35  import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
36  import org.testng.Assert;
37  import org.testng.annotations.Test;
38  
39  
40  public class TestJosqlProcessor extends ZkStandAloneCMTestBase
41  {
42    @Test (groups = {"integrationTest"})
43    public void testJosqlQuery() throws Exception
44    {
45      HelixManager manager = ((TestHelper.StartCMResult) (_startCMResultMap.values().toArray()[0]))._manager;
46      
47      // Find the instance name that contains partition TestDB_2 and state is 'MASTER'
48      String SQL = "SELECT id  " + 
49          "FROM LIVEINSTANCES " + 
50          "WHERE getMapFieldValue( getZNRecordFromMap(:IDEALSTATES , 'TestDB'), :partitionName, :_currObj.id)='MASTER'";
51      Map<String, Object> bindVariables = new HashMap<String, Object>();
52      bindVariables.put("partitionName", "TestDB_2");
53      
54      ClusterJosqlQueryProcessor p = new ClusterJosqlQueryProcessor(manager);
55      List<Object> result = p.runJoSqlQuery(SQL, bindVariables, null);
56      
57      Assert.assertEquals(result.size(), 1);
58      List<Object> firstList = (List<Object>) result.get(0);
59      Assert.assertTrue(((String)(firstList.get(0))).equalsIgnoreCase("localhost_12921"));
60      
61      // Find the live instances names that hosts Partition TestDB_10 according to idealstate
62      
63      SQL = "SELECT id  " + 
64          "FROM LIVEINSTANCES " + 
65          "WHERE hasMapFieldKey( getZNRecordFromMap(:IDEALSTATES, 'TestDB'), :partitionName, :_currObj.id)='true'";
66      p = new ClusterJosqlQueryProcessor(manager);
67      bindVariables.put("partitionName", "TestDB_10");
68      result = p.runJoSqlQuery(SQL, bindVariables, null);
69      
70      Assert.assertEquals(result.size(), 3);
71      Set<String> hosts = new HashSet<String>();
72      for(Object o : result)
73      {
74        String val = (String) ((List<Object>)o).get(0);
75        hosts.add(val);
76      }
77      Assert.assertTrue(hosts.contains("localhost_12918"));
78      Assert.assertTrue(hosts.contains("localhost_12920"));
79      Assert.assertTrue(hosts.contains("localhost_12921"));
80      
81      // Find the partitions on host localhost_12919 and is on MASTER state
82      SQL = "SELECT id  " + 
83          "FROM PARTITIONS " + 
84          "WHERE getMapFieldValue( getZNRecordFromMap(:EXTERNALVIEW, 'TestDB'), id, :instanceName)='MASTER'";
85      p = new ClusterJosqlQueryProcessor(manager);
86      bindVariables.clear();
87      bindVariables.put("instanceName", "localhost_12919");
88      result = p.runJoSqlQuery(SQL, bindVariables, null);
89      
90      Assert.assertEquals(result.size(), 4);
91      Set<String> partitions = new HashSet<String>();
92      for(Object o : result)
93      {
94        String val = (String) ((List<Object>)o).get(0);
95        partitions.add(val);
96      }
97      Assert.assertTrue(partitions.contains("TestDB_6"));
98      Assert.assertTrue(partitions.contains("TestDB_7"));
99      Assert.assertTrue(partitions.contains("TestDB_9"));
100     Assert.assertTrue(partitions.contains("TestDB_14"));
101 
102     // Find the partitions on host localhost_12919 and is on MASTER state
103     // Same as above but according to currentstates
104     SQL = "SELECT id  " + 
105         "FROM PARTITIONS " + 
106         "WHERE getMapFieldValue( getZNRecordFromMap(:CURRENTSTATES, :instanceName, 'TestDB'), :_currObj.id, :mapFieldKey)=:partitionState";
107     
108     p = new ClusterJosqlQueryProcessor(manager);
109     bindVariables.clear();
110     bindVariables.put("instanceName", "localhost_12919");
111     bindVariables.put("mapFieldKey", "CURRENT_STATE");
112     bindVariables.put("partitionState", "MASTER");
113     
114     result = p.runJoSqlQuery(SQL,  bindVariables, null);
115     
116     Assert.assertEquals(result.size(), 4);
117     partitions.clear();
118     partitions = new HashSet<String>();
119     for(Object o : result)
120     {
121       String val = (String) ((List<Object>)o).get(0);
122       partitions.add(val);
123     }
124     Assert.assertTrue(partitions.contains("TestDB_6"));
125     Assert.assertTrue(partitions.contains("TestDB_7"));
126     Assert.assertTrue(partitions.contains("TestDB_9"));
127     Assert.assertTrue(partitions.contains("TestDB_14"));
128     
129     // get node name that hosts a certain partition with certain state
130     
131     SQL = "SELECT id  " + 
132         "FROM LIVEINSTANCES " + 
133         "WHERE getMapFieldValue( getZNRecordFromMap(:CURRENTSTATES, id, 'TestDB'), :partitionName, :mapFieldKey)=:partitionState";
134     
135     p = new ClusterJosqlQueryProcessor(manager);
136     bindVariables.clear();
137     bindVariables.put("partitionName", "TestDB_8");
138     bindVariables.put("mapFieldKey", "CURRENT_STATE");
139     bindVariables.put("partitionState", "SLAVE");
140     
141     result = p.runJoSqlQuery(SQL,  bindVariables, null);
142     
143     Assert.assertEquals(result.size(), 2);
144     partitions.clear();
145     partitions = new HashSet<String>();
146     for(Object o : result)
147     {
148       String val = (String) ((List<Object>)o).get(0);
149       partitions.add(val);
150     }
151     Assert.assertTrue(partitions.contains("localhost_12918"));
152     Assert.assertTrue(partitions.contains("localhost_12922"));
153   }
154   
155   @Test (groups = {"unitTest"})
156   public void parseFromTarget() 
157   {
158     ClusterJosqlQueryProcessor p = new ClusterJosqlQueryProcessor(null);
159     String sql = "SELECT id  " + 
160         "FROM LIVEINSTANCES ";
161     String from = p.parseFromTarget(sql);
162     Assert.assertTrue(from.equals("LIVEINSTANCES"));
163     
164     sql = "SELECT id      " + 
165         "FROM    LIVEINSTANCES  WHERE 1=2";
166     
167     from = p.parseFromTarget(sql);
168     Assert.assertTrue(from.equals("LIVEINSTANCES"));
169     
170     sql = "SELECT id      " + 
171         "FROM LIVEINSTANCES";
172     
173     from = p.parseFromTarget(sql);
174     Assert.assertTrue(from.equals("LIVEINSTANCES"));
175     
176     sql = "SELECT id      " + 
177         " LIVEINSTANCES where tt=00";
178     boolean exceptionThrown = false;
179     try
180     {
181       from = p.parseFromTarget(sql);
182     }
183     catch(HelixException e)
184     {
185       exceptionThrown = true;
186     }
187     Assert.assertTrue(exceptionThrown);
188   }
189   
190   @Test (groups=("unitTest"))
191   public void testOrderby() throws Exception
192   {
193     HelixManager manager = ((TestHelper.StartCMResult) (_startCMResultMap.values().toArray()[0]))._manager;
194     
195     Map<String, ZNRecord> scnMap = new HashMap<String, ZNRecord>();
196     for(int i = 0;i < NODE_NR; i++)
197     {
198       String instance = "localhost_"+(12918+i);
199       ZNRecord metaData = new ZNRecord(instance);
200       metaData.setSimpleField(LiveInstanceProperty.SESSION_ID.toString(),
201           UUID.randomUUID().toString());
202       metaData.setMapField("SCN", new HashMap<String, String>());
203       for(int j = 0;j < _PARTITIONS; j++)
204       {
205         metaData.getMapField("SCN").put(TEST_DB+"_"+j, ""+i);
206       }
207       scnMap.put(instance, metaData);
208     }
209     Map<String, Object> bindVariables = new HashMap<String, Object>();
210     bindVariables.put("scnMap", scnMap);
211     String SQL = 
212         " SELECT DISTINCT mapSubKey AS 'subkey', mapValue AS 'mapValue' , getMapFieldValue(getZNRecordFromMap(:scnMap, mapSubKey), 'SCN', mapKey) AS 'SCN'" +
213         " FROM EXTERNALVIEW.Table " + 
214         " WHERE mapKey LIKE 'TestDB_1' " +
215           " AND mapSubKey LIKE '%' " +
216           " AND mapValue LIKE 'SLAVE' " +
217           " AND mapSubKey IN ((SELECT [*]id FROM :LIVEINSTANCES)) " +
218           " ORDER BY parseInt(getMapFieldValue(getZNRecordFromMap(:scnMap, mapSubKey), 'SCN', mapKey))";
219 
220     ClusterJosqlQueryProcessor p = new ClusterJosqlQueryProcessor(manager);
221     List<Object> result = p.runJoSqlQuery(SQL, bindVariables, null);
222     int prevSCN = -1;
223     for(Object row : result)
224     {
225       List<String> stringRow = (List<String>)row;
226       Assert.assertTrue(stringRow.get(1).equals("SLAVE"));
227       int scn = Integer.parseInt(stringRow.get(2));
228       Assert.assertTrue(scn > prevSCN);
229       prevSCN = scn;
230     }
231   }
232 }