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.qos.ResourceStatus.ResourceNode;
031: import org.cougaar.qos.qrs.AbstractContextInstantiater;
032: import org.cougaar.qos.qrs.ContextInstantiater;
033: import org.cougaar.qos.qrs.DataFormula;
034: import org.cougaar.qos.qrs.DataValue;
035: import org.cougaar.qos.qrs.RSS;
036: import org.cougaar.qos.qrs.ResourceContext;
037: import org.cougaar.util.log.Logger;
038: import org.cougaar.util.log.Logging;
039: import org.cougaar.core.qos.metrics.Constants;
040:
041: /**
042: * This RSS ResourceContext represents a remote Agent to which this Node is
043: * communicating. Its parent context in the RSS inheritance tree should be a
044: * Node ({@link NodeDS}). It's identified by the name of the destination
045: * Agent. It supports a range of messaging and ip-resource formulas, described
046: * in more detail elsewhere.
047: */
048: public class DestinationDS 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 DestinationDS(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("Destination", cinst);
066: }
067:
068: private static final String DESTINATION = "destination".intern();
069:
070: public DestinationDS(String[] parameters, ResourceContext parent)
071: throws ParameterError {
072: super (parameters, parent);
073: }
074:
075: protected void verifyParameters(String[] parameters)
076: throws ParameterError {
077: if (parameters == null || parameters.length != 1) {
078: throw new ParameterError(
079: "DestinationDS: wrong number of parameters");
080: }
081: if (!(parameters[0] != null)) {
082: throw new ParameterError(
083: "DestinationDS: wrong parameter type");
084: } else {
085: // could canonicalize here
086: String destination = parameters[0];
087: bindSymbolValue(DESTINATION, destination);
088: String node_name = (String) getValue(NodeDS.NODENAME);
089: historyPrefix = "Node" + KEY_SEPR + node_name + KEY_SEPR
090: + "Destination" + KEY_SEPR + destination;
091: }
092: }
093:
094: protected DataFormula instantiateFormula(String kind) {
095: if (kind.equals(Constants.MSG_FROM)
096: || kind.equals(Constants.BYTES_FROM)
097: || kind.equals(Constants.MSG_TO)
098: || kind.equals(Constants.BYTES_TO)) {
099: return new DecayingHistoryFormula(historyPrefix, kind);
100: } else if (kind.equals(Constants.PERSIST_SIZE_LAST)) {
101: return new PersistSizeLast();
102: } else if (kind.equals("AgentIpAddress")) {
103: return new AgentIpAddress();
104: } else if (kind.equals("CapacityMax")) {
105: return new CapacityMax();
106: } else if (kind.equals("OnSameSecureLAN")) {
107: return new OnSameSecureLAN();
108: } else {
109: return null;
110: }
111: }
112:
113: static class AgentIpAddress extends DataFormula {
114: protected void initialize(ResourceContext context) {
115: super .initialize(context);
116: String agent = (String) context.getValue(DESTINATION);
117: String[] parameters = { agent };
118: ResourceNode resource_node = new ResourceNode("Agent",
119: parameters);
120: ResourceNode[] path = { resource_node };
121: ResourceContext dependency = RSS.instance().getPathContext(
122: path);
123: registerDependency(dependency, "PrimaryIpAddress");
124: }
125:
126: public void formulaDeleted(DataFormula formula) {
127: super .formulaDeleted(formula);
128:
129: Logger logger = Logging
130: .getLogger("org.cougaar.core.qos.rss.DestinationDS");
131: if (logger.isDebugEnabled()) {
132: String agent = (String) getContext().getValue(
133: DESTINATION);
134: logger.debug("Formula " + formula + " deleted from "
135: + agent);
136: }
137:
138: }
139:
140: protected DataValue doCalculation(DataFormula.Values values) {
141: DataValue result = values.get("PrimaryIpAddress");
142: Logger logger = Logging
143: .getLogger("org.cougaar.core.qos.rss.DestinationDS");
144: if (logger.isDebugEnabled()) {
145: String agent = (String) getContext().getValue(
146: DESTINATION);
147: logger.debug("Recalculating Agent " + agent
148: + " AgentIpAddress as" + result);
149: }
150: return result;
151: }
152:
153: }
154:
155: static class CapacityMax extends DataFormula {
156: private static final DataValue UnknownCapacityMax = new DataValue(
157: 0, 0.0);
158:
159: protected void initialize(ResourceContext context) {
160: super .initialize(context);
161: // subscribe to our own IpAddress and NodeIpAddress
162: registerDependency(context, "AgentIpAddress");
163: registerDependency(context, "PrimaryIpAddress");
164: }
165:
166: protected DataValue doCalculation(DataFormula.Values values) {
167: DataValue result = null;
168: String agentAddr = null;
169: String myAddr = null;
170: try {
171: agentAddr = values.get("AgentIpAddress")
172: .getStringValue();
173: myAddr = values.get("PrimaryIpAddress")
174: .getStringValue();
175: } catch (Exception ex) {
176: // One of the dependencies is NO_VALUE
177: result = UnknownCapacityMax;
178: }
179: if (result != UnknownCapacityMax) {
180: if (NodeDS.isUnknownHost(agentAddr)
181: || NodeDS.isUnknownHost(myAddr)) {
182: result = UnknownCapacityMax;
183: } else {
184: String[] flow_params = { myAddr, agentAddr };
185: ResourceNode flow = new ResourceNode("IpFlow",
186: flow_params);
187: ResourceNode capm = new ResourceNode("CapacityMax",
188: null);
189: ResourceNode[] path = { flow, capm };
190: DataFormula cap_max = RSS.instance()
191: .getPathFormula(path);
192: result = cap_max.blockingQuery();
193: }
194: }
195:
196: Logger logger = Logging
197: .getLogger("org.cougaar.core.qos.rss.DestinationDS");
198: if (logger.isDebugEnabled()) {
199: logger.debug("Recalculating CapacityMax with"
200: + " my address = " + myAddr
201: + " dest address = " + agentAddr + " = "
202: + result);
203: }
204:
205: return result;
206: }
207:
208: }
209:
210: private static final double LAN_CAPACITY = 10000.0;
211:
212: static class OnSameSecureLAN extends DataFormula {
213: protected void initialize(ResourceContext context) {
214: super .initialize(context);
215: registerDependency(context, "CapacityMax");
216: }
217:
218: protected DataValue doCalculation(DataFormula.Values values) {
219: DataValue capacityMax = values.get("CapacityMax");
220: double capacityMaxValue = capacityMax.getDoubleValue();
221: double capacityMaxCred = capacityMax.getCredibility();
222:
223: DataValue results = new DataValue(
224: capacityMaxCred >= SYS_DEFAULT_CREDIBILITY
225: && capacityMaxValue >= LAN_CAPACITY,
226: capacityMaxCred);
227: Logger logger = Logging
228: .getLogger("org.cougaar.core.qos.rss.DestinationDS");
229: if (logger.isDebugEnabled()) {
230: String agent = (String) getContext().getValue(
231: DESTINATION);
232: logger.debug("Recalculating Agent " + agent
233: + " OnSameSecureLAN with" + " capacity max = "
234: + capacityMax + " results = " + results);
235: }
236: return results;
237: }
238:
239: }
240:
241: class PersistSizeLast extends DataFormula {
242:
243: protected DataValue defaultValue() {
244: return new DataValue(0);
245: }
246:
247: protected void initialize(ResourceContext ctx) {
248: super .initialize(ctx);
249: String key = historyPrefix + KEY_SEPR
250: + Constants.PERSIST_SIZE_LAST;
251: String[] parameters = { key };
252: ResourceNode node = new ResourceNode();
253: node.kind = "Integrater";
254: node.parameters = parameters;
255: ResourceNode formula = new ResourceNode();
256: formula.kind = "Formula";
257: formula.parameters = new String[0];
258: ResourceNode[] path = { node, formula };
259: DataFormula dependency = RSS.instance()
260: .getPathFormula(path);
261: registerDependency(dependency, "Formula");
262:
263: }
264:
265: protected DataValue doCalculation(DataFormula.Values values) {
266: DataValue computedValue = values.get("Formula");
267: DataValue defaultValue = defaultValue();
268: return DataValue.mostCredible(computedValue, defaultValue);
269: }
270:
271: }
272:
273: }
|