001: /*
002:
003: * <copyright>
004: *
005: * Copyright 2002-2007 BBNT Solutions, LLC
006: * under sponsorship of the Defense Advanced Research Projects
007: * Agency (DARPA).
008: *
009: * You can redistribute this software and/or modify it under the
010: * terms of the Cougaar Open Source License as published on the
011: * Cougaar Open Source Website (www.cougaar.org).
012: *
013: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
014: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
015: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
016: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
017: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
018: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
019: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
020: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
021: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
022: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
023: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
024: *
025: * </copyright>
026:
027: */
028:
029: package org.cougaar.qos.qrs;
030:
031: import java.net.InetAddress;
032:
033: import org.cougaar.util.log.Logger;
034:
035: /**
036: * A sample ResourceContext which looks for Host capacity data on any feed, by
037: * using a Remos-style key with an IntegraterDS. The available formulas are
038: * 'CapacityMax' and 'CapacityUnused'.
039: */
040: public class HostDS extends ResourceContext implements Constants {
041: static void register() {
042: ContextInstantiater cinst = new AbstractContextInstantiater() {
043: public ResourceContext instantiateContext(
044: String[] parameters, ResourceContext parent)
045: throws ResourceContext.ParameterError {
046: return new HostDS(parameters, parent);
047: }
048:
049: public Object identifyParameters(String[] parameters) {
050: if (parameters == null || parameters.length != 1) {
051: return null;
052: }
053: String x = parameters[0];
054: String result;
055: try {
056: result = InetAddress.getByName(x).getHostAddress();
057: } catch (java.net.UnknownHostException ex) {
058: result = x;
059: }
060: return result.intern();
061: }
062:
063: };
064: registerContextInstantiater("Host", cinst);
065: }
066:
067: private static final String IPADDRESS = "ipAddress";
068:
069: // Host ResourceContexts can be the first element in a path. They have
070: // no parent or context other than the root.
071: protected ResourceContext preferredParent(RSS root) {
072: return root;
073: }
074:
075: protected DataFormula instantiateFormula(String kind) {
076: if (kind.equals("PrimaryIpAddress")) {
077: return new PrimaryIpAddress();
078: } else if (kind.equals("PollingLoadAverage")) {
079: return new PollingLoadAverage();
080: } else if (kind.equals("LoadAverage")) {
081: return new LoadAverage();
082: } else if (kind.equals("BogoMips")) {
083: return new BogoMips();
084: } else if (kind.equals("Jips")) {
085: return new Jips();
086: } else if (kind.equals("Cache")) {
087: return new Cache();
088: } else if (kind.equals("Count")) {
089: return new Count();
090: } else if (kind.equals("FreeMemory")) {
091: return new FreeMemory();
092: } else if (kind.equals("TotalMemory")) {
093: return new TotalMemory();
094: } else if (kind.equals("MemoryUtilization")) {
095: return new MemoryUtilization();
096: } else if (kind.equals("TcpInUse")) {
097: return new TcpInUse();
098: } else if (kind.equals("UdpInUse")) {
099: return new UdpInUse();
100: } else if (kind.equals("MeanTimeBetweenFailure")) {
101: return new MeanTimeBetweenFailure();
102: } else if (kind.equals("EffectiveMJips")) {
103: return new EffectiveMJips();
104: } else if (kind.equals("IsReachable")) {
105: return new IsReachable();
106: } else if (kind.equals("RawGPS")) {
107: return new RawGPS();
108: } else if (kind.equals("Position")) {
109: return new Position();
110: } else if (kind.equals("ClockSpeed")) {
111: return new ClockSpeed();
112: } else {
113: return null;
114: }
115: }
116:
117: /**
118: * The parameters should contain one string, the address of the host being
119: * monitored.
120: */
121: protected void verifyParameters(String[] parameters)
122: throws ParameterError {
123: if (parameters == null || parameters.length != 1) {
124: throw new ParameterError(
125: "HostDS: wrong number of parameters");
126: } else {
127: // could canonicalize here
128: String addr = parameters[0];
129: try {
130: String ipAddress = InetAddress.getByName(addr)
131: .getHostAddress();
132: bindSymbolValue(IPADDRESS, ipAddress);
133: } catch (java.net.UnknownHostException unknown_host) {
134: Logger logger = Logging.getLogger(HostDS.class);
135: logger.error("Couldn't resolve hostname " + addr);
136: bindSymbolValue(IPADDRESS, addr);
137: }
138:
139: }
140:
141: }
142:
143: private DataValue ipAddrValue;
144:
145: private HostDS(String[] parameters, ResourceContext parent)
146: throws ParameterError {
147: super (parameters, parent);
148: }
149:
150: public String toString() {
151: String ipAddr = (String) getValue(IPADDRESS);
152: return "<HostDS " + ipAddr + ">";
153: }
154:
155: private synchronized DataValue getIpAddressValue() {
156: if (ipAddrValue == null) {
157: String addr = (String) getValue(IPADDRESS);
158: ipAddrValue = new DataValue(addr, SECOND_MEAS_CREDIBILITY);
159: }
160: return ipAddrValue;
161: }
162:
163: public class PrimaryIpAddress extends DataFormula {
164: protected DataValue doCalculation(DataFormula.Values values) {
165: // no dependencies, just ask our scope
166: return getIpAddressValue();
167: }
168:
169: }
170:
171: abstract static class Formula extends DataFormula implements
172: Constants {
173:
174: abstract String getKey();
175:
176: abstract DataValue defaultValue();
177:
178: protected void initialize(ResourceContext context) {
179: super .initialize(context);
180: String ipAddr = (String) context.getValue(IPADDRESS);
181: // Canonicalize ipAddr here
182: String key = "Host" + KEY_SEPR + ipAddr + KEY_SEPR
183: + getKey();
184: String[] parameters = { key };
185: ResourceContext dependency = RSS.instance().resolveSpec(
186: "Integrater", parameters);
187: registerDependency(dependency, "Formula");
188: }
189:
190: protected DataValue doCalculation(DataFormula.Values values) {
191: DataValue defaultValue = defaultValue();
192: DataValue computedValue = values.get("Formula");
193: return DataValue.mostCredible(computedValue, defaultValue);
194: }
195:
196: }
197:
198: public static class PollingLoadAverage extends
199: SingleKeyPollingIntegral {
200:
201: protected String getKey() {
202: String ipAddr = (String) getContext().getValue(IPADDRESS);
203: return "Host" + KEY_SEPR + ipAddr + KEY_SEPR + "CPU"
204: + KEY_SEPR + "loadavg";
205: // return "CPU" + KEY_SEPR + "loadavg" ;
206: }
207:
208: private static final String[] DefaultArgs = { "60000" }; // 1 min
209:
210: protected boolean hasArgs(String[] args) {
211: if (args == null || args.length == 0) {
212: return super .hasArgs(DefaultArgs);
213: } else {
214: return super .hasArgs(args);
215: }
216: }
217:
218: protected void setArgs(String[] args) {
219: if (args == null || args.length == 0) {
220: super .setArgs(DefaultArgs);
221: } else {
222: super .setArgs(args);
223: }
224: }
225:
226: // Not used by SingleKeyPollingIntegral
227: DataValue defaultValue() {
228: return new DataValue(0);
229: }
230: }
231:
232: public static class LoadAverage extends Formula {
233: String getKey() {
234: return "CPU" + KEY_SEPR + "loadavg";
235: }
236:
237: DataValue defaultValue() {
238: return new DataValue(0.01);
239: }
240: }
241:
242: public static class BogoMips extends Formula {
243: String getKey() {
244: return "CPU" + KEY_SEPR + "bogomips";
245: }
246:
247: DataValue defaultValue() {
248: return new DataValue(400);
249: }
250: }
251:
252: public static class Jips extends Formula {
253: String getKey() {
254: return "CPU" + KEY_SEPR + "Jips";
255: }
256:
257: DataValue defaultValue() {
258: return new DataValue(10.0E6);
259: }
260: }
261:
262: public static class Cache extends Formula {
263: String getKey() {
264: return "CPU" + KEY_SEPR + "cache";
265: }
266:
267: DataValue defaultValue() {
268: return new DataValue(0);
269: }
270: }
271:
272: public static class Count extends Formula {
273: String getKey() {
274: return "CPU" + KEY_SEPR + "count";
275: }
276:
277: DataValue defaultValue() {
278: return new DataValue(1);
279: }
280: }
281:
282: public static class FreeMemory extends Formula {
283: String getKey() {
284: return "Memory" + KEY_SEPR + "Physical" + KEY_SEPR + "Free";
285: }
286:
287: DataValue defaultValue() {
288: return new DataValue(64000);
289: }
290: }
291:
292: public static class TotalMemory extends Formula {
293: String getKey() {
294: return "Memory" + KEY_SEPR + "Physical" + KEY_SEPR
295: + "Total";
296: }
297:
298: DataValue defaultValue() {
299: return new DataValue(128000);
300: }
301: }
302:
303: public static class MemoryUtilization extends Formula {
304: String getKey() {
305: return "Memory" + KEY_SEPR + "Physical" + KEY_SEPR
306: + "Utilization";
307: }
308:
309: DataValue defaultValue() {
310: return new DataValue(0.0);
311: }
312: }
313:
314: public static class TcpInUse extends Formula {
315: String getKey() {
316: return "Network" + KEY_SEPR + "TCP" + KEY_SEPR + "sockets"
317: + KEY_SEPR + "inuse";
318: }
319:
320: DataValue defaultValue() {
321: return new DataValue(0);
322: }
323: }
324:
325: public static class UdpInUse extends Formula {
326: String getKey() {
327: return "Network" + KEY_SEPR + "UDP" + KEY_SEPR + "sockets"
328: + KEY_SEPR + "inuse";
329: }
330:
331: DataValue defaultValue() {
332: return new DataValue(0);
333: }
334: }
335:
336: public static class MeanTimeBetweenFailure extends Formula {
337: String getKey() {
338: return "CPU" + KEY_SEPR + "MeanTimeBetweenFailure";
339: }
340:
341: DataValue defaultValue() {
342: return new DataValue(8760.0, DEFAULT_CREDIBILITY, "hours",
343: "LinuxLiterature");
344: }
345: }
346:
347: public static class ClockSpeed extends Formula {
348: String getKey() {
349: return "CPU" + KEY_SEPR + "clockspeed";
350: }
351:
352: DataValue defaultValue() {
353: return new DataValue(100.0, NO_CREDIBILITY, "MHz", "Random");
354: }
355: }
356:
357: public static class EffectiveMJips extends DataFormula {
358:
359: protected void initialize(ResourceContext context) {
360: super .initialize(context);
361: registerDependency(context, "LoadAverage");
362: registerDependency(context, "Jips");
363: registerDependency(context, "Count");
364: }
365:
366: protected DataValue doCalculation(DataFormula.Values values) {
367: double lavg = values.doubleValue("LoadAverage");
368: double mjips = values.doubleValue("Jips") / 1.0E6;
369: double cpus = values.doubleValue("Count");
370:
371: double credibility = values.minCredibility();
372: if (mjips <= 0) {
373: mjips = 400;
374: credibility = DEFAULT_CREDIBILITY;
375: }
376: if (cpus <= 0) {
377: cpus = 1;
378: credibility = DEFAULT_CREDIBILITY;
379: }
380:
381: double effectiveMJips =
382: // JAZ LoadAverage for Linux is a hard metric to model
383: // If the Object is not greedy, it sneeks in and get
384: // normal latency regardless of the loadaverage.
385: // If the Object is greedy, its latancy is multiplied by
386: // the loadaverage which includes itself.
387: // The number of cpu reduces the load average
388: mjips / // Million Java Inst Per Sec
389: Math.max(1, (lavg / cpus));
390:
391: return new DataValue(effectiveMJips, credibility);
392: }
393:
394: }
395:
396: public static class IsReachable extends DataFormula implements
397: Constants {
398:
399: private static final DataValue defaultValue = new DataValue(
400: false, DEFAULT_CREDIBILITY);
401:
402: protected void initialize(ResourceContext context) {
403: super .initialize(context);
404: // The IP address of this Host
405: String remoteIpAddr = (String) context.getValue(IPADDRESS);
406: // The IP address of the host that RSS is running on
407: String localIpAddr = CorbaUtils.hostaddr();
408: // Canonicalize ipAddr here
409: String key = "Ip" + KEY_SEPR + "Flow" + KEY_SEPR
410: + localIpAddr + KEY_SEPR + remoteIpAddr + KEY_SEPR +
411: // JAZ TOS bits hard wired to 1 for now
412: "1" + KEY_SEPR + "PathCost-Hops";
413: String[] parameters = { key };
414: ResourceContext hops = RSS.instance().resolveSpec(
415: "Integrater", parameters);
416: registerDependency(hops, "Formula");
417: }
418:
419: protected DataValue doCalculation(DataFormula.Values values) {
420: DataValue hops = values.get("Formula");
421: if (hops.getCredibility() >= DEFAULT_CREDIBILITY) {
422: if (hops.getDoubleValue() >= 0.0) {
423: return new DataValue(true, hops.getCredibility(),
424: "up/down", hops.getProvenance());
425: } else {
426: return new DataValue(false, hops.getCredibility(),
427: "up/down", hops.getProvenance());
428: }
429: } else {
430: return defaultValue;
431: }
432: }
433:
434: }
435:
436: public static class RawGPS extends Formula {
437: String getKey() {
438: return "GPS";
439: }
440:
441: DataValue defaultValue() {
442: return new DataValue("none", NO_CREDIBILITY);
443: }
444: }
445:
446: public static class Position extends DataFormula {
447:
448: protected void initialize(ResourceContext context) {
449: super .initialize(context);
450: registerDependency(context, "RawGPS");
451: registerDependency(context, "IsReachable");
452: }
453:
454: protected DataValue doCalculation(DataFormula.Values values) {
455: DataValue rawGPS = values.get("RawGPS");
456: DataValue isReachable = values.get("IsReachable");
457:
458: if (rawGPS.getCredibility() > NO_CREDIBILITY) {
459: // GPS should have a real position
460: if (isReachable.getBooleanValue()) {
461: // The position is uptodate
462: return new DataValue(rawGPS);
463: } else {
464: // the position is stale
465: return new DataValue(rawGPS.getStringValue(),
466: HOURLY_MEAS_CREDIBILITY, rawGPS.getUnits(),
467: rawGPS.getProvenance());
468: }
469: } else {
470: // no real real position
471: return new DataValue("none", NO_CREDIBILITY);
472: }
473:
474: }
475: }
476: }
|