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 static org.apache.helix.PropertyType.ALERTS;
23  import static org.apache.helix.PropertyType.ALERT_STATUS;
24  import static org.apache.helix.PropertyType.CONFIGS;
25  import static org.apache.helix.PropertyType.CURRENTSTATES;
26  import static org.apache.helix.PropertyType.EXTERNALVIEW;
27  import static org.apache.helix.PropertyType.HEALTHREPORT;
28  import static org.apache.helix.PropertyType.HISTORY;
29  import static org.apache.helix.PropertyType.IDEALSTATES;
30  import static org.apache.helix.PropertyType.LIVEINSTANCES;
31  import static org.apache.helix.PropertyType.MESSAGES;
32  import static org.apache.helix.PropertyType.PAUSE;
33  import static org.apache.helix.PropertyType.STATEMODELDEFS;
34  import static org.apache.helix.PropertyType.STATUSUPDATES;
35  
36  import java.util.Arrays;
37  import java.util.HashMap;
38  import java.util.Map;
39  import java.util.regex.Matcher;
40  import java.util.regex.Pattern;
41  
42  import org.apache.helix.model.AlertStatus;
43  import org.apache.helix.model.Alerts;
44  import org.apache.helix.model.CurrentState;
45  import org.apache.helix.model.ExternalView;
46  import org.apache.helix.model.HealthStat;
47  import org.apache.helix.model.IdealState;
48  import org.apache.helix.model.InstanceConfig;
49  import org.apache.helix.model.LeaderHistory;
50  import org.apache.helix.model.LiveInstance;
51  import org.apache.helix.model.Message;
52  import org.apache.helix.model.PauseSignal;
53  import org.apache.helix.model.StateModelDefinition;
54  import org.apache.helix.model.StatusUpdate;
55  import org.apache.log4j.Logger;
56  
57  
58  public class PropertyPathConfig
59  {
60    private static Logger logger = Logger.getLogger(PropertyPathConfig.class);
61  
62    static final Map<PropertyType, Map<Integer, String>> templateMap = new HashMap<PropertyType, Map<Integer, String>>();
63    static final Map<PropertyType, Class<? extends HelixProperty>> typeToClassMapping= new HashMap<PropertyType, Class<? extends HelixProperty>>();
64    static{
65      typeToClassMapping.put(LIVEINSTANCES, LiveInstance.class);
66      typeToClassMapping.put(IDEALSTATES, IdealState.class);
67      typeToClassMapping.put(CONFIGS, InstanceConfig.class);
68      typeToClassMapping.put(EXTERNALVIEW, ExternalView.class);
69      typeToClassMapping.put(STATEMODELDEFS, StateModelDefinition.class);
70      typeToClassMapping.put(MESSAGES, Message.class);
71      typeToClassMapping.put(CURRENTSTATES, CurrentState.class);
72      typeToClassMapping.put(STATUSUPDATES, StatusUpdate.class);
73      typeToClassMapping.put(HISTORY, LeaderHistory.class);
74      typeToClassMapping.put(HEALTHREPORT, HealthStat.class);
75      typeToClassMapping.put(ALERTS, Alerts.class);
76      typeToClassMapping.put(ALERT_STATUS, AlertStatus.class);
77      typeToClassMapping.put(PAUSE, PauseSignal.class);
78  
79      // @formatter:off
80      addEntry(PropertyType.CONFIGS, 1, "/{clusterName}/CONFIGS");
81      addEntry(PropertyType.CONFIGS, 2, "/{clusterName}/CONFIGS/{scope}");
82      addEntry(PropertyType.CONFIGS, 3, "/{clusterName}/CONFIGS/{scope}/{scopeKey}");
83      // addEntry(PropertyType.CONFIGS,2,"/{clusterName}/CONFIGS/{instanceName}");
84      addEntry(PropertyType.LIVEINSTANCES, 1, "/{clusterName}/LIVEINSTANCES");
85      addEntry(PropertyType.LIVEINSTANCES, 2, "/{clusterName}/LIVEINSTANCES/{instanceName}");
86      addEntry(PropertyType.INSTANCES, 1, "/{clusterName}/INSTANCES");
87      addEntry(PropertyType.INSTANCES, 2, "/{clusterName}/INSTANCES/{instanceName}");
88      addEntry(PropertyType.IDEALSTATES, 1, "/{clusterName}/IDEALSTATES");
89      addEntry(PropertyType.IDEALSTATES, 2, "/{clusterName}/IDEALSTATES/{resourceName}");
90      addEntry(PropertyType.EXTERNALVIEW, 1, "/{clusterName}/EXTERNALVIEW");
91      addEntry(PropertyType.EXTERNALVIEW, 2, "/{clusterName}/EXTERNALVIEW/{resourceName}");
92      addEntry(PropertyType.STATEMODELDEFS, 1, "/{clusterName}/STATEMODELDEFS");
93      addEntry(PropertyType.STATEMODELDEFS, 2, "/{clusterName}/STATEMODELDEFS/{stateModelName}");
94      addEntry(PropertyType.CONTROLLER, 1, "/{clusterName}/CONTROLLER");
95      addEntry(PropertyType.PROPERTYSTORE, 1, "/{clusterName}/PROPERTYSTORE");
96      addEntry(PropertyType.HELIX_PROPERTYSTORE, 1, "/{clusterName}/HELIX_PROPERTYSTORE");
97  
98      // INSTANCE
99      addEntry(PropertyType.MESSAGES, 2, "/{clusterName}/INSTANCES/{instanceName}/MESSAGES");
100     addEntry(PropertyType.MESSAGES, 3, "/{clusterName}/INSTANCES/{instanceName}/MESSAGES/{msgId}");
101     addEntry(PropertyType.CURRENTSTATES, 2, "/{clusterName}/INSTANCES/{instanceName}/CURRENTSTATES");
102     addEntry(PropertyType.CURRENTSTATES, 3,
103         "/{clusterName}/INSTANCES/{instanceName}/CURRENTSTATES/{sessionId}");
104     addEntry(PropertyType.CURRENTSTATES, 4,
105         "/{clusterName}/INSTANCES/{instanceName}/CURRENTSTATES/{sessionId}/{resourceName}");
106     addEntry(PropertyType.CURRENTSTATES, 5,
107         "/{clusterName}/INSTANCES/{instanceName}/CURRENTSTATES/{sessionId}/{resourceName}/{bucketName}");
108     addEntry(PropertyType.STATUSUPDATES, 2, "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES");
109     addEntry(PropertyType.STATUSUPDATES, 3,
110         "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES/{sessionId}");
111     addEntry(PropertyType.STATUSUPDATES, 4,
112         "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES/{sessionId}/{subPath}");
113     addEntry(PropertyType.STATUSUPDATES, 5,
114         "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES/{sessionId}/{subPath}/{recordName}");
115     addEntry(PropertyType.ERRORS, 2, "/{clusterName}/INSTANCES/{instanceName}/ERRORS");
116     addEntry(PropertyType.ERRORS, 3, "/{clusterName}/INSTANCES/{instanceName}/ERRORS/{sessionId}");
117     addEntry(PropertyType.ERRORS, 4,
118         "/{clusterName}/INSTANCES/{instanceName}/ERRORS/{sessionId}/{subPath}");
119     addEntry(PropertyType.ERRORS, 5,
120         "/{clusterName}/INSTANCES/{instanceName}/ERRORS/{sessionId}/{subPath}/{recordName}");
121     addEntry(PropertyType.HEALTHREPORT, 2, "/{clusterName}/INSTANCES/{instanceName}/HEALTHREPORT");
122     addEntry(PropertyType.HEALTHREPORT, 3,
123         "/{clusterName}/INSTANCES/{instanceName}/HEALTHREPORT/{reportName}");
124     // CONTROLLER
125     addEntry(PropertyType.MESSAGES_CONTROLLER, 1, "/{clusterName}/CONTROLLER/MESSAGES");
126     addEntry(PropertyType.MESSAGES_CONTROLLER, 2, "/{clusterName}/CONTROLLER/MESSAGES/{msgId}");
127     addEntry(PropertyType.ERRORS_CONTROLLER, 1, "/{clusterName}/CONTROLLER/ERRORS");
128     addEntry(PropertyType.ERRORS_CONTROLLER, 2, "/{clusterName}/CONTROLLER/ERRORS/{errorId}");
129     addEntry(PropertyType.STATUSUPDATES_CONTROLLER, 1, "/{clusterName}/CONTROLLER/STATUSUPDATES");
130     addEntry(PropertyType.STATUSUPDATES_CONTROLLER, 2,
131         "/{clusterName}/CONTROLLER/STATUSUPDATES/{subPath}");
132     addEntry(PropertyType.STATUSUPDATES_CONTROLLER, 3,
133         "/{clusterName}/CONTROLLER/STATUSUPDATES/{subPath}/{recordName}");
134     addEntry(PropertyType.LEADER, 1, "/{clusterName}/CONTROLLER/LEADER");
135     addEntry(PropertyType.HISTORY, 1, "/{clusterName}/CONTROLLER/HISTORY");
136     addEntry(PropertyType.PAUSE, 1, "/{clusterName}/CONTROLLER/PAUSE");
137     addEntry(PropertyType.PERSISTENTSTATS, 1, "/{clusterName}/CONTROLLER/PERSISTENTSTATS");
138     addEntry(PropertyType.ALERTS, 1, "/{clusterName}/CONTROLLER/ALERTS");
139     addEntry(PropertyType.ALERT_STATUS, 1, "/{clusterName}/CONTROLLER/ALERT_STATUS");
140     addEntry(PropertyType.ALERT_HISTORY, 1, "/{clusterName}/CONTROLLER/ALERT_HISTORY");
141     // @formatter:on
142 
143   }
144   static Pattern pattern = Pattern.compile("(\\{.+?\\})");
145 
146   private static void addEntry(PropertyType type, int numKeys, String template)
147   {
148     if (!templateMap.containsKey(type))
149     {
150       templateMap.put(type, new HashMap<Integer, String>());
151     }
152     logger.trace("Adding template for type:" + type.getType() + " arguments:" + numKeys
153         + " template:" + template);
154     templateMap.get(type).put(numKeys, template);
155   }
156 
157   public static String getPath(PropertyType type, String clusterName, String... keys)
158   {
159     if (clusterName == null)
160     {
161       logger.warn("ClusterName can't be null for type:" + type);
162       return null;
163     }
164     if (keys == null)
165     {
166       keys = new String[] {};
167     }
168     String template = null;
169     if (templateMap.containsKey(type))
170     {
171       // keys.length+1 since we add clusterName
172       template = templateMap.get(type).get(keys.length + 1);
173     }
174 
175     String result = null;
176 
177     if (template != null)
178     {
179       result = template;
180       Matcher matcher = pattern.matcher(template);
181       int count = 0;
182       while (matcher.find())
183       {
184         count = count + 1;
185         String var = matcher.group();
186         if (count == 1)
187         {
188           result = result.replace(var, clusterName);
189         } else
190         {
191           result = result.replace(var, keys[count - 2]);
192         }
193       }
194     }
195     if (result == null || result.indexOf('{') > -1 || result.indexOf('}') > -1)
196     {
197       logger.warn("Unable to instantiate template:" + template + " using clusterName:"
198           + clusterName + " and keys:" + Arrays.toString(keys));
199     }
200     return result;
201   }
202   public static String getInstanceNameFromPath(String path)
203   {
204     // path structure
205     // /<cluster_name>/instances/<instance_name>/[currentStates/messages]
206     if (path.contains("/" + PropertyType.INSTANCES + "/"))
207     {
208       String[] split = path.split("\\/");
209       if (split.length > 3)
210       {
211         return split[3];
212       }
213     }
214     return null;
215   }
216 }