Source code: org/altara/mars/Service.java
1 /* MARS Network Monitoring Engine
2 Copyright (C) 1999 Brian H. Trammell
3 Copyright (C) 2002 Leapfrog Research & Development, LLC
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, it is available at
17 http:///www.gnu.org/copyleft/gpl.html, or by writing to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20 */
21
22 package org.altara.mars;
23
24 import java.util.*;
25 import org.jdom.*;
26 import javax.swing.tree.*;
27 import org.altara.mars.engine.*;
28
29 /** Represents a service on a host monitored by MARS. Each service
30 has a probe factory (which the service can use to build a probe
31 that knows how to monitor said service), a port on which the
32 service is running, a set of arguments to give to that factory's
33 create() method, and a representation of the current status
34 of that service.
35 */
36
37 public class Service implements java.io.Serializable, TreeNode {
38
39 public static final int NOTAC_NEVER = 0;
40 public static final int NOTAC_IMMEDIATE = 1;
41 public static final int DEFAULT_NOTAC = NOTAC_IMMEDIATE;
42 public static final int MAX_NOTAC = 3;
43
44 public static final long DEFAULT_PERIOD = 60000L; // 60 sec.
45 public static final long DEFAULT_TIMEOUT = 5000L; // 5 sec.
46
47 private Host host;
48 private String name;
49 private ProbeFactory factory;
50 private int port;
51 private HashMap params;
52 private Status status;
53 private long timeout;
54 private long period;
55 private int notac;
56
57 public Service (Host host, String name, String svctype, int port)
58 throws InvalidServiceTypeException {
59 this(host,name,svctype,port,DEFAULT_TIMEOUT,DEFAULT_PERIOD,
60 DEFAULT_NOTAC);
61 }
62
63 public Service (Host host, String name, String svctype,
64 int port, long timeout, long period, int notac)
65 throws InvalidServiceTypeException {
66 this(host,name,svctype,port,timeout,period,notac,new HashMap());
67 }
68
69 public Service (Host host, String name, String svctype,
70 int port, long timeout, long period, int notac, HashMap params)
71 throws InvalidServiceTypeException {
72 this.host = host;
73 this.name = name;
74 this.factory = ProbeFactory.getFactory(svctype);
75 if (factory == null) throw new InvalidServiceTypeException();
76 this.port = port;
77 this.params = params;
78 this.status = new Status(Status.UNKNOWN);
79 this.timeout = timeout;
80 this.period = period;
81 this.notac = notac;
82 host.addService(this);
83 }
84
85 public void setParameter(String name, String value) {
86 params.put(name,value);
87 }
88
89 public void setStatus(Status status) {
90 this.status = status;
91 }
92
93 public void setName(String name) {
94 this.name = name;
95 }
96
97 public void setSvcType(String svctype) throws InvalidServiceTypeException {
98 this.factory = ProbeFactory.getFactory(svctype);
99 if (factory == null) throw new InvalidServiceTypeException();
100 }
101
102 public void setPort(int port) {
103 this.port = port;
104 }
105
106 public void setTimeout(long timeout) {
107 this.timeout = timeout;
108 }
109
110 public void setPeriod(long period) {
111 this.period = period;
112 }
113
114 public void setNotac(int notac) {
115 this.notac = notac;
116 }
117
118 public void fireServiceChanged() {
119 host.getModel().serviceChanged(this);
120 }
121
122 public Host getHost() {
123 return host;
124 }
125
126 public int getPort() {
127 return port;
128 }
129
130 public String getName() {
131 return name;
132 }
133
134 public Probe getProbe() {
135 return factory.createProbe(this);
136 }
137
138 public String getSvcType() {
139 return factory.getName();
140 }
141
142 public ProbeFactory getProbeFactory() {
143 return factory;
144 }
145
146 public Status getStatus() {
147 return status;
148 }
149
150 public String getParameter(String name) {
151 return (String)params.get(name);
152 }
153
154 public Iterator getParameterNames() {
155 return params.keySet().iterator();
156 }
157
158 public long getTimeout() {
159 return timeout;
160 }
161
162 public long getPeriod() {
163 return period;
164 }
165
166 public int getNotac() {
167 return notac;
168 }
169
170 public boolean isDue() {
171 return System.currentTimeMillis() > status.getTimestamp() + period;
172 }
173
174 public String toString() {
175 return "Service "+name+
176 " ("+getSvcType()+"), port "+port+" on "+host.getName();
177 }
178
179 /*------------------------------------------------------------
180 TreeNode implementation
181 ------------------------------------------------------------*/
182
183 public boolean getAllowsChildren() {
184 return false;
185 }
186
187 public int getChildCount() {
188 return 0;
189 }
190
191 public boolean isLeaf() {
192 return true;
193 }
194
195 public TreeNode getParent() {
196 return host;
197 }
198
199 public Enumeration children() {
200 return null;
201 }
202
203 public TreeNode getChildAt(int childIndex) {
204 return null;
205 }
206
207 public int getIndex(TreeNode node) {
208 return -1;
209 }
210
211 public TreePath getTreePath() {
212 return new TreePath(host.getModel())
213 .pathByAddingChild(host)
214 .pathByAddingChild(this);
215 }
216
217 /*------------------------------------------------------------
218 Cloning
219 ------------------------------------------------------------*/
220
221 public Service duplicate(Host newHost) {
222 try {
223 return new Service(newHost, name, factory.getName(), port,
224 timeout, period, notac, (HashMap)params.clone());
225 } catch (InvalidServiceTypeException ignored) {
226 // can never happen
227 return null;
228 }
229 }
230
231 /*------------------------------------------------------------
232 XML parsing/generation methods
233 ------------------------------------------------------------*/
234
235 public Element toJDOMElem(boolean includeStatus) {
236 Element servelem = new Element("service", MarsModel.NAMESPACE);
237 servelem.setAttribute("name",getName());
238 servelem.setAttribute("port",String.valueOf(getPort()));
239 servelem.setAttribute("svctype",getSvcType());
240 servelem.setAttribute("timeout",String.valueOf(getTimeout()));
241 servelem.setAttribute("period",String.valueOf(getPeriod()));
242 servelem.setAttribute("notac",String.valueOf(getNotac()));
243 // get all the parameters for this service
244 Iterator svcparamNames = getParameterNames();
245 while (svcparamNames.hasNext()) {
246 String paramName = (String)svcparamNames.next();
247 String paramValue = getParameter(paramName);
248 // create an element for this service parameter
249 Element svcparamelem =
250 new Element("parameter", MarsModel.NAMESPACE);
251 svcparamelem.setAttribute("name",paramName);
252 svcparamelem.addContent(paramValue);
253 servelem.addContent(svcparamelem);
254 }
255 // if we're storing status too, do so now
256 if (includeStatus) {
257 Status status = getStatus();
258 Element statelem = status.toJDOMElem();
259 servelem.addContent(statelem);
260 }
261 return servelem;
262 }
263
264 public static Service fromJDOMElem(Host host, Element in)
265 throws InvalidDocumentException {
266 // get service information from attributes
267 String svcName = in.getAttributeValue("name");
268 if (svcName == null)
269 throw new InvalidDocumentException("Missing service name");
270 String svcType = in.getAttributeValue("svctype");
271 if (svcType == null)
272 throw new InvalidDocumentException("Missing service type");
273 String portStr = in.getAttributeValue("port");
274 int port = -1;
275 String timeoutStr = in.getAttributeValue("timeout");
276 long timeout = -1;
277 String periodStr = in.getAttributeValue("period");
278 long period = -1;
279 String notacStr = in.getAttributeValue("notac");
280 int notac = -1;
281 try {
282 port = Integer.parseInt(portStr);
283 } catch (Exception ex) {
284 throw new InvalidDocumentException(
285 "Bad or missing service port");
286 }
287 try {
288 timeout = Long.parseLong(timeoutStr);
289 if (timeout < 0) throw new Exception();
290 } catch (Exception ex) {
291 throw new InvalidDocumentException(
292 "Bad or missing service timeout");
293 }
294 try {
295 period = Long.parseLong(periodStr);
296 if (period < 0) throw new Exception();
297 } catch (Exception ex) {
298 throw new InvalidDocumentException(
299 "Bad or missing service period");
300 }
301 // null isn't an error on notac - for backward compatibility
302 if (notacStr == null) {
303 notac = DEFAULT_NOTAC;
304 } else {
305 try {
306 notac = Integer.parseInt(notacStr);
307 if (notac > MAX_NOTAC) throw new Exception();
308 if (notac < 0) throw new Exception();
309 } catch (Exception ex) {
310 throw new InvalidDocumentException(
311 "Bad service notification attempt count");
312 }
313 }
314 // okay. everything's there. try creating the service.
315 Service out = null;
316 try {
317 out = new Service(host,svcName,svcType,port,timeout,period,notac);
318 } catch (InvalidServiceTypeException ex) {
319 throw new InvalidDocumentException("Bad service type");
320 }
321 // add any parameters the service has
322 Iterator paramElems =
323 in.getChildren("parameter",MarsModel.NAMESPACE).iterator();
324 while (paramElems.hasNext()) {
325 Element thisParamElem = (Element)paramElems.next();
326 String paramName = thisParamElem.getAttributeValue("name");
327 if (paramName == null)
328 throw new InvalidDocumentException("Missing parameter name");
329 String paramValue = thisParamElem.getText();
330 if (paramValue == null)
331 throw new InvalidDocumentException("Missing parameter value");
332 out.setParameter(paramName,paramValue);
333 }
334 // add status information if it exists
335 Element statusElem = in.getChild("status", MarsModel.NAMESPACE);
336 if (statusElem != null) {
337 out.setStatus(Status.fromJDOMElem(statusElem));
338 }
339 // done building this service, return it
340 return out;
341 }
342 }