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: */
015: package org.griphyn.cPlanner.transfer.implementation;
016:
017: import org.griphyn.cPlanner.classes.TransferJob;
018: import org.griphyn.cPlanner.classes.NameValue;
019: import org.griphyn.cPlanner.classes.PlannerOptions;
020: import org.griphyn.cPlanner.classes.FileTransfer;
021:
022: import org.griphyn.cPlanner.common.LogManager;
023: import org.griphyn.cPlanner.common.PegasusProperties;
024:
025: import org.griphyn.cPlanner.namespace.VDS;
026:
027: import org.griphyn.common.classes.TCType;
028:
029: import org.griphyn.common.catalog.TransformationCatalogEntry;
030:
031: import org.griphyn.common.util.Separator;
032:
033: import java.io.FileWriter;
034:
035: import java.util.Collection;
036: import java.util.Iterator;
037: import java.util.List;
038:
039: /**
040: * The implementation that creates transfer jobs referring to the old GUC
041: * that could handle only one transfer per guc invocation.
042: *
043: * <p>
044: * The client is generally invoked on the remote execution sites, unless
045: * the user uses the thirdparty transfer option, in which case the transfer is
046: * invoked on the submit host. Hence there should be an entry in the transformation
047: * catalog for logical transformation <code>globus-url-copy</code> at the
048: * execution sites.
049: * GUC is distributed as part of the VDS worker package and can be found at
050: * $GLOBUS_LOCATION/bin/globus-url-copy.
051: *
052: * <p>
053: * It leads to the creation of the setup chmod jobs to the workflow, that appear
054: * as parents to compute jobs in case the transfer implementation does not
055: * preserve the X bit on the file being transferred. This is required for
056: * staging of executables as part of the workflow. The setup jobs are only added
057: * as children to the stage in jobs.
058: *
059: * <p>
060: * In order to use the transfer implementation implemented by this class,
061: * <pre>
062: * - the property vds.transfer.*.impl must be set to value OldGUC.
063: * </pre>
064: *
065: * <p>
066: * There should be an entry in the transformation catalog with the fully qualified
067: * name as <code>globus-url-copy</code> for all the sites where workflow is run,
068: * or on the local site in case of third party transfers.
069: *
070: * <p>
071: * The arguments with which the client is invoked can be specified
072: * <pre>
073: * - by specifying the property vds.transfer.arguments
074: * - associating the VDS profile key transfer.arguments
075: * </pre>
076:
077: *
078: * @author Karan Vahi
079: * @version $Revision: 50 $
080: */
081: public class OldGUC extends AbstractSingleFTPerXFERJob {
082:
083: /**
084: * The transformation namespace for the transfer job.
085: */
086: public static final String TRANSFORMATION_NAMESPACE = null;
087:
088: /**
089: * The name of the underlying transformation that is queried for in the
090: * Transformation Catalog.
091: */
092: public static final String TRANSFORMATION_NAME = "globus-url-copy";
093:
094: /**
095: * The version number for the transfer job.
096: */
097: public static final String TRANSFORMATION_VERSION = null;
098:
099: /**
100: * The derivation namespace for for the transfer job.
101: */
102: public static final String DERIVATION_NAMESPACE = "VDS";
103:
104: /**
105: * The name of the underlying derivation.
106: */
107: public static final String DERIVATION_NAME = "globus-url-copy";
108:
109: /**
110: * The derivation version number for the transfer job.
111: */
112: public static final String DERIVATION_VERSION = "1.0";
113:
114: /**
115: * A short description of the transfer implementation.
116: */
117: public static final String DESCRIPTION = "Old GUC client that does only one transfer per invocation";
118:
119: /**
120: * The number of streams that each g-u-c process opens to do the ftp transfer.
121: */
122: protected String mNumOfTXStreams;
123:
124: /**
125: * Whether to use force option for the transfer executable or not.
126: */
127: protected boolean mUseForce;
128:
129: /**
130: * A boolean indicating whehter to quote the urls or not.
131: */
132: protected boolean mQuoteURL;
133:
134: /**
135: * The overloaded constructor, that is called by the Factory to load the
136: * class.
137: *
138: * @param properties the properties object.
139: * @param options the options passed to the Planner.
140: */
141: public OldGUC(PegasusProperties properties, PlannerOptions options) {
142: super (properties, options);
143: mNumOfTXStreams = mProps.getNumOfTransferStreams();
144: mUseForce = mProps.useForceInTransfer();
145: mQuoteURL = mProps.quoteTransferURL();
146: }
147:
148: /**
149: * Return a boolean indicating whether the transfers to be done always in
150: * a third party transfer mode. A value of false, results in the
151: * direct or peer to peer transfers being done.
152: * <p>
153: * A value of false does not preclude third party transfers. They still can
154: * be done, by setting the property "vds.transfer.*.thirdparty.sites".
155: *
156: * @return boolean indicating whether to always use third party transfers
157: * or not.
158: *
159: * @see PegasusProperties#getThirdPartySites(String)
160: */
161: public boolean useThirdPartyTransferAlways() {
162: return false;
163: }
164:
165: /**
166: * Returns a boolean indicating whether the transfer protocol being used by
167: * the implementation preserves the X Bit or not while staging.
168: *
169: * @return boolean
170: */
171: public boolean doesPreserveXBit() {
172: return false;
173: }
174:
175: /**
176: * Returns a textual description of the transfer implementation.
177: *
178: * @return a short textual description
179: */
180: public String getDescription() {
181: return this .DESCRIPTION;
182: }
183:
184: /**
185: * Retrieves the transformation catalog entry for the executable that is
186: * being used to transfer the files in the implementation.
187: *
188: * @param siteHandle the handle of the site where the transformation is
189: * to be searched.
190: *
191: * @return the transformation catalog entry if found, else null.
192: */
193: public TransformationCatalogEntry getTransformationCatalogEntry(
194: String siteHandle) {
195: List tcentries = null;
196: try {
197: //namespace and version are null for time being
198: tcentries = mTCHandle.getTCEntries(
199: this .TRANSFORMATION_NAMESPACE,
200: this .TRANSFORMATION_NAME,
201: this .TRANSFORMATION_VERSION, siteHandle,
202: TCType.INSTALLED);
203: } catch (Exception e) {
204: mLogger.log("Unable to retrieve entry from TC for "
205: + getCompleteTCName() + " :" + e.getMessage(),
206: LogManager.ERROR_MESSAGE_LEVEL);
207: }
208:
209: //see if any record is returned or not
210: return (tcentries == null) ? null
211: : (TransformationCatalogEntry) tcentries.get(0);
212: }
213:
214: /**
215: * Returns the namespace of the derivation that this implementation
216: * refers to.
217: *
218: * @return the namespace of the derivation.
219: */
220: protected String getDerivationNamespace() {
221: return this .DERIVATION_NAMESPACE;
222: }
223:
224: /**
225: * Returns the logical name of the derivation that this implementation
226: * refers to.
227: *
228: * @return the name of the derivation.
229: */
230: protected String getDerivationName() {
231: return this .DERIVATION_NAME;
232: }
233:
234: /**
235: * Returns the version of the derivation that this implementation
236: * refers to.
237: *
238: * @return the version of the derivation.
239: */
240: protected String getDerivationVersion() {
241: return this .DERIVATION_VERSION;
242: }
243:
244: /**
245: * It constructs the arguments to the transfer executable that need to be passed
246: * to the executable referred to in this transfer mode.
247: *
248: * @param job the transfer job that is being created.
249: * @param file the FileTransfer that needs to be done.
250: * @return the argument string
251: */
252: protected String generateArgumentString(TransferJob job,
253: FileTransfer file) {
254: StringBuffer sb = new StringBuffer();
255:
256: if (job.vdsNS.containsKey(VDS.TRANSFER_ARGUMENTS_KEY)) {
257: sb.append(job.vdsNS.removeKey(VDS.TRANSFER_ARGUMENTS_KEY));
258: } else {
259: //append the number of streams that are
260: //opened for each transfer
261: sb.append(" -p ").append(mNumOfTXStreams).append(" ");
262: }
263:
264: sb = (mQuoteURL) ? sb.append("'") : sb;
265: sb.append(((NameValue) file.getSourceURL()).getValue());
266:
267: sb = (mQuoteURL) ? sb.append("' '") : sb.append(" ");
268:
269: sb.append(((NameValue) file.getDestURL()).getValue());
270: sb = (mQuoteURL) ? sb.append("'") : sb;
271:
272: return sb.toString();
273:
274: }
275:
276: /**
277: * Returns the complete name for the transformation.
278: *
279: * @return the complete name.
280: */
281: protected String getCompleteTCName() {
282: return Separator.combine(this.TRANSFORMATION_NAMESPACE,
283: this.TRANSFORMATION_NAME, this.TRANSFORMATION_VERSION);
284: }
285: }
|