001: /*
002: * <copyright>
003: *
004: * Copyright 2001-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.core.mobility;
028:
029: import org.cougaar.core.mts.MessageAddress;
030:
031: /**
032: * A ticket requesting agent mobility.
033: */
034: public class MoveTicket extends AbstractTicket implements
035: java.io.Serializable {
036:
037: private final Object id;
038: private final MessageAddress mobileAgent;
039: private final MessageAddress origNode;
040: private final MessageAddress destNode;
041: private final boolean forceRestart;
042:
043: // FIXME maybe add "timeout" here
044: // FIXME maybe add "clone" here + clone name
045: // FIXME maybe add security tags here
046:
047: public MoveTicket(Object id, MessageAddress mobileAgent,
048: MessageAddress origNode, MessageAddress destNode,
049: boolean forceRestart) {
050: this .id = id;
051: this .mobileAgent = mobileAgent;
052: this .origNode = origNode;
053: this .destNode = destNode;
054: this .forceRestart = forceRestart;
055: }
056:
057: /**
058: * An optional identifier for this ticket instance.
059: * <p>
060: * The identifier <u>must</u> be serializable and should be
061: * immutable. A UID is a good identifier.
062: */
063: public Object getIdentifier() {
064: return id;
065: }
066:
067: /**
068: * The agent to be moved.
069: * <p>
070: * An agent can only pass a Ticket to "dispatch(..)" if
071: * the agent <i>is</i> the one moving. Aside from this
072: * sanity check, tagging the ticket with the agent address
073: * aids debugging.
074: * <p>
075: * If the agent is null then the caller of the
076: * MobilityService is assumed.
077: */
078: public MessageAddress getMobileAgent() {
079: return mobileAgent;
080: }
081:
082: /**
083: * Optional assertion on the current node that the mobile agent
084: * is running on.
085: * <p>
086: * If the origin node is non-null then the ticket will only be
087: * accepted if the agent is on that node. Of course, a ticket
088: * can only be presented to the MobilityService <i>by</i>
089: * the local agent, but this is a sanity check that the agent
090: * wasn't moved or restarted after the ticket was created.
091: */
092: public MessageAddress getOriginNode() {
093: return origNode;
094: }
095:
096: /**
097: * Destination node for the mobile agent.
098: * <p>
099: * If the destination node is null then the agent should
100: * remain at its current node. This is is useful for
101: * a "force-restart".
102: */
103: public MessageAddress getDestinationNode() {
104: return destNode;
105: }
106:
107: /**
108: * If true, force the agent to be restarted even if the agent
109: * is already on the destination node.
110: * <p>
111: * If false then a move of an agent already at the destination
112: * will reply with a trivial success. In practice one would
113: * tyically set this to <b>false</b> for performance reasons.
114: * <p>
115: * The "force reload" capability is primarily designed to test
116: * the agent-side mobility requirements without actually
117: * relocating the agent.
118: * <p>
119: * If the agent and its components (plugins, services, etc)
120: * correctly implement the suspend and persistence APIs then
121: * the restart of an agent on the same node should have
122: * <i>no</i> permanent side effects. A hundred restarts
123: * should have no side effect other than a temporary
124: * performance penalty.
125: * <p>
126: * On the other hand, a failure to support a restart might
127: * result in an agent:<ul>
128: * <li>memory leak (garbage-collection)</li>
129: * <li>thread leak (didn't stop/pool all theads)</li>
130: * <li>serialization/deserialization error</li>
131: * <li>state loss (some state not captured)</li>
132: * <li>internal deadlock (synchronization bug)</li>
133: * <li>persistence error</li>
134: * <li>naming-service mess</li>
135: * <li>crypto-key loss (unable to re-obtain identity)</li>
136: * <li>conflict with other services (health-check, etc)</li>
137: * </ul>
138: * or some other error that (ideally) should be easier to
139: * debug than the full relocation of the agent on another
140: * node.
141: */
142: public boolean isForceRestart() {
143: return forceRestart;
144: }
145:
146: public int hashCode() {
147: return (((id != null) ? id.hashCode() : 17) ^ ((mobileAgent != null) ? mobileAgent
148: .hashCode()
149: : 53));
150: }
151:
152: public boolean equals(Object o) {
153: if (o == this ) {
154: return true;
155: } else if (!(o instanceof MoveTicket)) {
156: return false;
157: } else {
158: MoveTicket t = (MoveTicket) o;
159: return ((forceRestart == t.forceRestart)
160: && ((id == null) ? (t.id == null) : (id
161: .equals(t.id)))
162: && ((mobileAgent == null) ? (t.mobileAgent == null)
163: : (mobileAgent.equals(t.mobileAgent)))
164: && ((origNode == null) ? (t.origNode == null)
165: : (origNode.equals(t.origNode))) && ((destNode == null) ? (t.destNode == null)
166: : (destNode.equals(t.destNode))));
167: }
168: }
169:
170: public String toString() {
171: // cache?
172: return "Move "
173: + ((id != null) ? (id) : (" unidentified "))
174: + " of "
175: + ((mobileAgent != null) ? "agent \"" + mobileAgent
176: + "\"" : "this agent")
177: + " from "
178: + ((origNode != null) ? "node \"" + origNode + "\""
179: : "this node")
180: + " to "
181: + ((destNode != null) ? "node \"" + destNode + "\""
182: : "this node")
183: + (forceRestart ? " with forced restart" : "");
184: }
185:
186: private static final long serialVersionUID = 3892837467898101093L;
187:
188: }
|