001: /*
002: * <copyright>
003: *
004: * Copyright 2002-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: package org.cougaar.tools.csmart.ui.servlet;
028:
029: import org.cougaar.core.servlet.SimpleServletSupport;
030: import org.cougaar.core.util.UID;
031: import org.cougaar.planning.ldm.plan.AllocationResult;
032: import org.cougaar.planning.ldm.plan.PlanElement;
033: import org.cougaar.planning.ldm.plan.Task;
034: import org.cougaar.util.UnaryPredicate;
035: import org.cougaar.util.log.Logger;
036:
037: import javax.servlet.http.HttpServlet;
038: import javax.servlet.http.HttpServletRequest;
039: import javax.servlet.http.HttpServletResponse;
040: import java.io.IOException;
041: import java.io.ObjectOutputStream;
042: import java.io.OutputStream;
043: import java.util.ArrayList;
044: import java.util.Collection;
045: import java.util.Iterator;
046:
047: /**
048: * Servlet to gather Metrics for CSMART.
049: *
050: * <pre/>
051: * number of tasks
052: * % and number of tasks that are not yet allocated
053: * % and number of tasks that are low confidence < 0.50
054: * </pre>
055: *
056: * <p>
057: * Can be loaded manually by including this line in an agent's .ini configuration file: <br>
058: * plugin = org.cougaar.core.servlet.SimpleServletComponent(org.cougaar.tools.csmart.ui.servlet.MetricsServlet,
059: * /CSMART_MetricsServlet)
060: *
061: * <p>
062: * Is loaded from a URL on a CSMART machine, on agent 'Agent': <br>
063: * http://localhost:port/$Agent/CSMART_MetricsServlet
064: *
065: */
066: public class MetricsServlet extends HttpServlet {
067: private SimpleServletSupport support;
068:
069: public void setSimpleServletSupport(SimpleServletSupport support) {
070: this .support = support;
071: if (!("/CSMART_MetricsServlet".equals(support.getPath()))) {
072: support.getLog().error(
073: "Incorrect servlet path: " + support.getPath());
074: }
075: }
076:
077: /* Reponds to the GET http method call
078: * @param request HttpServletRequest
079: * @param response HttpServletResponse
080: */
081: public void doGet(HttpServletRequest request,
082: HttpServletResponse response) throws IOException {
083: // create a new "MetricProvider" context per request
084: MetricProvider mp = new MetricProvider(support);
085: mp.execute(request, response);
086: }
087:
088: /* Reponds to the PUT http method call
089: * @param request HttpServletRequest
090: * @param response HttpServletResponse
091: */
092: public void doPut(HttpServletRequest request,
093: HttpServletResponse response) throws IOException {
094: // create a new "MetricProvider" context per request
095: MetricProvider mp = new MetricProvider(support);
096: mp.execute(request, response);
097: }
098:
099: /**
100: * This inner class does all the work.
101: * <p>
102: * A new class is created per request, to keep all the
103: * instance fields separate. If there was only one
104: * instance then multiple simultaneous requests would
105: * corrupt the instance fields (e.g. the "out" stream).
106: * <p>
107: * This acts as a <b>context</b> per request.
108: */
109: private static class MetricProvider {
110:
111: /* Output Stream obtained from the request */
112: private OutputStream out;
113:
114: /* since "MetricProvider" is a static inner class, here
115: * we hold onto the support API.
116: *
117: * this makes it clear that MetricProvider only uses
118: * the "support" from the outer class.
119: */
120: private SimpleServletSupport support;
121: private Logger log;
122:
123: /* Inner class constructor
124: *
125: * @param support Cougaar hook
126: */
127: public MetricProvider(SimpleServletSupport support) {
128: this .support = support;
129: this .log = support.getLog();
130: }
131:
132: /* Obtains Task Predicate */
133: protected static final UnaryPredicate TASK_PRED = new UnaryPredicate() {
134: public boolean execute(Object o) {
135: return (o instanceof Task);
136: }
137: };
138:
139: /*
140: * Main Servlet method. Parses any parameters passed into it, collects data
141: * on all Tasks and writes the object back to the client.
142: * @param request HttpServletRequest
143: * @param response HttpServletResponse
144: */
145: public void execute(HttpServletRequest request,
146: HttpServletResponse response) throws IOException {
147:
148: // There is no mode, as it only returns the list of agent
149: // names, so do nothing but set up for parameter parsing.
150:
151: if (request.getQueryString() == null) {
152: response.setStatus(HttpServletResponse.SC_OK);
153: }
154:
155: // check for illegal arguments
156: if (request.getQueryString() != null) {
157: response.sendError(HttpServletResponse.SC_BAD_REQUEST,
158: "<html><body><br><font size=4>"
159: + "<font size = 5><B>"
160: + request.getQueryString()
161: + "</B></font>"
162: + " Is Not A Legal Parameter List<br>"
163: + "This servlet expects no parameters"
164: + "</font></body></html>");
165: }
166:
167: /**
168: * Fetch CompletionData and write to output.
169: */
170: try {
171: ArrayList list = collectData(support);
172: if (list != null) {
173: // serialize back to the user
174: this .out = response.getOutputStream();
175: ObjectOutputStream p = new ObjectOutputStream(out);
176: p.writeObject(list);
177: //System.out.println("Sent Objects");
178: }
179: } catch (Exception e) {
180: if (log.isErrorEnabled()) {
181: log.error("CSMART_MetricsServlet Exception", e);
182: }
183: }
184: }
185:
186: /* Gets all sociey <code>Task</code> objects from support */
187: protected static Collection getAllTasks(
188: SimpleServletSupport support) {
189: Collection col = support.queryBlackboard(TASK_PRED);
190: if (col == null) {
191: col = new ArrayList(0);
192: }
193: return col;
194: }
195:
196: /* Get data from each Task
197: * @return ArrayList
198: */
199: protected ArrayList collectData(SimpleServletSupport support) {
200:
201: Collection tasks = getAllTasks(support);
202: Iterator taskIter = tasks.iterator();
203: ArrayList results = new ArrayList(2);
204: int nTasks = 0;
205: int nLowConfidence = 0;
206: int nUnallocated = 0;
207: Integer[] data = new Integer[3];
208:
209: while (taskIter.hasNext()) {
210: Task t = (Task) taskIter.next();
211: nTasks++;
212: PlanElement pe = t.getPlanElement();
213: if (pe != null) {
214: AllocationResult estResult = pe
215: .getEstimatedResult();
216: if (estResult != null) {
217: double estConf = estResult
218: .getConfidenceRating();
219: if (estConf < 0.5) {
220: nLowConfidence++;
221: }
222: }
223: } else {
224: nUnallocated++;
225: }
226: }
227: data[0] = new Integer(nTasks);
228: data[1] = new Integer(nUnallocated);
229: data[2] = new Integer(nLowConfidence);
230: results.add(support.getAgentIdentifier());
231: results.add(data);
232: return results;
233: }
234: }
235: }
|