001: /**
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */package org.griphyn.cPlanner.selector.replica;
015:
016: import org.griphyn.cPlanner.classes.ReplicaLocation;
017:
018: import org.griphyn.cPlanner.selector.ReplicaSelector;
019:
020: import org.griphyn.cPlanner.common.LogManager;
021: import org.griphyn.cPlanner.common.PegasusProperties;
022: import org.griphyn.cPlanner.common.PegRandom;
023:
024: import org.griphyn.common.catalog.ReplicaCatalogEntry;
025:
026: import java.util.ArrayList;
027: import java.util.Iterator;
028: import java.util.Vector;
029:
030: /**
031: * This replica selector that takes into account availability times returned by
032: * the DC. It selects the replica with the lowest availability time.
033: *
034: * <p>
035: * In order to use the replica selector implemented by this class,
036: * <pre>
037: * - the property pegasus.selector.replica must be set to value Windward
038: * - the property pegasus.catalog.replica must be set to value Windward
039: * </pre>
040: *
041: *
042: * @see org.griphyn.cPlanner.transfer.implementation.Condor
043: *
044: * @author Karan Vahi
045: * @version $Revision: 440 $
046: */
047: public class Windward implements ReplicaSelector {
048:
049: /**
050: * A short description of the replica selector.
051: */
052: private static String mDescription = "Takes into account availability times returned by the DC";
053:
054: /**
055: * The scheme name for file url.
056: */
057: protected static final String FILE_URL_SCHEME = "file:";
058:
059: /**
060: * The handle to the logging object that is used to log the various debug
061: * messages.
062: */
063: protected LogManager mLogger;
064:
065: /**
066: * The properties object containing the properties passed to the planner.
067: */
068: protected PegasusProperties mProps;
069:
070: /**
071: * The overloaded constructor, that is called by load method.
072: *
073: * @param properties the <code>PegasusProperties</code> object containing all
074: * the properties required by Pegasus.
075: *
076: *
077: */
078: public Windward(PegasusProperties properties) {
079: mProps = properties;
080: mLogger = LogManager.getInstance();
081: }
082:
083: /**
084: * Selects a replica that has the lowest availability time, else selects
085: * a random replica.
086: *
087: * @param rl the <code>ReplicaLocation</code> object containing all
088: * the pfn's associated with that LFN.
089: * @param preferredSite the preffered site for picking up the replicas.
090: *
091: * @return <code>ReplicaCatalogEntry</code> corresponding to the location selected.
092: *
093: * @see org.griphyn.cPlanner.classes.ReplicaLocation
094: */
095: public ReplicaCatalogEntry selectReplica(ReplicaLocation rl,
096: String preferredSite) {
097:
098: ArrayList prefPFNs = new ArrayList();
099: int locSelected;
100: String site = null;
101:
102: mLogger.log("Selecting a pfn for lfn " + rl.getLFN()
103: + "\n amongst" + rl.getPFNList(),
104: LogManager.DEBUG_MESSAGE_LEVEL);
105:
106: ReplicaCatalogEntry selected = null;
107: double lowest = Double.MAX_VALUE;
108: for (Iterator it = rl.pfnIterator(); it.hasNext();) {
109: ReplicaCatalogEntry rce = (ReplicaCatalogEntry) it.next();
110: site = rce.getResourceHandle();
111:
112: Double availTime = (Double) rce
113: .getAttribute(org.griphyn.common.catalog.replica.Windward.DATA_AVAILABILITY_KEY);
114:
115: if (availTime == null) {
116: //skip to next replica
117: continue;
118: }
119:
120: //if the current availability time is less use max
121: if (availTime < lowest) {
122: selected = rce;
123: }
124: }
125:
126: if (selected == null) {
127: //select a random location from
128: //all the matching locations
129: mLogger.log("Selecting a random replica for lfn "
130: + rl.getLFN(), LogManager.DEBUG_MESSAGE_LEVEL);
131:
132: int length = rl.getPFNCount();
133: //System.out.println("No of locations found at pool " + prefPool + " are " + length);
134: locSelected = PegRandom.getInteger(length - 1);
135: selected = (ReplicaCatalogEntry) rl.getPFN(locSelected);
136: }
137:
138: mLogger.log("Selected replica " + selected,
139: LogManager.DEBUG_MESSAGE_LEVEL);
140: return selected;
141:
142: }
143:
144: /**
145: * This chooses a location amongst all the locations returned by the
146: * Replica Mechanism. If a location is found with re/pool attribute same
147: * as the preference pool, it is taken. This returns all the locations which
148: * match to the preference pool. This function is called to determine if a
149: * file does exist on the output pool or not beforehand. We need all the
150: * location to ensure that we are able to make a match if it so exists.
151: * Else a random location is selected and returned
152: *
153: * @param rl the <code>ReplicaLocation</code> object containing all
154: * the pfn's associated with that LFN.
155: * @param preferredSite the preffered site for picking up the replicas.
156: *
157: * @return <code>ReplicaLocation</code> corresponding to the replicas selected.
158: *
159: * @see org.griphyn.cPlanner.classes.ReplicaLocation
160: */
161: public ReplicaLocation selectReplicas(ReplicaLocation rl,
162: String preferredSite) {
163:
164: String lfn = rl.getLFN();
165: ReplicaLocation result = new ReplicaLocation();
166: result.setLFN(rl.getLFN());
167:
168: ReplicaCatalogEntry rce;
169: String site;
170: int noOfLocs = 0;
171:
172: for (Iterator it = rl.pfnIterator(); it.hasNext();) {
173: noOfLocs++;
174: rce = (ReplicaCatalogEntry) it.next();
175: site = rce.getResourceHandle();
176:
177: if (site != null && site.equals(preferredSite)) {
178: result.addPFN(rce);
179: } else if (site == null) {
180: mLogger.log(
181: " pool attribute not specified for the location objects"
182: + " in the Replica Catalog",
183: LogManager.WARNING_MESSAGE_LEVEL);
184: }
185: }
186:
187: if (result.getPFNCount() == 0) {
188: //means we have to choose a random location between 0 and (noOfLocs -1)
189: int locSelected = PegRandom.getInteger(noOfLocs - 1);
190: rce = (ReplicaCatalogEntry) rl.getPFN(locSelected);
191: result.addPFN(rce);
192: }
193: return result;
194:
195: }
196:
197: /**
198: * Returns a short description of the replica selector.
199: *
200: * @return string corresponding to the description.
201: */
202: public String description() {
203: return mDescription;
204: }
205:
206: }
|