001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: // Later this will move elsewhere...
028: package org.cougaar.core.qos.rss;
029:
030: import org.cougaar.core.component.ServiceBroker;
031: import org.cougaar.core.service.wp.AddressEntry;
032: import org.cougaar.core.mts.MessageAddress;
033: import org.cougaar.core.qos.metrics.Constants;
034: import org.cougaar.core.service.wp.WhitePagesService;
035: import org.cougaar.qos.ResourceStatus.ResourceNode;
036: import org.cougaar.qos.qrs.AbstractContextInstantiater;
037: import org.cougaar.qos.qrs.ContextInstantiater;
038: import org.cougaar.qos.qrs.DataFormula;
039: import org.cougaar.qos.qrs.DataValue;
040: import org.cougaar.qos.qrs.RSS;
041: import org.cougaar.qos.qrs.ResourceContext;
042:
043: /**
044: * This RSS ResourceContext represents a COUGGAR Node. Its parent in the RSS
045: * hierarchy tree is the context for the Node's host. It's identified by the
046: * Node's name and has no locally defined formulas.
047: */
048: public class NodeDS extends CougaarDS {
049: static void register() {
050: ContextInstantiater cinst = new AbstractContextInstantiater() {
051: public ResourceContext instantiateContext(
052: String[] parameters, ResourceContext parent)
053: throws ParameterError {
054: return new NodeDS(parameters, parent);
055: }
056:
057: public Object identifyParameters(String[] parameters) {
058: if (parameters == null || parameters.length != 1) {
059: return null;
060: }
061: return parameters[0];
062: }
063:
064: };
065: registerContextInstantiater("Node", cinst);
066: }
067:
068: static final String NODENAME = "nodename".intern();
069: static final String TOPOLOGY = "topology";
070: static final String UNKNOWN_HOST_IP = "169.0.0.1";// DHCP No Address from
071: // server
072:
073: private DataFormula vm_size;
074:
075: static boolean isUnknownHost(String addr) {
076: return addr.equals(UNKNOWN_HOST_IP);
077: }
078:
079: public NodeDS(String[] parameters, ResourceContext parent)
080: throws ParameterError {
081: super (parameters, parent);
082: }
083:
084: protected boolean useParentPath() {
085: return false;
086: }
087:
088: String getNodeName() {
089: return (String) getSymbolValue(NODENAME);
090: }
091:
092: // Node DataScopes can be the first element in a path. They must
093: // find or make the corresponding HostDS and return that as the
094: // preferred parent.
095: protected ResourceContext preferredParent(RSS root) {
096:
097: ServiceBroker sb = (ServiceBroker) root
098: .getProperty("ServiceBroker");
099: AgentTopologyService ats = sb.getService(this ,
100: AgentTopologyService.class, null);
101: String nodename = (String) getSymbolValue(NODENAME);
102: String hostname = null;
103: if (ats != null) {
104: hostname = ats.getNodeHost(MessageAddress
105: .getMessageAddress(nodename));
106: } else {
107: // AgentTopologyService not loaded. Try a direct WP
108: // call, even though it can give an inconsistent picture.
109: WhitePagesService svc = sb.getService(this ,
110: WhitePagesService.class, null);
111: try {
112: AddressEntry entry = svc.get(nodename, TOPOLOGY, -1);
113: if (entry == null) {
114: if (logger.isWarnEnabled()) {
115: logger.warn("Can't find host for node "
116: + nodename);
117: }
118: } else {
119: hostname = entry.getURI().getHost();
120: }
121: } catch (Exception ex) {
122: // log this?
123: }
124: }
125:
126: String[] params = { hostname == null ? UNKNOWN_HOST_IP
127: : hostname };
128: ResourceNode node = new ResourceNode();
129: node.kind = "Host";
130: node.parameters = params;
131: ResourceNode[] path = { node };
132: ResourceContext parent = root.getPathContext(path);
133: setParent(parent);
134: return parent;
135: }
136:
137: protected void verifyParameters(String[] parameters)
138: throws ParameterError {
139: if (parameters == null || parameters.length != 1) {
140: throw new ParameterError(
141: "NodeDS: wrong number of parameters");
142: }
143: if (!(parameters[0] != null)) {
144: throw new ParameterError("NodeDS: wrong parameter type");
145: } else {
146: // could canonicalize here
147: String nodename = parameters[0];
148: bindSymbolValue(NODENAME, nodename);
149: historyPrefix = "Node" + KEY_SEPR + nodename;
150: }
151: }
152:
153: protected DataFormula instantiateFormula(String kind) {
154: if (kind.equals(Constants.CPU_LOAD_AVG)
155: || kind.equals(Constants.CPU_LOAD_MJIPS)
156: || kind.equals(Constants.MSG_IN)
157: || kind.equals(Constants.BYTES_IN)
158: || kind.equals(Constants.MSG_OUT)
159: || kind.equals(Constants.BYTES_OUT)) {
160: return new DecayingHistoryFormula(historyPrefix, kind);
161: } else if (kind.equals("VMSize")) {
162: // singleton
163: return findOrMakeVMSizeFormula();
164: } else {
165: // No local formulas
166: return null;
167: }
168: }
169:
170: private synchronized DataFormula findOrMakeVMSizeFormula() {
171: if (vm_size == null) {
172: vm_size = new VMSize();
173: }
174: return vm_size;
175: }
176:
177: private class VMSize extends DataFormula {
178: Runtime rt;
179:
180: protected DataValue defaultValue() {
181: return DataValue.NO_VALUE;
182: }
183:
184: protected void initialize(ResourceContext context) {
185: super .initialize(context);
186:
187: rt = Runtime.getRuntime();
188: ResourceNode node = new ResourceNode();
189: node.kind = "Alarm";
190: node.parameters = new String[0];
191: ResourceNode formula = new ResourceNode();
192: formula.kind = "FifteenSeconds";
193: formula.parameters = new String[0];
194: ResourceNode[] path = { node, formula };
195: DataFormula alarm = RSS.instance().getPathFormula(path);
196: registerDependency(alarm, "Alarm");
197: }
198:
199: protected DataValue doCalculation(DataFormula.Values vals) {
200: long total = rt.totalMemory(); // code size? never
201: // changes in Linux
202: if (logger.isDebugEnabled()) {
203: long free = rt.freeMemory();
204: long max = rt.maxMemory();
205: logger.debug(" totalMemory=" + total + " maxMemory="
206: + max + " freeMemory=" + free);
207: }
208: return new DataValue(total,
209: Constants.SECOND_MEAS_CREDIBILITY, "bytes",
210: "Runtime.getRuntime().totalMemory()");
211: }
212:
213: }
214: }
|