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: package org.cougaar.mts.std;
028:
029: import java.io.FileOutputStream;
030: import java.io.PrintStream;
031:
032: import org.cougaar.core.component.ServiceBroker;
033: import org.cougaar.core.mts.MessageAddress;
034: import org.cougaar.core.mts.MessageAttributes;
035: import org.cougaar.core.service.wp.AddressEntry;
036: import org.cougaar.core.service.wp.WhitePagesService;
037: import org.cougaar.mts.base.DestinationLink;
038: import org.cougaar.mts.base.NameLookupException;
039: import org.cougaar.mts.base.CommFailureException;
040: import org.cougaar.mts.base.MisdeliveredMessageException;
041: import org.cougaar.mts.base.DestinationLinkDelegateImplBase;
042: import org.cougaar.mts.base.UnregisteredNameException;
043: import org.cougaar.mts.base.StandardAspect;
044:
045: /**
046: * This test Aspect logs all outgoing messages, including in each log
047: * the source and destination Agent, the destination Node, and the
048: * destination Host.
049: */
050: public class ForwardMessageLoggingAspect extends StandardAspect {
051: static final String TOPOLOGY = "topology";
052:
053: private static final char SEPR = '\t';
054:
055: private PrintStream log;
056: private boolean madeLog;
057: private WhitePagesService wp;
058:
059: public void load() {
060: super .load();
061: ServiceBroker sb = getServiceBroker();
062: wp = (WhitePagesService) sb.getService(this ,
063: WhitePagesService.class, null);
064: }
065:
066: private synchronized void ensureLog() {
067: if (madeLog)
068: return;
069: log = System.out; // default PrintStream
070: String logfile = getRegistry().getIdentifier()
071: + "_MessageForwarding.log";
072: try {
073: FileOutputStream fos = new FileOutputStream(logfile);
074: log = new PrintStream(fos);
075: } catch (java.io.FileNotFoundException fnf) {
076: // ???
077: }
078: madeLog = true;
079: }
080:
081: public Object getDelegate(Object delegate, Class type) {
082: if (type == DestinationLink.class) {
083: return new DestinationLinkDelegate(
084: (DestinationLink) delegate);
085: } else {
086: return null;
087: }
088: }
089:
090: private static final int UBYTE_MAX = (1 << 8) - 1;
091: private static final int USHORT_MAX = (1 << 16) - 1;
092:
093: private boolean isUnsignedByte(String string, int start, int end) {
094: String s = string.substring(start, end);
095: try {
096: int x = Integer.parseInt(s);
097: return x >= 0 && x < UBYTE_MAX;
098: } catch (NumberFormatException ex) {
099: return false;
100: }
101: }
102:
103: private boolean isUnsignedShort(String string, int start, int end) {
104: String s = string.substring(start, end);
105: try {
106: int x = Integer.parseInt(s);
107: return x >= 0 && x < USHORT_MAX;
108: } catch (NumberFormatException ex) {
109: return false;
110: }
111: }
112:
113: private String extractInetAddr(String raw) {
114: if (raw.startsWith("IOR:")) {
115: // CORBA ior; handle this later. Just return null for
116: // now.
117: return null;
118: }
119:
120: int i = 0;
121: int end = raw.length();
122: while (i < end) {
123: if (Character.isDigit(raw.charAt(i))) {
124: int start = i;
125:
126: int substart = i;
127: i = raw.indexOf('.', substart);
128: if (i == -1)
129: break;
130: if (!isUnsignedByte(raw, substart, i))
131: continue;
132:
133: substart = i + 1;
134: i = raw.indexOf('.', substart);
135: if (i == -1)
136: break;
137: if (!isUnsignedByte(raw, substart, i))
138: continue;
139:
140: substart = i + 1;
141: i = raw.indexOf('.', substart);
142: if (i == -1)
143: break;
144: if (!isUnsignedByte(raw, substart, i))
145: continue;
146:
147: substart = i + 1;
148: i = raw.indexOf(':', substart);
149: if (i == -1)
150: break;
151: if (!isUnsignedByte(raw, substart, i))
152: continue;
153:
154: substart = i + 1;
155: while (i < end - 1
156: && Character.isDigit(raw.charAt(++i)))
157: ;
158: if (!isUnsignedShort(raw, substart, i))
159: continue;
160:
161: return raw.substring(start, i);
162:
163: } else {
164: ++i;
165: }
166: }
167:
168: return null;
169: }
170:
171: private void logMessage(AttributedMessage msg, String tag,
172: DestinationLink link) {
173: ensureLog();
174: MessageAddress src = msg.getOriginator();
175: MessageAddress dst = msg.getTarget();
176: String dst_agent = dst.getAddress();
177: Class pclass = link.getProtocolClass();
178: long now = System.currentTimeMillis();
179: Object remote = link.getRemoteReference();
180: String remoteIP = remote == null ? null
181: : extractInetAddr(remote.toString());
182: String dst_node = null;
183: try {
184: AddressEntry entry = wp.get(dst_agent, TOPOLOGY, 10);
185: if (entry == null) {
186: dst_node = "???";
187: } else {
188: dst_node = entry.getURI().getPath().substring(1);
189: }
190: } catch (Exception ex) {
191: getLoggingService().error("", ex);
192: dst_node = "???";
193: }
194:
195: synchronized (this ) {
196: log.print(now);
197: log.print(SEPR);
198: log.print(tag);
199: log.print(SEPR);
200: log.print(src);
201: log.print(SEPR);
202: log.print(dst);
203: log.print(SEPR);
204: log.print(dst_node);
205: log.print(SEPR);
206: log.print(pclass.getName());
207: log.print(SEPR);
208: log.print(remoteIP);
209: log.print(SEPR);
210: log.println(remote);
211: log.flush();
212: }
213: }
214:
215: public class DestinationLinkDelegate extends
216: DestinationLinkDelegateImplBase {
217:
218: public DestinationLinkDelegate(DestinationLink link) {
219: super (link);
220: }
221:
222: public MessageAttributes forwardMessage(AttributedMessage msg)
223: throws UnregisteredNameException, NameLookupException,
224: CommFailureException, MisdeliveredMessageException
225:
226: {
227: try {
228: MessageAttributes result = super .forwardMessage(msg);
229: logMessage(msg, "Sent", this );
230: return result;
231: } catch (UnregisteredNameException ex1) {
232: logMessage(msg, "Failed", this );
233: throw ex1;
234: } catch (NameLookupException ex2) {
235: logMessage(msg, "Failed", this );
236: throw ex2;
237: } catch (CommFailureException ex3) {
238: logMessage(msg, "Failed", this );
239: throw ex3;
240: } catch (MisdeliveredMessageException ex4) {
241: logMessage(msg, "Failed", this);
242: throw ex4;
243: }
244: }
245:
246: }
247:
248: }
|