View Javadoc

1   package org.apache.helix.webapp.resources;
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.io.StringReader;
23  import java.util.Arrays;
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.Map;
28  import java.util.Set;
29  import java.util.TreeMap;
30  
31  import org.apache.helix.HelixException;
32  import org.apache.helix.ZNRecord;
33  import org.apache.helix.tools.ClusterSetup;
34  import org.codehaus.jackson.map.ObjectMapper;
35  import org.restlet.data.Form;
36  import org.restlet.resource.Representation;
37  
38  
39  public class JsonParameters
40  {
41    // json parameter key
42    public static final String           JSON_PARAMETERS       = "jsonParameters";
43  
44    // json parameter map keys
45    public static final String           PARTITION             = "partition";
46    public static final String           RESOURCE              = "resource";
47    public static final String           MANAGEMENT_COMMAND    = "command";
48    public static final String           ENABLED               = "enabled";
49    public static final String           GRAND_CLUSTER         = "grandCluster";
50    public static final String           REPLICAS              = "replicas";
51    public static final String           RESOURCE_KEY_PREFIX   = "key";
52    public static final String           INSTANCE_NAME         = "instanceName";
53    public static final String           INSTANCE_NAMES        = "instanceNames";
54    public static final String           OLD_INSTANCE          = "oldInstance";
55    public static final String           NEW_INSTANCE          = "newInstance";
56    public static final String           CONFIGS               = "configs";
57    public static final String           CONSTRAINT_ATTRIBUTES = "constraintAttributes";
58  //  public static final String           CONSTRAINT_ID         = "constraintId";
59    public static final String           CLUSTER_NAME          = "clusterName";
60    public static final String           PARTITIONS            = "partitions";
61    public static final String           RESOURCE_GROUP_NAME   = "resourceGroupName";
62    public static final String           STATE_MODEL_DEF_REF   = "stateModelDefRef";
63    public static final String           IDEAL_STATE_MODE      = "mode";
64    public static final String           MAX_PARTITIONS_PER_NODE = "maxPartitionsPerNode";
65    public static final String           BUCKET_SIZE           = "bucketSize";
66    
67  
68    // zk commands
69    public static final String             ZK_DELETE_CHILDREN  = "zkDeleteChildren";
70  
71    // extra json parameter map keys
72    public static final String             NEW_IDEAL_STATE     = "newIdealState";
73    public static final String             NEW_STATE_MODEL_DEF = "newStateModelDef";
74  
75    public static final String TAG = "tag";
76  
77    // aliases for ClusterSetup commands
78    public static Map<String, Set<String>> CLUSTERSETUP_COMMAND_ALIASES;
79    static
80    {
81      CLUSTERSETUP_COMMAND_ALIASES = new HashMap<String, Set<String>>();
82      CLUSTERSETUP_COMMAND_ALIASES.put(ClusterSetup.addResource,
83                                       new HashSet<String>(Arrays.asList(new String[] { "addResourceGroup" })));
84      CLUSTERSETUP_COMMAND_ALIASES.put(ClusterSetup.activateCluster,
85                                       new HashSet<String>(Arrays.asList(new String[] { "enableStorageCluster" })));
86      CLUSTERSETUP_COMMAND_ALIASES.put(ClusterSetup.addInstance,
87                                       new HashSet<String>(Arrays.asList(new String[] { "addInstance" })));
88    }
89  
90    // parameter map
91    final Map<String, String>              _parameterMap;
92  
93    // extra parameters map
94    final Map<String, ZNRecord>            _extraParameterMap  =
95                                                                   new HashMap<String, ZNRecord>();
96  
97    public JsonParameters(Representation entity) throws Exception
98    {
99      Form form = new Form(entity);
100 
101     // get parameters in String format
102     String jsonPayload = form.getFirstValue(JSON_PARAMETERS, true);
103     if (jsonPayload == null || jsonPayload.isEmpty())
104     {
105       _parameterMap = Collections.emptyMap();
106     }
107     else
108     {
109       _parameterMap = ClusterRepresentationUtil.JsonToMap(jsonPayload);
110     }
111 
112     // get extra parameters in ZNRecord format
113     ObjectMapper mapper = new ObjectMapper();
114     String newIdealStateString = form.getFirstValue(NEW_IDEAL_STATE, true);
115 
116     if (newIdealStateString != null)
117     {
118       ZNRecord newIdealState =
119           mapper.readValue(new StringReader(newIdealStateString), ZNRecord.class);
120       _extraParameterMap.put(NEW_IDEAL_STATE, newIdealState);
121     }
122 
123     String newStateModelString = form.getFirstValue(NEW_STATE_MODEL_DEF, true);
124     if (newStateModelString != null)
125     {
126       ZNRecord newStateModel =
127           mapper.readValue(new StringReader(newStateModelString), ZNRecord.class);
128       _extraParameterMap.put(NEW_STATE_MODEL_DEF, newStateModel);
129     }
130   }
131 
132   public String getParameter(String key)
133   {
134     return _parameterMap.get(key);
135   }
136 
137   public String getCommand()
138   {
139     String command = _parameterMap.get(MANAGEMENT_COMMAND); 
140     return command;
141   }
142 
143   public ZNRecord getExtraParameter(String key)
144   {
145     return _extraParameterMap.get(key);
146   }
147 
148   public Map<String, String> cloneParameterMap()
149   {
150     Map<String, String> parameterMap = new TreeMap<String, String>();
151     parameterMap.putAll(_parameterMap);
152     return parameterMap;
153   }
154 
155   public void verifyCommand(String command)
156   {
157 
158     // verify command itself
159     if (_parameterMap.isEmpty())
160     {
161       throw new HelixException("'" + JSON_PARAMETERS + "' in the POST body is empty");
162     }
163 
164     if (!_parameterMap.containsKey(MANAGEMENT_COMMAND))
165     {
166       throw new HelixException("Missing management paramater '" + MANAGEMENT_COMMAND
167           + "'");
168     }
169 
170     if (!_parameterMap.get(MANAGEMENT_COMMAND).equalsIgnoreCase(command)
171         && !(CLUSTERSETUP_COMMAND_ALIASES.get(command) != null && CLUSTERSETUP_COMMAND_ALIASES.get(command)
172                                                                                               .contains(_parameterMap.get(MANAGEMENT_COMMAND))))
173     {
174       throw new HelixException(MANAGEMENT_COMMAND + " must be '" + command + "'");
175     }
176 
177     // verify command parameters
178     if (command.equalsIgnoreCase(ClusterSetup.enableInstance))
179     {
180       if (!_parameterMap.containsKey(ENABLED))
181       {
182         throw new HelixException("Missing Json parameters: '" + ENABLED + "'");
183       }
184     }
185     else if (command.equalsIgnoreCase(ClusterSetup.enablePartition))
186     {
187       if (!_parameterMap.containsKey(ENABLED))
188       {
189         throw new HelixException("Missing Json parameters: '" + ENABLED + "'");
190       }
191 
192       if (!_parameterMap.containsKey(PARTITION))
193       {
194         throw new HelixException("Missing Json parameters: '" + PARTITION + "'");
195       }
196 
197       if (!_parameterMap.containsKey(RESOURCE))
198       {
199         throw new HelixException("Missing Json parameters: '" + RESOURCE + "'");
200       }
201     }
202     else if (command.equalsIgnoreCase(ClusterSetup.resetPartition))
203     {
204       if (!_parameterMap.containsKey(PARTITION))
205       {
206         throw new HelixException("Missing Json parameters: '" + PARTITION + "'");
207       }
208 
209       if (!_parameterMap.containsKey(RESOURCE))
210       {
211         throw new HelixException("Missing Json parameters: '" + RESOURCE + "'");
212       }
213     }
214     else if (command.equalsIgnoreCase(ClusterSetup.resetInstance))
215     {
216       // nothing
217     }
218     else if (command.equalsIgnoreCase(ClusterSetup.activateCluster))
219     {
220       if (!_parameterMap.containsKey(GRAND_CLUSTER))
221       {
222         throw new HelixException("Missing Json parameters: '" + GRAND_CLUSTER + "'");
223       }
224     }
225     else if (command.equalsIgnoreCase(ClusterSetup.setConfig))
226     {
227       if (!_parameterMap.containsKey(CONFIGS))
228       {
229         throw new HelixException("Missing Json parameters: '" + CONFIGS + "'");
230       }
231     }
232     else if (command.equalsIgnoreCase(ClusterSetup.removeConfig))
233     {
234       if (!_parameterMap.containsKey(CONFIGS))
235       {
236         throw new HelixException("Missing Json parameters: '" + CONFIGS + "'");
237       }
238     }
239     else if (command.equalsIgnoreCase(ClusterSetup.addInstanceTag))
240     {
241       if (!_parameterMap.containsKey(ClusterSetup.instanceGroupTag))
242       {
243         throw new HelixException("Missing Json parameters: '" + ClusterSetup.instanceGroupTag + "'");
244       }
245     }
246     else if (command.equalsIgnoreCase(ClusterSetup.removeInstanceTag))
247     {
248       if (!_parameterMap.containsKey(ClusterSetup.instanceGroupTag))
249       {
250         throw new HelixException("Missing Json parameters: '" + ClusterSetup.instanceGroupTag + "'");
251       }
252     }
253     else if (command.equalsIgnoreCase(ClusterSetup.addCluster))
254     {
255       if (!_parameterMap.containsKey(CLUSTER_NAME))
256       {
257         throw new HelixException("Missing Json parameters: '" + CLUSTER_NAME + "'");
258       }
259     }
260     else if (command.equalsIgnoreCase(ClusterSetup.addResource))
261     {
262       if (!_parameterMap.containsKey(RESOURCE_GROUP_NAME))
263       {
264         throw new HelixException("Missing Json paramaters: '" + RESOURCE_GROUP_NAME + "'");
265       }
266 
267       if (!_parameterMap.containsKey(PARTITIONS))
268       {
269         throw new HelixException("Missing Json paramaters: '" + PARTITIONS + "'");
270       }
271 
272       if (!_parameterMap.containsKey(STATE_MODEL_DEF_REF))
273       {
274         throw new HelixException("Missing Json paramaters: '" + STATE_MODEL_DEF_REF + "'");
275       }
276 
277     }
278   }
279 
280   // temp test
281   public static void main(String[] args) throws Exception
282   {
283     String jsonPayload =
284         "{\"command\":\"resetPartition\",\"resource\": \"DB-1\",\"partition\":\"DB-1_22 DB-1_23\"}";
285     Map<String, String> map = ClusterRepresentationUtil.JsonToMap(jsonPayload);
286     System.out.println(map);
287   }
288 }