1 package org.apache.helix.alerts;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.LinkedList;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.helix.HelixDataAccessor;
29 import org.apache.helix.HelixException;
30 import org.apache.helix.HelixManager;
31 import org.apache.helix.HelixProperty;
32 import org.apache.helix.PropertyKey;
33 import org.apache.helix.PropertyType;
34 import org.apache.helix.ZNRecord;
35 import org.apache.helix.PropertyKey.Builder;
36 import org.apache.helix.controller.stages.HealthDataCache;
37 import org.apache.helix.model.AlertStatus;
38 import org.apache.helix.model.Alerts;
39 import org.apache.log4j.Logger;
40
41
42 public class AlertsHolder {
43
44 private static final Logger logger = Logger
45 .getLogger(AlertsHolder.class.getName());
46
47 HelixDataAccessor _accessor;
48 HealthDataCache _cache;
49 Map<String, Map<String,String>> _alertsMap;
50 Map<String, Map<String,String>> _alertStatusMap;
51
52 HashSet<String> alerts;
53 StatsHolder _statsHolder;
54
55 private final HelixManager _manager;
56
57 private Builder _keyBuilder;
58
59 public AlertsHolder(HelixManager manager, HealthDataCache cache)
60 {
61 this(manager, cache, new StatsHolder(manager, cache));
62 }
63
64 public AlertsHolder(HelixManager manager, HealthDataCache cache, StatsHolder statHolder)
65 {
66 _manager = manager;
67 _accessor = manager.getHelixDataAccessor();
68 _cache = cache;
69 _statsHolder = statHolder;
70 _keyBuilder = new PropertyKey.Builder(_manager.getClusterName());
71 updateCache(_cache);
72 }
73
74 public void refreshAlerts()
75 {
76 _cache.refresh(_accessor);
77 updateCache(_cache);
78
79
80
81
82
83
84
85
86 }
87
88 public void refreshAlertStatus()
89 {
90 AlertStatus alertStatusRecord = _cache.getAlertStatus();
91 if (alertStatusRecord != null) {
92 _alertStatusMap = alertStatusRecord.getMapFields();
93 }
94 else {
95 _alertStatusMap = new HashMap<String, Map<String,String>>();
96 }
97 }
98
99 public void persistAlerts()
100 {
101
102
103 Alerts alerts = _accessor.getProperty(_keyBuilder.alerts());
104 if (alerts == null) {
105 alerts = new Alerts(Alerts.nodeName);
106 }
107 alerts.getRecord().setMapFields(_alertsMap);
108 boolean retVal = _accessor.setProperty(_keyBuilder.alerts(), alerts);
109 logger.debug("persistAlerts retVal: "+retVal);
110 }
111
112 public void persistAlertStatus()
113 {
114
115 AlertStatus alertStatus = _accessor.getProperty(_keyBuilder.alertStatus());
116 if (alertStatus == null) {
117 alertStatus = new AlertStatus(AlertStatus.nodeName);
118 }
119 alertStatus.getRecord().setMapFields(_alertStatusMap);
120 boolean retVal = _accessor.setProperty(_keyBuilder.alertStatus(), alertStatus);
121 logger.debug("persistAlerts retVal: "+retVal);
122 }
123
124
125 private void readExistingAlerts()
126 {
127
128 }
129
130 public void addAlert(String alert) throws HelixException
131 {
132 alert = alert.replaceAll("\\s+", "");
133 AlertParser.validateAlert(alert);
134 refreshAlerts();
135
136 Map<String, String> alertFields = new HashMap<String,String>();
137 alertFields.put(AlertParser.EXPRESSION_NAME,
138 AlertParser.getComponent(AlertParser.EXPRESSION_NAME, alert));
139 alertFields.put(AlertParser.COMPARATOR_NAME,
140 AlertParser.getComponent(AlertParser.COMPARATOR_NAME, alert));
141 alertFields.put(AlertParser.CONSTANT_NAME,
142 AlertParser.getComponent(AlertParser.CONSTANT_NAME, alert));
143 try
144 {
145 alertFields.put(AlertParser.ACTION_NAME,
146 AlertParser.getComponent(AlertParser.ACTION_NAME, alert));
147 }
148 catch(Exception e)
149 {
150 logger.info("No action specified in " + alert);
151 }
152
153 _statsHolder.addStat(alertFields.get(AlertParser.EXPRESSION_NAME));
154 _statsHolder.persistStats();
155
156
157 _alertsMap.put(alert, alertFields);
158 persistAlerts();
159 }
160
161
162
163
164 public void addAlertStatusSet(Map<String, Map<String, AlertValueAndStatus>> statusSet) throws HelixException
165 {
166 if (_alertStatusMap == null) {
167 _alertStatusMap = new HashMap<String, Map<String,String>>();
168 }
169 _alertStatusMap.clear();
170 for (String alert : statusSet.keySet()) {
171 Map<String,AlertValueAndStatus> currStatus = statusSet.get(alert);
172 if (currStatus != null) {
173 addAlertStatus(alert, currStatus);
174 }
175 }
176
177 AlertStatus alertStatus = _accessor.getProperty(_keyBuilder.alertStatus());
178 int alertStatusSize = 0;
179 if (alertStatus != null) {
180 alertStatusSize = alertStatus.getMapFields().size();
181 }
182
183 if (_alertStatusMap.size() > 0 || alertStatusSize > 0) {
184 persistAlertStatus();
185 }
186 }
187
188 private void addAlertStatus(String parentAlertKey, Map<String,AlertValueAndStatus> alertStatus) throws HelixException
189 {
190
191 for (String alertName : alertStatus.keySet()) {
192 String mapAlertKey;
193 mapAlertKey = parentAlertKey;
194 if (!alertName.equals(ExpressionParser.wildcardChar)) {
195 mapAlertKey = mapAlertKey+" : ("+alertName+")";
196 }
197 AlertValueAndStatus vs = alertStatus.get(alertName);
198 Map<String,String> alertFields = new HashMap<String,String>();
199 alertFields.put(AlertValueAndStatus.VALUE_NAME, vs.getValue().toString());
200 alertFields.put(AlertValueAndStatus.FIRED_NAME, String.valueOf(vs.isFired()));
201 _alertStatusMap.put(mapAlertKey, alertFields);
202 }
203 }
204
205 public AlertValueAndStatus getAlertValueAndStatus(String alertName)
206 {
207 Map<String,String> alertFields = _alertStatusMap.get(alertName);
208 String val = alertFields.get(AlertValueAndStatus.VALUE_NAME);
209 Tuple<String> valTup = new Tuple<String>();
210 valTup.add(val);
211 boolean fired = Boolean.valueOf(alertFields.get(AlertValueAndStatus.FIRED_NAME));
212 AlertValueAndStatus vs = new AlertValueAndStatus(valTup, fired);
213 return vs;
214 }
215
216 public static void parseAlert(String alert, StringBuilder statsName,
217 Map<String,String> alertFields) throws HelixException
218 {
219 alert = alert.replaceAll("\\s+", "");
220 AlertParser.validateAlert(alert);
221
222 alertFields.put(AlertParser.EXPRESSION_NAME,
223 AlertParser.getComponent(AlertParser.EXPRESSION_NAME, alert));
224 alertFields.put(AlertParser.COMPARATOR_NAME,
225 AlertParser.getComponent(AlertParser.COMPARATOR_NAME, alert));
226 alertFields.put(AlertParser.CONSTANT_NAME,
227 AlertParser.getComponent(AlertParser.CONSTANT_NAME, alert));
228 try
229 {
230 alertFields.put(AlertParser.ACTION_NAME,
231 AlertParser.getComponent(AlertParser.ACTION_NAME, alert));
232 }
233 catch(Exception e)
234 {
235 logger.info("No action specified in " + alert);
236 }
237 statsName.append(alertFields.get(AlertParser.EXPRESSION_NAME));
238 }
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256 public List<Alert> getAlertList()
257 {
258 List<Alert> alerts = new LinkedList<Alert>();
259 for (String alert : _alertsMap.keySet()) {
260 Map<String,String> alertFields = _alertsMap.get(alert);
261 String exp = alertFields.get(AlertParser.EXPRESSION_NAME);
262 String comp = alertFields.get(AlertParser.COMPARATOR_NAME);
263 Tuple<String> con = Tuple.fromString(alertFields.get(AlertParser.CONSTANT_NAME));
264
265
266 Alert a = new Alert(alert, exp, comp, con);
267 alerts.add(a);
268 }
269 return alerts;
270 }
271
272 public void updateCache(HealthDataCache cache)
273 {
274 _cache = cache;
275 Alerts alertsRecord = _cache.getAlerts();
276 if (alertsRecord != null)
277 {
278 _alertsMap = alertsRecord.getMapFields();
279 }
280 else
281 {
282 _alertsMap = new HashMap<String, Map<String,String>>();
283 }
284 }
285
286 public Map<String, Map<String,String>> getAlertsMap()
287 {
288 return _alertsMap;
289 }
290 }