0001: /*
0002: * This file or a portion of this file is licensed under the terms of
0003: * the Globus Toolkit Public License, found in file GTPL, or at
0004: * http://www.globus.org/toolkit/download/license.html. This notice must
0005: * appear in redistributions of this file, with or without modification.
0006: *
0007: * Redistributions of this Software, with or without modification, must
0008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
0009: * some other similar material which is provided with the Software (if
0010: * any).
0011: *
0012: * Copyright 1999-2004 University of Chicago and The University of
0013: * Southern California. All rights reserved.
0014: */
0015: package org.griphyn.common.catalog.replica;
0016:
0017: import org.griphyn.common.catalog.ReplicaCatalog;
0018: import org.griphyn.common.catalog.ReplicaCatalogEntry;
0019: import org.griphyn.common.catalog.CatalogException;
0020:
0021: import org.griphyn.cPlanner.common.LogManager;
0022:
0023: import org.globus.replica.rls.RLSClient;
0024: import org.globus.replica.rls.RLSException;
0025: import org.globus.replica.rls.RLSAttribute;
0026: import org.globus.replica.rls.RLSAttributeObject;
0027: import org.globus.replica.rls.RLSString2Bulk;
0028: import org.globus.replica.rls.RLSString2;
0029: import org.globus.replica.rls.RLSOffsetLimit;
0030:
0031: import java.util.Collection;
0032: import java.util.Collections;
0033: import java.util.Comparator;
0034: import java.util.Map;
0035: import java.util.HashMap;
0036: import java.util.Set;
0037: import java.util.HashSet;
0038: import java.util.Properties;
0039: import java.util.List;
0040: import java.util.ArrayList;
0041: import java.util.LinkedHashSet;
0042: import java.util.Iterator;
0043: import java.util.TreeMap;
0044:
0045: /**
0046: * This class implements the VDS replica catalog interface on top of the
0047: * LRC. This class implementation ends up talking to a single LRC.
0048: * It is accessed internally from the RLI implementation.
0049: * RLS Exceptions are being caught here. They probably should be thrown
0050: * and caught at the calling class (i.e the RLI implementation).
0051: *
0052: * @author Karan Vahi
0053: * @author Gaurang Mehta
0054: *
0055: * @version $Revision: 50 $
0056: */
0057: public class LRC implements ReplicaCatalog {
0058:
0059: /**
0060: * The number of entries searched in each bulk query to RLS.
0061: */
0062: public static final int RLS_BULK_QUERY_SIZE = 1000;
0063:
0064: /**
0065: * The default timeout in seconds to be used while querying the LRC.
0066: */
0067: public static final String DEFAULT_LRC_TIMEOUT = "30";
0068:
0069: /**
0070: * The key that is used to get hold of the timeout value from the properties
0071: * object.
0072: */
0073: public static final String RLS_TIMEOUT_KEY = "rls.timeout";
0074:
0075: /**
0076: * The key that is used to get hold of the timeout value from the properties
0077: * object.
0078: */
0079: public static final String LRC_TIMEOUT_KEY = "lrc.timeout";
0080:
0081: /**
0082: * The attribute in RLS that maps to a site handle.
0083: */
0084: public static final String SITE_ATTRIBUTE = "pool";
0085:
0086: /**
0087: * The undefined pool attribute value. The pool attribute is assigned this
0088: * value if the pfn queried does not have a pool associated with it.
0089: */
0090: public static final String UNDEFINED_SITE = "UNDEFINED_POOL";
0091:
0092: /**
0093: * The key that is used to get hold of the url from the properties object.
0094: */
0095: public static final String URL_KEY = "url";
0096:
0097: /**
0098: * The key that if set, specifies the proxy to be picked up while connecting
0099: * to the RLS.
0100: */
0101: public static final String PROXY_KEY = "proxy";
0102:
0103: /**
0104: * The error message for not connected to LRC.
0105: */
0106: public static final String LRC_NOT_CONNECTED_MSG = "Not connected to LRC ";
0107:
0108: /**
0109: * The handle to the logging object. Should be log4j soon.
0110: */
0111: private LogManager mLogger;
0112:
0113: /**
0114: * The string holding the message that is logged in the logger.
0115: */
0116: private String mLogMsg;
0117:
0118: /**
0119: * The URL pointing to the LRC to which this instance of class talks to.
0120: */
0121: private String mLRCURL;
0122:
0123: /**
0124: * The handle to the client that allows access to the RLS running at the
0125: * url specified while connecting.
0126: */
0127: private RLSClient mRLS;
0128:
0129: /**
0130: * The handle to the client that allows access to the LRC running at the
0131: * url specified while connecting.
0132: */
0133: private RLSClient.LRC mLRC;
0134:
0135: /**
0136: * The batch size while querying the LRC in the bulk mode.
0137: */
0138: private int mBatchSize;
0139:
0140: /**
0141: * The timeout in seconds while querying to the LRC.
0142: */
0143: private int mTimeout;
0144:
0145: /**
0146: * The default constructor, that creates an object which is not linked with
0147: * any RLS. Use the connect method to connect to the LRC and use it.
0148: *
0149: * @see #connect(Properties).
0150: */
0151: public LRC() {
0152: mRLS = null;
0153: mLRC = null;
0154: mLogger = LogManager.getInstance();
0155: mBatchSize = this .RLS_BULK_QUERY_SIZE;
0156: mTimeout = Integer.parseInt(this .DEFAULT_LRC_TIMEOUT);
0157: }
0158:
0159: /**
0160: * Establishes a connection to the LRC.
0161: *
0162: * @param props contains all necessary data to establish the link.
0163: * @return true if connected now, or false to indicate a failure.
0164: */
0165: public boolean connect(Properties props) {
0166: boolean con = false;
0167: Object obj = props.get(URL_KEY);
0168: mLRCURL = (obj == null) ? null : (String) obj;
0169:
0170: if (mLRCURL == null) {
0171: //nothing to connect to.
0172: log("The LRC url is not specified",
0173: LogManager.ERROR_MESSAGE_LEVEL);
0174: return con;
0175: }
0176:
0177: //try to see if a proxy cert has been specified or not
0178: String proxy = props.getProperty(PROXY_KEY);
0179:
0180: //determine timeout
0181: mTimeout = getTimeout(props);
0182:
0183: //set the batch size for querie
0184: setBatchSize(props);
0185:
0186: return connect(mLRCURL, proxy);
0187: }
0188:
0189: /**
0190: * Establishes a connection to the LRC, picking up the proxy from the default
0191: * location usually /tmp/ directory.
0192: *
0193: * @param url the url to lrc to connect to.
0194: *
0195: * @return true if connected now, or false to indicate a failure.
0196: */
0197: public boolean connect(String url) {
0198: return connect(url, null);
0199: }
0200:
0201: /**
0202: * Establishes a connection to the LRC.
0203: *
0204: * @param url the url to lrc to connect to.
0205: * @param proxy the path to the proxy file to be picked up. null denotes
0206: * default location.
0207: *
0208: * @return true if connected now, or false to indicate a failure.
0209: *
0210: * @throws ReplicaCatalogException in case of
0211: */
0212: public boolean connect(String url, String proxy) {
0213: mLRCURL = url;
0214: try {
0215: mRLS = (proxy == null) ? new RLSClient(url) : //proxy is picked up from default loc /tmp
0216: new RLSClient(url, proxy);
0217:
0218: //set the timeout
0219: mRLS.SetTimeout(mTimeout);
0220:
0221: //connect is only successful if we have
0222: //successfully connected to the LRC
0223: mLRC = mRLS.getLRC();
0224:
0225: } catch (RLSException e) {
0226: log("RLS Exception", e, LogManager.ERROR_MESSAGE_LEVEL);
0227: return false;
0228: }
0229: return true;
0230: }
0231:
0232: /**
0233: * Gets a handle to the LRC that is associated with the RLS running at
0234: * url.
0235: *
0236: * @return <code>RLSClient.LRC</code> that points to the RLI that is
0237: * running , or null in case connect method not being called.
0238: * @see #mLRCURL
0239: */
0240: public RLSClient.LRC getLRC() {
0241: return (isClosed()) ? null : mLRC;
0242: }
0243:
0244: /**
0245: * Retrieves the entry for a given filename and resource handle from
0246: * the LRC.
0247: *
0248: * @param lfn is the logical filename to obtain information for.
0249: * @param handle is the resource handle to obtain entries for.
0250: * @return the (first) matching physical filename, or
0251: * <code>null</code> if no match was found.
0252: *
0253: * @throws ReplicaCatalogException in case of any error that is throw by LRC
0254: * that can't be handled.
0255: */
0256: public String lookup(String lfn, String handle) {
0257: //sanity check
0258: if (this .isClosed()) {
0259: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
0260: + this .mLRCURL);
0261: }
0262: String pfn = null;
0263: String site = null;
0264:
0265: //query the lrc
0266: try {
0267: List l = mLRC.getPFN(lfn);
0268: for (Iterator it = l.iterator(); it.hasNext();) {
0269: //query for the pool attribute
0270: pfn = ((RLSString2) it.next()).s2;
0271: site = getSiteHandle(pfn);
0272: if (site.equalsIgnoreCase(handle)) {
0273: //ok we have the first pfn with for the site and lfn
0274: break;
0275: }
0276: }
0277: } catch (RLSException ex) {
0278: if (ex.GetRC() == RLSClient.RLS_LFN_NEXIST
0279: || ex.GetRC() == RLSClient.RLS_MAPPING_NEXIST) {
0280: pfn = null;
0281: } else {
0282: throw exception("lookup(String,String)", ex);
0283: }
0284: }
0285:
0286: return pfn;
0287: }
0288:
0289: /**
0290: * Retrieves all entries for a given LFN from the LRC.
0291: * Each entry in the result set is a tuple of a PFN and all its
0292: * attributes.
0293: *
0294: * @param lfn is the logical filename to obtain information for.
0295: * @return a collection of replica catalog entries, or null in case of
0296: * unable to connect to RLS or error.
0297: *
0298: * @throws ReplicaCatalogException in case of any error that is throw by LRC
0299: * that can't be handled.
0300: * @see ReplicaCatalogEntry
0301: */
0302: public Collection lookup(String lfn) throws ReplicaCatalogException {
0303: //sanity check
0304: if (this .isClosed()) {
0305: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
0306: + this .mLRCURL);
0307: }
0308:
0309: List res = new ArrayList(3);
0310:
0311: //query the lrc
0312: try {
0313: List l = mLRC.getPFN(lfn);
0314: for (Iterator it = l.iterator(); it.hasNext();) {
0315: String pfn = ((RLSString2) it.next()).s2;
0316: //get hold of all attributes
0317: ReplicaCatalogEntry entry = new ReplicaCatalogEntry(
0318: pfn, getAttributes(pfn));
0319: res.add(entry);
0320: }
0321: } catch (RLSException ex) {
0322: if (ex.GetRC() == RLSClient.RLS_LFN_NEXIST
0323: || ex.GetRC() == RLSClient.RLS_MAPPING_NEXIST) {
0324: log("Mapping for lfn " + lfn + " does not exist",
0325: LogManager.DEBUG_MESSAGE_LEVEL);
0326: } else {
0327: throw exception("lookup(String)", ex);
0328: }
0329: }
0330:
0331: return res;
0332:
0333: }
0334:
0335: /**
0336: * Retrieves all entries for a given LFN from the replica catalog.
0337: * Each entry in the result set is just a PFN string. Duplicates
0338: * are reduced through the set paradigm.
0339: *
0340: * @param lfn is the logical filename to obtain information for.
0341: * @return a set of PFN strings, or null in case of unable to connect
0342: * to RLS.
0343: *
0344: */
0345: public Set lookupNoAttributes(String lfn) {
0346: //sanity check
0347: if (this .isClosed()) {
0348: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
0349: + this .mLRCURL);
0350: }
0351:
0352: Set res = new HashSet(3);
0353:
0354: //query the lrc
0355: try {
0356: List l = mLRC.getPFN(lfn);
0357: for (Iterator it = l.iterator(); it.hasNext();) {
0358: String pfn = ((RLSString2) it.next()).s2;
0359: res.add(pfn);
0360: }
0361: } catch (RLSException ex) {
0362: //am not clear whether to throw the exception or what
0363: log("lookup(String,String):", ex,
0364: LogManager.ERROR_MESSAGE_LEVEL);
0365: return null;
0366: }
0367:
0368: return res;
0369:
0370: }
0371:
0372: /**
0373: * Retrieves multiple entries for a given logical filename, up to the
0374: * complete LRC. It uses the bulk query api to the LRC to query for stuff.
0375: * Bulk query has been in RLS since version 2.0.8. Internally, the bulk
0376: * queries are done is sizes specified by variable mBatchSize.
0377: *
0378: * @param lfns is a set of logical filename strings to look up.
0379: * @return a map indexed by the LFN. Each value is a collection
0380: * of replica catalog entries for the LFN.
0381: * @see ReplicaCatalogEntry
0382: * @see #getBatchSize()
0383: */
0384: public Map lookup(Set lfns) throws ReplicaCatalogException {
0385: //one has to do a bulk query in batches
0386: Set s = null;
0387: int size = mBatchSize;
0388: Map map = new HashMap(lfns.size());
0389:
0390: log("Number of files to query LRC " + lfns.size()
0391: + " in batch sizes of " + size,
0392: LogManager.DEBUG_MESSAGE_LEVEL);
0393:
0394: for (Iterator it = lfns.iterator(); it.hasNext();) {
0395: s = new HashSet(size);
0396: for (int j = 0; (j < size) && (it.hasNext()); j++) {
0397: s.add(it.next());
0398: }
0399: if (!s.isEmpty()) {
0400: //there is no conflict, as the keys are unique
0401: //via the set paradigm. Passing null as we want
0402: //to get hold of all attributes.
0403: map.putAll(bulkLookup(s, null));
0404: }
0405:
0406: }
0407:
0408: return map;
0409: }
0410:
0411: /**
0412: * Retrieves multiple entries for a given logical filename, up to the
0413: * complete LRC.
0414: *
0415: * The <code>noAttributes</code> flag is missing on purpose, because
0416: * due to the resource handle, attribute lookups are already required.
0417: *
0418: * @param lfns is a set of logical filename strings to look up.
0419: * @param handle is the resource handle, restricting the LFNs.
0420: * @return a map indexed by the LFN. Each value is a collection
0421: * of replica catalog entries.
0422: *
0423: * @see ReplicaCatalogEntry
0424: */
0425: public Map lookup(Set lfns, String handle) {
0426: return lookup(lfns, SITE_ATTRIBUTE, handle);
0427: }
0428:
0429: /**
0430: * Retrieves multiple entries for a given logical filename, up to the
0431: * complete LRC. It returns the complete RCE for each entry i.e all the
0432: * attributes a pfn is associated with in addition to the one that is
0433: * the key for matching.
0434: *
0435: * @param lfns is a set of logical filename strings to look up.
0436: * @param name is the name of the attribute.
0437: * @param value is the value of the attribute.
0438: *
0439: * @return a map indexed by the LFN. Each value is a collection
0440: * of replica catalog entries.
0441: *
0442: * @see ReplicaCatalogEntry
0443: */
0444: public Map lookup(Set lfns, String name, Object value) {
0445: //one has to do a bulk query in batches
0446: Set s = null;
0447: int size = mBatchSize;
0448: Map map = new HashMap(lfns.size());
0449:
0450: log("Number of files to query LRC " + lfns.size()
0451: + " in batch sizes of " + size,
0452: LogManager.DEBUG_MESSAGE_LEVEL);
0453:
0454: for (Iterator it = lfns.iterator(); it.hasNext();) {
0455: s = new HashSet(size);
0456: for (int j = 0; (j < size) && (it.hasNext()); j++) {
0457: s.add(it.next());
0458: }
0459: if (!s.isEmpty()) {
0460: //there is no conflict, as the keys are unique
0461: //via the set paradigm.
0462: //temp contains results indexed by lfn but each value
0463: //is a collection of ReplicaCatalogEntry objects
0464: //we query for all attributes as we are to return
0465: //complete RCE as stipulated by the interface.
0466: Map temp = bulkLookup(s, null);
0467: //iterate thru it
0468: for (Iterator it1 = temp.entrySet().iterator(); it1
0469: .hasNext();) {
0470: Map.Entry entry = (Map.Entry) it1.next();
0471: Set pfns = subset((Collection) entry.getValue(),
0472: name, value);
0473: if (!pfns.isEmpty()) {
0474: map.put(entry.getKey(), pfns);
0475: }
0476: }
0477: }
0478:
0479: }
0480:
0481: return map;
0482: }
0483:
0484: /**
0485: * Retrieves multiple entries for a given logical filename, up to the
0486: * complete catalog. Retrieving full catalogs should be harmful, but
0487: * may be helpful in an online display or portal.
0488: *
0489: * @param lfns is a set of logical filename strings to look up.
0490: * @return a map indexed by the LFN. Each value is a set
0491: * of PFN strings.
0492: */
0493: public Map lookupNoAttributes(Set lfns) {
0494: //one has to do a bulk query in batches
0495: Set s = null;
0496: int size = mBatchSize;
0497: size = (size > lfns.size()) ? lfns.size() : size;
0498: Map map = new HashMap(lfns.size());
0499:
0500: log("Number of files to query LRC " + lfns.size()
0501: + " in batch sizes of " + size,
0502: LogManager.DEBUG_MESSAGE_LEVEL);
0503:
0504: for (Iterator it = lfns.iterator(); it.hasNext();) {
0505: s = new HashSet(size);
0506: for (int j = 0; (j < size) && (it.hasNext()); j++) {
0507: s.add(it.next());
0508: }
0509: if (!s.isEmpty()) {
0510: //there is no conflict, as the keys are unique
0511: //via the set paradigm.
0512: map.putAll(bulkLookupNoAttributes(s));
0513: }
0514:
0515: }
0516:
0517: return map;
0518: }
0519:
0520: /**
0521: * Retrieves multiple entries for a given logical filename, up to the
0522: * complete catalog. Retrieving full catalogs should be harmful, but
0523: * may be helpful in online display or portal.<p>
0524: *
0525: * @param lfns is a set of logical filename strings to look up.
0526: * @param handle is the resource handle, restricting the LFNs.
0527: *
0528: * @return a map indexed by the LFN. Each value is a set of
0529: * physical filenames.
0530: */
0531: public Map lookupNoAttributes(Set lfns, String handle) {
0532: return lookupNoAttributes(lfns, SITE_ATTRIBUTE, handle);
0533: }
0534:
0535: /**
0536: * Retrieves multiple entries for a given logical filename, up to the
0537: * complete catalog. Retrieving full catalogs should be harmful, but
0538: * may be helpful in online display or portal.<p>
0539: *
0540: * @param lfns is a set of logical filename strings to look up.
0541: * @param name is the PFN attribute name to look for.
0542: * @param value is an exact match of the attribute value to match.
0543: *
0544: * @return a map indexed by the LFN. Each value is a set of
0545: * physical filenames.
0546: */
0547: public Map lookupNoAttributes(Set lfns, String name, Object value) {
0548: //one has to do a bulk query in batches
0549: Set s = null;
0550: Collection c;
0551: int size = mBatchSize;
0552: Map map = new HashMap(lfns.size());
0553:
0554: log("Number of files to query LRC " + lfns.size()
0555: + " in batch sizes of " + size,
0556: LogManager.DEBUG_MESSAGE_LEVEL);
0557:
0558: for (Iterator it = lfns.iterator(); it.hasNext();) {
0559: s = new HashSet(size);
0560: for (int j = 0; (j < size) && (it.hasNext()); j++) {
0561: s.add(it.next());
0562: }
0563: if (!s.isEmpty()) {
0564: //there is no conflict, as the keys are unique
0565: //via the set paradigm.
0566: //temp contains results indexed by lfn but each value
0567: //is a collection of ReplicaCatalogEntry objects
0568: Map temp = bulkLookup(s, name, value);
0569: //iterate thru it
0570: for (Iterator it1 = temp.entrySet().iterator(); it1
0571: .hasNext();) {
0572: Map.Entry entry = (Map.Entry) it1.next();
0573: c = (Collection) entry.getValue();
0574: //System.out.println("Entry is " + entry);
0575: Set pfns = new HashSet(c.size());
0576: for (Iterator cit = c.iterator(); cit.hasNext();) {
0577: pfns.add(((ReplicaCatalogEntry) cit.next())
0578: .getPFN());
0579: }
0580: if (!pfns.isEmpty()) {
0581: map.put(entry.getKey(), pfns);
0582: }
0583: }
0584: }
0585:
0586: }
0587:
0588: return map;
0589: }
0590:
0591: /**
0592: * Retrieves multiple entries for a given logical filename, up to the
0593: * complete catalog. Retrieving full catalogs should be harmful, but
0594: * may be helpful in online display or portal.<p>
0595: *
0596: * At present it DOES NOT SUPPORT ATTRIBUTE MATCHING.
0597: *
0598: * @param constraints is mapping of keys 'lfn', 'pfn', to a string that
0599: * has some meaning to the implementing system. This can be a SQL
0600: * wildcard for queries, or a regular expression for Java-based memory
0601: * collections. Unknown keys are ignored. Using an empty map requests
0602: * the complete catalog.
0603: *
0604: * @return a map indexed by the LFN. Each value is a collection
0605: * of replica catalog entries.
0606: *
0607: * @see ReplicaCatalogEntry
0608: */
0609: public Map lookup(Map constraints) throws ReplicaCatalogException {
0610: return (constraints.isEmpty()) ? lookup(list())
0611: : getAttributes(lookupLFNPFN(constraints), null, null);
0612: }
0613:
0614: /**
0615: * Retrieves multiple entries for a given logical filename, up to the
0616: * complete catalog. Retrieving full catalogs should be harmful, but
0617: * may be helpful in online display or portal. At present it does not
0618: * support attribute matching.
0619: *
0620: * @param constraints is mapping of keys 'lfn', 'pfn', or any
0621: * attribute name, e.g. the resource handle 'site', to a string that
0622: * has some meaning to the implementing system. This can be a SQL
0623: * wildcard for queries, or a regular expression for Java-based memory
0624: * collections. Unknown keys are ignored. Using an empty map requests
0625: * the complete catalog.
0626: *
0627: * @return A list of <code>MyRLSString2Bulk</code> objects containing
0628: * the lfn in s1 field, and pfn in s2 field. The list is
0629: * grouped by lfns. The set may be empty.
0630: */
0631: public List lookupLFNPFN(Map constraints) {
0632: if (isClosed()) {
0633: //not connected to LRC
0634: //throw an exception??
0635: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
0636: + this .mLRCURL);
0637: }
0638: /*
0639: if(constraints == null || constraints.isEmpty()){
0640: //return the set of all LFNs in the catalog
0641: return list();
0642: }*/
0643:
0644: List result = new ArrayList();
0645: boolean notFirst = false;
0646:
0647: for (Iterator i = constraints.keySet().iterator(); i.hasNext();) {
0648: String key = (String) i.next();
0649: if (key.equals("lfn")) {
0650: if (notFirst) {
0651: //do the AND(intersect)operation
0652: result.retainAll(listLFNPFN((String) constraints
0653: .get(key), true));
0654: } else {
0655: result = listLFNPFN((String) constraints.get(key),
0656: true);
0657: }
0658: } else if (key.equals("pfn")) {
0659: if (notFirst) {
0660: //do the AND(intersect)operation
0661: result.retainAll(listLFNPFN((String) constraints
0662: .get(key), false));
0663: } else {
0664: result = listLFNPFN((String) constraints.get(key),
0665: false);
0666: }
0667: } else {
0668: //just a warning
0669: log("Implementation does not support constraint "
0670: + "matching of type " + key,
0671: LogManager.WARNING_MESSAGE_LEVEL);
0672: }
0673: if (result.isEmpty()) {
0674: //the intersection is already empty. No use matching further
0675: break;
0676: }
0677: notFirst = true;
0678: }
0679:
0680: //sort according to lfn
0681: Collections.sort(result, new RLSString2BulkComparator());
0682:
0683: return result;
0684: }
0685:
0686: /**
0687: * Lists all logical filenames in the catalog.
0688: *
0689: * @return a set of all logical filenames known to the catalog or null in
0690: * case of not connected to the LRC or error.
0691: */
0692: public Set list() {
0693: return list("*");
0694: }
0695:
0696: /**
0697: * Lists a subset of all logical filenames in the catalog.
0698: *
0699: * @param constraint is a constraint for the logical filename only. It
0700: * is a string that has some meaning to the implementing system. This
0701: * can be a SQL wildcard for queries, or a regular expression for
0702: * Java-based memory collections.
0703: *
0704: * @return A set of logical filenames that match. The set may be empty
0705: */
0706: public Set list(String constraint) {
0707: List l = listLFNPFN(constraint, true);
0708: Set result = new HashSet(l.size());
0709: for (Iterator it = l.iterator(); it.hasNext();) {
0710: RLSString2Bulk rs = (RLSString2Bulk) it.next();
0711: result.add(rs.s1);
0712: }
0713: return result;
0714: }
0715:
0716: /**
0717: * Lists a subset of all LFN,PFN pairs in the catalog matching to
0718: * a pfn or a lfn constraint.
0719: *
0720: * @param constraint is a constraint for the logical filename only. It
0721: * is a string that has some meaning to the implementing system. This
0722: * can be a SQL wildcard for queries, or a regular expression for
0723: * Java-based memory collections.
0724: *
0725: * @return A set a list of <code>MyRLSString2Bulk</code> objects containing
0726: * the lfn in s1 field, and pfn in s2 field. The list is
0727: * grouped by lfns. The set may be empty.
0728: *
0729: * @see #getAttributes(List,String,Object)
0730: */
0731: public List listLFNPFN(String constraint, boolean lfnConstraint)
0732: throws ReplicaCatalogException {
0733: if (isClosed()) {
0734: //not connected to LRC
0735: //throw an exception??
0736: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
0737: + this .mLRCURL);
0738: }
0739:
0740: int size = getBatchSize();
0741: List l = new ArrayList();
0742: ArrayList result = new ArrayList();
0743: int capacity = size;
0744:
0745: //do a wildcard query in batch sizes
0746: RLSOffsetLimit offset = new RLSOffsetLimit(0, size);
0747: while (true) {
0748: try {
0749: l = (lfnConstraint) ?
0750: //do lfn matching
0751: mLRC.getPFNWC(constraint, offset)
0752: :
0753: //do pfn matching
0754: mLRC.getLFNWC(constraint, offset);
0755:
0756: //we need to group pfns by lfn
0757: Collections.sort(l, new RLSString2Comparator());
0758: } catch (RLSException e) {
0759: if (e.GetRC() == RLSClient.RLS_PFN_NEXIST
0760: || e.GetRC() == RLSClient.RLS_LFN_NEXIST
0761: || e.GetRC() == RLSClient.RLS_MAPPING_NEXIST) {
0762: log(
0763: "listLFNPFN(String, boolean) :Mapping matching constraint "
0764: + constraint + " does not exist",
0765: LogManager.ERROR_MESSAGE_LEVEL);
0766: } else {
0767: //am not clear whether to throw the exception or what
0768: log("list()", e, LogManager.ERROR_MESSAGE_LEVEL);
0769: }
0770: //return empty list
0771: return new ArrayList(0);
0772: }
0773: //result = new ArrayList(l.size());
0774: //increment the size of the list
0775: //but first the capacity
0776: capacity += l.size();
0777: result.ensureCapacity(capacity);
0778:
0779: for (Iterator it = l.iterator(); it.hasNext();) {
0780: RLSString2 res = (RLSString2) it.next();
0781: result.add(convert(res));
0782: }
0783: if (offset.offset == -1)
0784: break;//offset is set to -1 when no more results
0785:
0786: }
0787:
0788: return result;
0789:
0790: }
0791:
0792: /**
0793: * Inserts multiple mappings into the replica catalog. The input is a
0794: * map indexed by the LFN. The value for each LFN key is a collection
0795: * of replica catalog entries. Ends up doing a sequential insert for all
0796: * the entries instead of doing a bulk insert. Easier to track failure this
0797: * way.
0798: *
0799: * @param x is a map from logical filename string to list of replica
0800: * catalog entries.
0801: * @return the number of insertions.
0802: * @see ReplicaCatalogEntry
0803: */
0804: public int insert(Map x) {
0805: int result = 0;
0806: String lfn;
0807: ReplicaCatalogEntry rce = null;
0808:
0809: // Not doing sequential inserts any longer
0810: // Karan April 9, 2006
0811: // Collection c;
0812: // for(Iterator it = x.entrySet().iterator();it.hasNext();){
0813: // Map.Entry entry = (Map.Entry)it.next();
0814: // lfn = (String)entry.getKey();
0815: // c = (Collection)entry.getValue();
0816: // log("Inserting entries for lfn " + lfn,
0817: // LogManager.DEBUG_MESSAGE_LEVEL);
0818: // for(Iterator pfnIt = c.iterator();pfnIt.hasNext();){
0819: // try{
0820: // rce = (ReplicaCatalogEntry)pfnIt.next();
0821: // insert(lfn,rce);
0822: // res += 1;
0823: // }
0824: // catch(ReplicaCatalogException e){
0825: // log("Inserting lfn->pfn " +
0826: // lfn + "->" + rce.getPFN(),e,
0827: // LogManager.ERROR_MESSAGE_LEVEL);
0828: // }
0829: // }
0830: // }
0831: // return res;
0832:
0833: int size = this .getBatchSize();
0834: int current = 0;
0835: String pfn;
0836: List lfnPfns = new ArrayList(size);
0837: List attrs = new ArrayList(size);
0838: CatalogException exception = new ReplicaCatalogException();
0839:
0840: //indexed by pfn and values as RLSAttributeObject objects
0841: Map attrMap = new HashMap(size);
0842:
0843: for (Iterator it = x.entrySet().iterator(); it.hasNext();) {
0844: Map.Entry entry = (Map.Entry) it.next();
0845: lfn = (String) entry.getKey();
0846: Collection c = (Collection) entry.getValue();
0847:
0848: //traverse through the rce's for the pfn's
0849: for (Iterator pfnIt = c.iterator(); pfnIt.hasNext();) {
0850: rce = (ReplicaCatalogEntry) pfnIt.next();
0851: pfn = rce.getPFN();
0852: lfnPfns.add(new RLSString2(lfn, pfn));
0853:
0854: //increment current only once per pfn
0855: if (rce.getAttributeCount() == 0)
0856: current++;
0857:
0858: //build the attributes list
0859: for (Iterator attrIt = rce.getAttributeIterator(); attrIt
0860: .hasNext(); current++) {
0861: String key = (String) attrIt.next();
0862: RLSAttribute attr = new RLSAttribute(key,
0863: RLSAttribute.LRC_PFN, (String) rce
0864: .getAttribute(key));
0865: attrs.add(new RLSAttributeObject(attr, pfn));
0866: attrMap.put(pfn, new RLSAttributeObject(attr, pfn));
0867: }
0868: }
0869: //check if diff is more than batch size
0870: if (current >= size) {
0871: //we have the subset of RCE's on which we
0872: //want to do bulk inserts, and the value till
0873: //we want to do bulk inserts
0874: try {
0875: result += bulkInsert(lfnPfns, attrMap);
0876: } catch (ReplicaCatalogException e) {
0877: exception.setNextException(e);
0878: }
0879:
0880: //reset data structures
0881: current = 0;
0882: lfnPfns.clear();
0883: attrs.clear();
0884: attrMap.clear();
0885: }
0886: }
0887: //check for the last bunch
0888: if (!lfnPfns.isEmpty()) {
0889: //we have the subset of RCE's on which we
0890: //want to do bulk inserts, and the value till
0891: //we want to do bulk inserts
0892: try {
0893: result += bulkInsert(lfnPfns, attrMap);
0894: } catch (ReplicaCatalogException e) {
0895: exception.setNextException(e);
0896: }
0897: current = 0;
0898: }
0899:
0900: //throw an exception only if a nested exception
0901: if ((exception = exception.getNextException()) != null)
0902: throw exception;
0903:
0904: return result;
0905: }
0906:
0907: /**
0908: * Calls the bulk delete on the mappings. This function can timeout if the
0909: * size of the list passed is too large.
0910: *
0911: * @param lfnPfns list of <code>RLSString2</code> objects containing the
0912: * lfn pfn mappings to be deleted.
0913: *
0914: * @return the number of items deleted
0915: *
0916: * @throws ReplicaCatalogException in case of error
0917: */
0918: private int bulkDelete(List lfnPfns) throws ReplicaCatalogException {
0919: if (isClosed()) {
0920: //not connected to LRC
0921: //throw an exception??
0922: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
0923: + this .mLRCURL);
0924: }
0925:
0926: //result only tracks successful lfn->pfn mappings
0927: int result = lfnPfns.size();
0928: Collection failedDeletes;
0929: CatalogException exception = new ReplicaCatalogException();
0930:
0931: //do a bulk delete
0932: //FIX ME: The deletes should have been done in batches.
0933: try {
0934: failedDeletes = mLRC.deleteBulk((ArrayList) lfnPfns);
0935: } catch (RLSException e) {
0936: mLogger.log("RLS: Bulk Delete ", e,
0937: LogManager.ERROR_MESSAGE_LEVEL);
0938: throw new ReplicaCatalogException("RLS: Bulk Delete "
0939: + e.getMessage());
0940: }
0941:
0942: if (!failedDeletes.isEmpty()) {
0943: result -= failedDeletes.size();
0944: //FIXME: Do we really care about failed deletes
0945: //and reporting why deletes failed.
0946: // i think we do.
0947: RLSString2Bulk rs;
0948: int error;
0949: for (Iterator it = failedDeletes.iterator(); it.hasNext();) {
0950: rs = (RLSString2Bulk) it.next();
0951: error = rs.rc;
0952:
0953: if (error == RLSClient.RLS_PFN_NEXIST
0954: || error == RLSClient.RLS_LFN_NEXIST
0955: || error == RLSClient.RLS_MAPPING_NEXIST) {
0956:
0957: log("Mapping " + rs.s1 + "->" + rs.s2
0958: + " does not exist",
0959: LogManager.DEBUG_MESSAGE_LEVEL);
0960: } else {
0961: exception.setNextException(exception(rs));
0962: }
0963: }
0964:
0965: }
0966:
0967: //throw an exception only if a nested exception
0968: if ((exception = exception.getNextException()) != null)
0969: throw exception;
0970:
0971: return result;
0972:
0973: }
0974:
0975: /**
0976: * Calls the bulk insert on the mappings. This function can timeout if the
0977: * size of the list passed is too large.
0978: *
0979: * @param lfnPfns list of <code>RLSString2</code> objects containing the
0980: * lfn pfn mappings to be inserted.
0981: * @param attrMap a map indexed by pfn and values as RLSAttributeObject objects.
0982: *
0983: * @return the number of items inserted
0984: *
0985: * @throws ReplicaCatalogException in case of error
0986: */
0987: private int bulkInsert(List lfnPfns, Map attrMap) {
0988: if (isClosed()) {
0989: //not connected to LRC
0990: //throw an exception??
0991: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
0992: + this .mLRCURL);
0993: }
0994:
0995: //result only tracks successful lfn->pfn mappings
0996: int result = lfnPfns.size();
0997:
0998: List failedCreates;
0999: List failedAdds;
1000: CatalogException exception = new ReplicaCatalogException();
1001:
1002: try {
1003: /* bulk insert on mappings starts*/
1004: failedCreates = mLRC.createBulk((ArrayList) lfnPfns);
1005:
1006: //try to do a bulkAdd on the failed creates
1007: List bulkAdd = new ArrayList(failedCreates.size());
1008: for (Iterator it = failedCreates.iterator(); it.hasNext();) {
1009: RLSString2Bulk rs = (RLSString2Bulk) it.next();
1010: if (rs.rc == RLSClient.RLS_LFN_EXIST) {
1011: //s1 is lfn and s2 is pfn
1012: bulkAdd.add(new RLSString2(rs.s1, rs.s2));
1013: } else {
1014: exception.setNextException(exception(rs));
1015: result--;
1016: }
1017: }
1018:
1019: //do a bulk add if list non empty
1020: if (!bulkAdd.isEmpty()) {
1021: failedAdds = mLRC.addBulk((ArrayList) bulkAdd);
1022: //pipe all the failed adds to the exception
1023: for (Iterator it = failedAdds.iterator(); it.hasNext();) {
1024: RLSString2Bulk rs = (RLSString2Bulk) it.next();
1025:
1026: //just log that mapping already exists
1027: if (rs.rc == RLSClient.RLS_MAPPING_EXIST) {
1028: //we want to log instead of throwning an exception
1029: log("LFN-PFN Mapping alreadys exists in LRC "
1030: + mLRCURL + " for " + rs.s1 + "->"
1031: + rs.s2, LogManager.DEBUG_MESSAGE_LEVEL);
1032: result--;
1033:
1034: } else {
1035: exception.setNextException(exception(rs));
1036: result--;
1037: }
1038: }
1039: }
1040: /*bulk insert on mappings ends */
1041:
1042: /*bulk insert on attributes starts */
1043: ArrayList failedAttrs;//the failed attributes
1044:
1045: //build the attribute list
1046: ArrayList attrs = new ArrayList(attrMap.size());
1047: int num = 0;
1048: for (Iterator it = attrMap.values().iterator(); it
1049: .hasNext(); num++) {
1050: attrs.add(it.next());
1051: }
1052:
1053: //try a bulk add on attributes assuming attrs already exist
1054: failedAttrs = mLRC.attributeAddBulk((ArrayList) attrs);
1055:
1056: //go through the failed attributes and create them
1057: for (Iterator it = failedAttrs.iterator(); it.hasNext();) {
1058: RLSString2Bulk s2b = (RLSString2Bulk) it.next();
1059: /*
1060: RLSAttribute attributeToAdd =
1061: new RLSAttribute(s2b.s2,RLSAttribute.LRC_PFN,
1062: (String)tuple.getAttribute(s2b.s2));
1063: */
1064:
1065: //s1 is the pfn
1066: //s2 is the attribute name
1067: String pfn = s2b.s1;
1068: RLSAttributeObject attrObject = (RLSAttributeObject) attrMap
1069: .get(pfn);
1070: RLSAttribute attributeToAdd = attrObject.attr;
1071:
1072: if (s2b.rc == RLSClient.RLS_ATTR_NEXIST) {
1073: //we need to create the attribute
1074: log("Creating an attribute name " + s2b.s2
1075: + " for pfn " + pfn,
1076: LogManager.DEBUG_MESSAGE_LEVEL);
1077: try {
1078: //FIXME : should have done a bulkAttributeCreate that doesnt exist
1079: mLRC.attributeCreate(s2b.s2,
1080: RLSAttribute.LRC_PFN, RLSAttribute.STR);
1081: //add the attribute in sequentially instead of bulk
1082: mLRC.attributeAdd(pfn, attributeToAdd);
1083:
1084: } catch (RLSException e) {
1085: //ignore any attribute already exist error
1086: //case of multiple creates of same attribute
1087: if (e.GetRC() != RLSClient.RLS_ATTR_EXIST) {
1088: exception
1089: .setNextException(new ReplicaCatalogException(
1090: "Adding attrib to pfn "
1091: + pfn + " "
1092: + e.getMessage()));
1093: }
1094: }
1095: } else if (s2b.rc == RLSClient.RLS_ATTR_EXIST) {
1096: log("Attribute " + s2b.s2 + " for pfn " + pfn
1097: + " already exists",
1098: LogManager.DEBUG_MESSAGE_LEVEL);
1099: //get the existing value of attribute
1100: List l = null;
1101: try {
1102: l = mLRC.attributeValueGet(pfn, s2b.s2,
1103: RLSAttribute.LRC_PFN);
1104: } catch (RLSException e) {
1105: exception
1106: .setNextException(new ReplicaCatalogException(
1107: "Getting value of existing attrib "
1108: + e.getMessage()));
1109: }
1110: if (l == null || l.isEmpty() || l.size() > 1) {
1111: log("Contents of list are " + l,
1112: LogManager.DEBUG_MESSAGE_LEVEL);
1113: //should never happen
1114: log("Unreachable case.",
1115: LogManager.FATAL_MESSAGE_LEVEL);
1116: throw new ReplicaCatalogException(
1117: "Whammy while trying to get value of an exisiting attribute "
1118: + s2b.s2
1119: + " associated with PFN " + pfn);
1120: }
1121:
1122: //try to see if it matches with the existing value
1123: RLSAttribute attribute = (RLSAttribute) l.get(0);
1124: if (!attribute.GetStrVal().equalsIgnoreCase(
1125: attributeToAdd.GetStrVal())) {
1126:
1127: //log a warning saying updating value
1128: mLogMsg = "Existing value for attribute "
1129: + s2b.s2 + " associated with PFN "
1130: + pfn + " updated with new value "
1131: + attributeToAdd.GetStrVal();
1132:
1133: //update the value
1134: try {
1135: mLRC.attributeModify(pfn, attributeToAdd);
1136: log(mLogMsg,
1137: LogManager.WARNING_MESSAGE_LEVEL);
1138: } catch (RLSException e) {
1139: exception
1140: .setNextException(new ReplicaCatalogException(
1141: "RLS Exception "
1142: + e.getMessage()));
1143: }
1144: }
1145: } else {
1146: exception.setNextException(exception(s2b));
1147: }
1148: }
1149:
1150: /*bulk insert on attributes ends */
1151:
1152: } catch (RLSException e) {
1153: exception.setNextException(new ReplicaCatalogException(
1154: "RLS Exception " + e.getMessage()));
1155: }
1156:
1157: //throw an exception only if a nested exception
1158: if ((exception = exception.getNextException()) != null)
1159: throw exception;
1160:
1161: return result;
1162: }
1163:
1164: /**
1165: * Inserts a new mapping into the replica catalog. The attributes are added
1166: * in bulk assuming the attribute definitions already exist. If an attribute
1167: * definition does not exist, it is created and inserted. Note there is no
1168: * notion of transactions in LRC. It assumes all the attributes are of type
1169: * String.
1170: *
1171: * @param lfn is the logical filename under which to book the entry.
1172: * @param tuple is the physical filename and associated PFN attributes.
1173: *
1174: * @return number of insertions, should always be 1. On failure,
1175: * throws an exception instead of returning zero.
1176: */
1177: public int insert(String lfn, ReplicaCatalogEntry tuple) {
1178: Map m = new HashMap(1);
1179: List l = new ArrayList(1);
1180: l.add(tuple);
1181: m.put(lfn, l);
1182: return insert(m);
1183:
1184: // Just composing the call to insert(Map method)
1185: // Only one code handles inserts. Karan April 12, 2006
1186: // if(isClosed()){
1187: // //not connected to LRC
1188: // //throw an exception??
1189: // throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG + this.mLRCURL);
1190: // }
1191: // int res = 0;
1192:
1193: // //we have no notion of transaction at this point.
1194: // String pfn = tuple.getPFN();
1195: // try{
1196: // //insert the pfn
1197: // mLRC.add(lfn, pfn);
1198: // }
1199: // catch(RLSException e){
1200: // if(e.GetRC() == RLSClient.RLS_LFN_NEXIST){
1201: // //the first instance of the lfn, so we add
1202: // //instead of creating the mapping
1203: // try{
1204: // mLRC.create(lfn, pfn);
1205: // }
1206: // catch(RLSException ex){
1207: // throw new ReplicaCatalogException("RLS Exception "+ ex.getMessage());
1208: // }
1209: // }
1210: // else if(e.GetRC() == RLSClient.RLS_MAPPING_EXIST){
1211: // log("LFN-PFN Mapping alreadys exists in LRC "
1212: // + mLRCURL + " for " + lfn + "->" + pfn,
1213: // LogManager.ERROR_MESSAGE_LEVEL);
1214: // return res;
1215: // }
1216: // else
1217: // throw new ReplicaCatalogException("RLS Exception "+ e.getMessage());
1218: // }
1219: //
1220: // //we need to add attributes in bulk
1221: // String key;
1222: // ArrayList failedAttrs;//the failed attributes
1223: // ArrayList attrs = new ArrayList(tuple.getAttributeCount());
1224: // for(Iterator it = tuple.getAttributeIterator(); it.hasNext();){
1225: // key = (String)it.next();
1226: // RLSAttribute attr = new RLSAttribute(key,RLSAttribute.LRC_PFN,
1227: // (String)tuple.getAttribute(key));
1228: // attrs.add(new RLSAttributeObject(attr,pfn));
1229: //
1230: // }
1231: //
1232: // try{
1233: // failedAttrs = mLRC.attributeAddBulk(attrs);
1234: // }
1235: // catch(RLSException e){
1236: // throw new ReplicaCatalogException("RLS Exception "+ e.getMessage());
1237: // }
1238: //
1239: // //go through the failed attributes and create them
1240: // for(Iterator it = failedAttrs.iterator();it.hasNext();){
1241: // RLSString2Bulk s2b = (RLSString2Bulk)it.next();
1242: // RLSAttribute attributeToAdd = new RLSAttribute(s2b.s2,RLSAttribute.LRC_PFN,
1243: // (String)tuple.getAttribute(s2b.s2));
1244: // //s1 is the pfn
1245: // //s2 is the attribute name
1246: // if(s2b.rc == RLSClient.RLS_ATTR_NEXIST){
1247: // //we need to create the attribute
1248: // log("Creating an attribute name " + s2b.s2 +
1249: // " for pfn " + pfn, LogManager.DEBUG_MESSAGE_LEVEL);
1250: // try{
1251: // mLRC.attributeCreate(s2b.s2, RLSAttribute.LRC_PFN,
1252: // RLSAttribute.STR);
1253: // //add the attribute in sequentially instead of bulk
1254: // mLRC.attributeAdd(pfn,attributeToAdd);
1255: //
1256: // }
1257: // catch(RLSException e){
1258: // throw new ReplicaCatalogException("RLS Exception "+ e.getMessage());
1259: // }
1260: // }
1261: // else if(s2b.rc == RLSClient.RLS_ATTR_EXIST){
1262: // log("Attribute " + s2b.s2 + " for pfn " + pfn +
1263: // " already exists", LogManager.DEBUG_MESSAGE_LEVEL);
1264: // //get the existing value of attribute
1265: // List l = null;
1266: // try{
1267: // l = mLRC.attributeValueGet(pfn, s2b.s2, RLSAttribute.LRC_PFN);
1268: // }
1269: // catch(RLSException e){
1270: // throw new ReplicaCatalogException("RLS Exception "+ e.getMessage());
1271: // }
1272: // if(l == null || l.isEmpty() || l.size() > 1){
1273: // log("Contents of list are " + l,LogManager.DEBUG_MESSAGE_LEVEL);
1274: // //should never happen
1275: // log("Unreachable case.",LogManager.FATAL_MESSAGE_LEVEL);
1276: // throw new ReplicaCatalogException(
1277: // "Whammy while trying to get value of an exisiting attribute " +
1278: // s2b.s2 + " associated with PFN " + pfn);
1279: // }
1280: // //try to see if it matches with the existing value
1281: // RLSAttribute attribute = (RLSAttribute)l.get(0);
1282: // if(!attribute.GetStrVal().equalsIgnoreCase(
1283: // attributeToAdd.GetStrVal())){
1284: //
1285: // //log a warning saying updating value
1286: // mLogMsg = "Existing value for attribute " + s2b.s2 +
1287: // " associated with PFN " + pfn +
1288: // " updated with new value " + attributeToAdd.GetStrVal();
1289: //
1290: // //update the value
1291: // try{
1292: // mLRC.attributeModify(pfn, attributeToAdd);
1293: // log(mLogMsg,LogManager.WARNING_MESSAGE_LEVEL);
1294: // }
1295: // catch(RLSException e){
1296: // throw new ReplicaCatalogException("RLS Exception" +
1297: // e.getMessage());
1298: // }
1299: // }
1300: // }
1301: // else{
1302: // throw new ReplicaCatalogException(
1303: // "Unknown Error while adding attributes. RLS Error Code " +
1304: // s2b.rc);
1305: // }
1306: // }
1307: //
1308: // return 1;
1309:
1310: }
1311:
1312: /**
1313: * Inserts a new mapping into the replica catalog. This is a
1314: * convenience function exposing the resource handle. Internally,
1315: * the <code>ReplicaCatalogEntry</code> element will be contructed, and passed to
1316: * the appropriate insert function.
1317: *
1318: * @param lfn is the logical filename under which to book the entry.
1319: * @param pfn is the physical filename associated with it.
1320: * @param handle is a resource handle where the PFN resides.
1321: *
1322: * @return number of insertions, should always be 1. On failure,
1323: * throw an exception, don't use zero.
1324: *
1325: * @see #insert( String, ReplicaCatalogEntry )
1326: * @see ReplicaCatalogEntry
1327: */
1328: public int insert(String lfn, String pfn, String handle) {
1329: //prepare the appropriate ReplicaCatalogEntry object
1330: ReplicaCatalogEntry rce = new ReplicaCatalogEntry(pfn, handle);
1331: return insert(lfn, rce);
1332: }
1333:
1334: /**
1335: * Deletes multiple mappings into the replica catalog. The input is a
1336: * map indexed by the LFN. The value for each LFN key is a collection
1337: * of replica catalog entries. On setting matchAttributes to false, all entries
1338: * having matching lfn pfn mapping to an entry in the Map are deleted.
1339: * However, upon removal of an entry, all attributes associated with the pfn
1340: * also evaporate (cascaded deletion).
1341: * The deletes are done in batches.
1342: *
1343: * @param x is a map from logical filename string to list of
1344: * replica catalog entries.
1345: * @param matchAttributes whether mapping should be deleted only if all
1346: * attributes match.
1347: *
1348: * @return the number of deletions.
1349: * @see ReplicaCatalogEntry
1350: */
1351: public int delete(Map x, boolean matchAttributes) {
1352: int result = 0;
1353: if (isClosed()) {
1354: //not connected to LRC
1355: //throw an exception??
1356: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
1357: + this .mLRCURL);
1358: }
1359:
1360: String lfn, pfn;
1361: ReplicaCatalogEntry rce;
1362: Collection c;
1363: CatalogException exception = new ReplicaCatalogException();
1364:
1365: if (matchAttributes) {
1366: //do a sequential delete for the time being
1367: for (Iterator it = x.entrySet().iterator(); it.hasNext();) {
1368: Map.Entry entry = (Map.Entry) it.next();
1369: lfn = (String) entry.getKey();
1370: c = (Collection) entry.getValue();
1371:
1372: //iterate through all RCE's for this lfn and delete
1373: for (Iterator rceIt = c.iterator(); rceIt.hasNext();) {
1374: rce = (ReplicaCatalogEntry) it.next();
1375: result += delete(lfn, rce);
1376: }
1377: }
1378: } else {
1379: //we can use bulk delete
1380: int size = this .getBatchSize();
1381: int current = 0;
1382: List lfnPfns = new ArrayList(size);
1383: for (Iterator it = x.entrySet().iterator(); it.hasNext();) {
1384: Map.Entry entry = (Map.Entry) it.next();
1385: lfn = (String) entry.getKey();
1386: c = (Collection) entry.getValue();
1387:
1388: //traverse through the rce's for the pfn's
1389: for (Iterator pfnIt = c.iterator(); pfnIt.hasNext();) {
1390: rce = (ReplicaCatalogEntry) pfnIt.next();
1391: pfn = rce.getPFN();
1392: lfnPfns.add(new RLSString2(lfn, pfn));
1393: current++;
1394:
1395: //check if diff is more than batch size
1396: if (current >= size) {
1397: //we have the subset of RCE's on which we
1398: //want to do bulk deletes
1399: try {
1400: result += bulkDelete(lfnPfns);
1401: } catch (ReplicaCatalogException e) {
1402: exception.setNextException(e);
1403: }
1404:
1405: current = 0;
1406: lfnPfns.clear();
1407: }
1408:
1409: }
1410: }
1411: //check for the last bunch
1412: if (!lfnPfns.isEmpty()) {
1413: //we have the subset of RCE's on which we
1414: //we want to do bulk deletes
1415: try {
1416: result += bulkDelete(lfnPfns);
1417: } catch (ReplicaCatalogException e) {
1418: exception.setNextException(e);
1419: }
1420:
1421: current = 0;
1422: }
1423: }
1424:
1425: //throw an exception only if a nested exception
1426: if ((exception = exception.getNextException()) != null)
1427: throw exception;
1428:
1429: return result;
1430: }
1431:
1432: /**
1433: * Deletes a specific mapping from the replica catalog. We don't care
1434: * about the resource handle. More than one entry could theoretically
1435: * be removed. Upon removal of an entry, all attributes associated
1436: * with the PFN also evaporate (cascading deletion) automatically at the
1437: * RLS server end.
1438: *
1439: * @param lfn is the logical filename in the tuple.
1440: * @param pfn is the physical filename in the tuple.
1441: *
1442: * @return the number of removed entries.
1443: */
1444: public int delete(String lfn, String pfn) {
1445: int res = 0;
1446: if (isClosed()) {
1447: //not connected to LRC
1448: //throw an exception??
1449: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
1450: + this .mLRCURL);
1451: }
1452:
1453: try {
1454: mLRC.delete(lfn, pfn);
1455: res++;
1456: } catch (RLSException e) {
1457: if (e.GetRC() == RLSClient.RLS_PFN_NEXIST
1458: || e.GetRC() == RLSClient.RLS_LFN_NEXIST
1459: || e.GetRC() == RLSClient.RLS_MAPPING_NEXIST) {
1460: log("Mapping " + lfn + "->" + pfn + " does not exist",
1461: LogManager.DEBUG_MESSAGE_LEVEL);
1462: } else {
1463: throw new ReplicaCatalogException(
1464: "Error while deleting mapping "
1465: + e.getMessage());
1466: }
1467: }
1468: return res;
1469: }
1470:
1471: /**
1472: * Deletes a very specific mapping from the replica catalog. The LFN
1473: * must be matches, the PFN, and all PFN attributes specified in the
1474: * replica catalog entry. More than one entry could theoretically be
1475: * removed. Upon removal of an entry, all attributes associated with
1476: * the PFN also evaporate (cascading deletion).
1477: *
1478: * @param lfn is the logical filename in the tuple.
1479: * @param tuple is a description of the PFN and its attributes.
1480: * @return the number of removed entries, either 0 or 1.
1481: */
1482: public int delete(String lfn, ReplicaCatalogEntry tuple) {
1483: int res = 0;
1484: if (isClosed()) {
1485: //not connected to LRC
1486: //throw an exception??
1487: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
1488: + this .mLRCURL);
1489: }
1490:
1491: //get hold of all the RCE in this LRC matching to lfn
1492: Collection c = lookup(lfn);
1493: ReplicaCatalogEntry rce;
1494: for (Iterator it = c.iterator(); it.hasNext();) {
1495: rce = (ReplicaCatalogEntry) it.next();
1496: if (rce.equals(tuple)) {
1497: //we need to delete the rce
1498: //cascaded deletes take care of the attribute deletes
1499: delete(lfn, tuple.getPFN());
1500: res++;
1501: }
1502: }
1503:
1504: return res;
1505: }
1506:
1507: /**
1508: * Deletes all PFN entries for a given LFN from the replica catalog
1509: * where the PFN attribute is found, and matches exactly the object
1510: * value. This method may be useful to remove all replica entries that
1511: * have a certain MD5 sum associated with them. It may also be harmful
1512: * overkill.
1513: *
1514: * @param lfn is the logical filename to look for.
1515: * @param name is the PFN attribute name to look for.
1516: * @param value is an exact match of the attribute value to match.
1517: *
1518: * @return the number of removed entries.
1519: */
1520: public int delete(String lfn, String name, Object value) {
1521: int result = 0;
1522: Collection c = null;
1523: if (isClosed()) {
1524: //not connected to LRC
1525: //throw an exception??
1526: throw new ReplicaCatalogException(LRC_NOT_CONNECTED_MSG
1527: + this .mLRCURL);
1528: }
1529:
1530: //query lookup for that lfn and delete accordingly.
1531: Set s = new HashSet(1);
1532: s.add(lfn);
1533: Map map = this .lookupNoAttributes(s, name, value);
1534: if (map == null || map.isEmpty()) {
1535: return 0;
1536: }
1537:
1538: //we need to pipe this into a list of RLSString2 objects
1539: ArrayList lfnPfns = new ArrayList(3);
1540: for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
1541: Map.Entry entry = (Map.Entry) it.next();
1542: lfn = (String) entry.getKey();
1543:
1544: for (Iterator it1 = ((Set) entry.getValue()).iterator(); it1
1545: .hasNext();) {
1546: RLSString2 lfnPfn = new RLSString2(lfn, (String) it1
1547: .next());
1548: lfnPfns.add(lfnPfn);
1549: result++;
1550: }
1551:
1552: }
1553:
1554: try {
1555: c = mLRC.deleteBulk(lfnPfns);
1556: } catch (RLSException e) {
1557: log("remove(Set)", e, LogManager.ERROR_MESSAGE_LEVEL);
1558: }
1559:
1560: //c should be empty ideally
1561: if (!c.isEmpty()) {
1562: result -= c.size();
1563: log("Removing lfns remove(Set)" + c,
1564: LogManager.ERROR_MESSAGE_LEVEL);
1565: }
1566: return result;
1567:
1568: }
1569:
1570: /**
1571: * Deletes all PFN entries for a given LFN from the replica catalog
1572: * where the resource handle is found. Karan requested this
1573: * convenience method, which can be coded like
1574: * <pre>
1575: * delete( lfn, SITE_ATTRIBUTE, handle )
1576: * </pre>
1577: *
1578: * @param lfn is the logical filename to look for.
1579: * @param handle is the resource handle
1580: *
1581: * @return the number of entries removed.
1582: *
1583: * @see #SITE_ATTRIBUTE
1584: */
1585: public int deleteByResource(String lfn, String handle) {
1586: return delete(lfn, SITE_ATTRIBUTE, handle);
1587: }
1588:
1589: /**
1590: * Removes all mappings for a set of LFNs.
1591: *
1592: * @param lfn is a set of logical filename to remove all mappings for.
1593: *
1594: * @return the number of removed entries.
1595: */
1596: public int remove(String lfn) {
1597: //first get hold of all the pfn mappings for the lfn
1598: Collection c = this .lookupNoAttributes(lfn);
1599: int result = 0;
1600: if (c == null || c.isEmpty()) {
1601: return 0;
1602: }
1603:
1604: //we need to pipe this into a list of RLSString2Bulk objects
1605: result = c.size();
1606: ArrayList lfnPfns = new ArrayList(result);
1607: for (Iterator it = c.iterator(); it.hasNext();) {
1608: RLSString2 lfnPfn = new RLSString2(lfn, (String) it.next());
1609: lfnPfns.add(lfnPfn);
1610: }
1611:
1612: //do a bulk delete
1613: try {
1614: c = mLRC.deleteBulk(lfnPfns);
1615: } catch (RLSException e) {
1616: log("remove(String)", e, LogManager.ERROR_MESSAGE_LEVEL);
1617: }
1618:
1619: //c should be empty ideally
1620: if (!c.isEmpty()) {
1621: result -= c.size();
1622: log("remove(String)" + c, LogManager.ERROR_MESSAGE_LEVEL);
1623: }
1624: return result;
1625: }
1626:
1627: /**
1628: * Removes all mappings for a set of LFNs.
1629: *
1630: * @param lfns is a set of logical filename to remove all mappings for.
1631: *
1632: * @return the number of removed entries.
1633: */
1634: public int remove(Set lfns) {
1635: String lfn = null;
1636: Collection c = null;
1637: int result = 0;
1638:
1639: //first get hold of all the pfn mappings for the lfn
1640: Map map = this .lookupNoAttributes(lfns);
1641: if (map == null || map.isEmpty()) {
1642: return 0;
1643: }
1644: //we need to pipe this into a list of RLSString2 objects
1645: ArrayList lfnPfns = new ArrayList(map.keySet().size());
1646: for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
1647: Map.Entry entry = (Map.Entry) it.next();
1648: lfn = (String) entry.getKey();
1649: for (Iterator it1 = ((Set) entry.getValue()).iterator(); it1
1650: .hasNext();) {
1651: RLSString2 lfnPfn = new RLSString2(lfn, (String) it1
1652: .next());
1653: lfnPfns.add(lfnPfn);
1654: result++;
1655: }
1656: }
1657:
1658: //do a bulk delete
1659: //FIX ME: The deletes should have been done in batches.
1660: try {
1661: c = mLRC.deleteBulk(lfnPfns);
1662: } catch (RLSException e) {
1663: log("remove(Set)" + e, LogManager.ERROR_MESSAGE_LEVEL);
1664: }
1665:
1666: //c should be empty ideally
1667: if (!c.isEmpty()) {
1668: result -= c.size();
1669: log("remove(Set)" + c, LogManager.ERROR_MESSAGE_LEVEL);
1670: for (Iterator it = c.iterator(); it.hasNext();) {
1671: RLSString2Bulk rs2 = (RLSString2Bulk) it.next();
1672: System.out.println("(" + rs2.s1 + "->" + rs2.s2 + ","
1673: + rs2.rc + ")");
1674: }
1675: }
1676: return result;
1677:
1678: }
1679:
1680: /**
1681: * Removes all entries associated with a particular resource handle.
1682: * This is useful, if a site goes offline. It is a convenience method,
1683: * which calls the generic <code>removeByAttribute</code> method.
1684: *
1685: * @param handle is the site handle to remove all entries for.
1686: *
1687: * @return the number of removed entries.
1688: *
1689: * @see #removeByAttribute( String, Object )
1690: */
1691: public int removeByAttribute(String handle) {
1692: return removeByAttribute(SITE_ATTRIBUTE, handle);
1693: }
1694:
1695: /**
1696: * Removes all entries from the replica catalog where the PFN attribute
1697: * is found, and matches exactly the object value.
1698: *
1699: * @param name is the PFN attribute name to look for.
1700: * @param value is an exact match of the attribute value to match.
1701: *
1702: * @return the number of removed entries.
1703: */
1704: public int removeByAttribute(String name, Object value) {
1705: String lfn = null;
1706: String pfn = null;
1707: Collection c = null;
1708: int result = 0;
1709:
1710: //get hold of all the lfns in the lrc
1711: Set s = list();
1712:
1713: //first get hold of all the pfn mappings for the lfn
1714: Map map = this .lookup(s, name, value);
1715: if (map == null || map.isEmpty()) {
1716: return 0;
1717: }
1718:
1719: //we need to pipe this into a list of RLSString2 objects
1720: ArrayList lfnPfns = new ArrayList(result);
1721: for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
1722: Map.Entry entry = (Map.Entry) it.next();
1723: lfn = (String) entry.getKey();
1724: //System.out.println(lfn + " ->");
1725: for (Iterator it1 = ((Set) entry.getValue()).iterator(); it1
1726: .hasNext();) {
1727: pfn = ((ReplicaCatalogEntry) it1.next()).getPFN();
1728: RLSString2 lfnPfn = new RLSString2(lfn, pfn);
1729: lfnPfns.add(lfnPfn);
1730: result++;
1731: //System.out.print(lfnPfn.s2 + ",");
1732: }
1733: }
1734:
1735: //do a bulk delete
1736: //FIX ME: The deletes should have been done in batches.
1737: try {
1738: c = mLRC.deleteBulk(lfnPfns);
1739: } catch (RLSException e) {
1740: throw new ReplicaCatalogException("Bulk Delete: "
1741: + e.getMessage());
1742: }
1743:
1744: //c should be empty ideally
1745: if (!c.isEmpty()) {
1746: result -= c.size();
1747: log("removeByAttribute(String,Object)" + c,
1748: LogManager.ERROR_MESSAGE_LEVEL);
1749: }
1750: return result;
1751: }
1752:
1753: /**
1754: * Removes everything. Use with caution!
1755: *
1756: * @return the number of removed entries.
1757: */
1758: public int clear() {
1759:
1760: //do a bulk delete
1761: //FIX ME: The deletes should have been done in batches.
1762: try {
1763: mLRC.clear();
1764: } catch (RLSException e) {
1765: log("clear()", e, LogManager.ERROR_MESSAGE_LEVEL);
1766: }
1767: return 0;
1768: /*
1769: String lfn = null;
1770: String pfn = null;
1771: Collection c = null;
1772: int result = 0;
1773:
1774: //get hold of all the lfns in the lrc
1775: Set s = list();
1776:
1777: //first get hold of all the pfn mappings for the lfn
1778: Map map = this.lookupNoAttributes(s);
1779: if(map == null || map.isEmpty()){
1780: return 0;
1781: }
1782:
1783: //we need to pipe this into a list of RLSString2 objects
1784: ArrayList lfnPfns = new ArrayList(result);
1785: for(Iterator it = map.entrySet().iterator();it.hasNext();){
1786: Map.Entry entry = (Map.Entry) it.next();
1787: lfn = (String)entry.getKey();
1788: //System.out.println(lfn + " ->");
1789: for (Iterator it1 = ( (Set) entry.getValue()).iterator();
1790: it1.hasNext(); ) {
1791: pfn = ((String)it1.next());
1792: RLSString2 lfnPfn = new RLSString2(lfn, pfn);
1793: lfnPfns.add(lfnPfn);
1794: result++;
1795: //System.out.print(lfnPfn.s2 + ",");
1796: }
1797: }
1798:
1799: //do a bulk delete
1800: //FIX ME: The deletes should have been done in batches.
1801: try{
1802: c = mLRC.deleteBulk(lfnPfns);
1803: }
1804: catch(RLSException e){
1805: log("clear()",e,LogManager.ERROR_MESSAGE_LEVEL);
1806: }
1807:
1808: //c should be empty ideally
1809: if(!c.isEmpty()){
1810: result -= c.size();
1811: log("clear()" + c,LogManager.ERROR_MESSAGE_LEVEL);
1812: }
1813: return result;
1814: */
1815: }
1816:
1817: /**
1818: * Explicitely free resources before the garbage collection hits.
1819: */
1820: public void close() {
1821: try {
1822: if (mRLS != null) {
1823: mRLS.Close();
1824: }
1825: } catch (RLSException e) {
1826: //ignore
1827: } finally {
1828: mRLS = null;
1829: }
1830: }
1831:
1832: /**
1833: * Returns whether the connection to the RLS with which this instance is
1834: * associated is closed or not.
1835: *
1836: * @return true, if the implementation is disassociated, false otherwise.
1837: * @see #close()
1838: */
1839: public boolean isClosed() {
1840: return (mRLS == null);
1841: }
1842:
1843: /**
1844: * It returns the timeout value in seconds after which to timeout in case of
1845: * no activity from the LRC.
1846: *
1847: * Referred to by the "lrc.timeout" property.
1848: *
1849: * @return the timeout value if specified else,
1850: * the value specified by "rls.timeout" property, else
1851: * DEFAULT_LRC_TIMEOUT.
1852: *
1853: * @see #DEFAULT_LRC_TIMEOUT
1854: */
1855: protected int getTimeout(Properties properties) {
1856: String prop = properties.getProperty(this .LRC_TIMEOUT_KEY);
1857:
1858: //if prop is null get rls timeout,
1859: prop = (prop == null) ? properties
1860: .getProperty(this .RLS_TIMEOUT_KEY) : prop;
1861:
1862: int val = 0;
1863: try {
1864: val = Integer.parseInt(prop);
1865: } catch (Exception e) {
1866: val = Integer.parseInt(DEFAULT_LRC_TIMEOUT);
1867: }
1868: return val;
1869:
1870: }
1871:
1872: /**
1873: * Returns the site handle associated with the pfn at the lrc to which
1874: * the instance of this application binds. It returns <code>UNDEFINED_SITE
1875: * </code> even when the pfn is not in the lrc.
1876: *
1877: * @param pfn The pfn with which the attribute is associated.
1878: *
1879: * @return value of the attribute if found
1880: * else UNDEFINED_POOL
1881: */
1882: private String getSiteHandle(String pfn) {
1883: return getSiteHandle(mLRC, pfn);
1884: }
1885:
1886: /**
1887: * Returns the site handle associated with a pfn at the lrc associated
1888: * with the <code>RLSClient</code> passed. It returns <code>UNDEFINED_SITE
1889: * </code> even when the pfn is not in the lrc.
1890: *
1891: * @param lrc the handle to the lrc , where the attributes are stored.
1892: * @param pfn the pfn with which the attribute is associated.
1893: *
1894: * @return value of the attribute if found
1895: * else UNDEFINED_POOL
1896: *
1897: */
1898: private String getSiteHandle(RLSClient.LRC lrc, String pfn) {
1899: String poolAttr = getAttribute(lrc, pfn, SITE_ATTRIBUTE);
1900: return (poolAttr == null) ? UNDEFINED_SITE : poolAttr;
1901: }
1902:
1903: /**
1904: * Retrieves from the lrc, associated with this instance all the
1905: * attributes associated with the <code>pfn</code> in a map. All the
1906: * attribute values are stored as String.
1907: *
1908: * @param pfn the pfn with which the attribute is associated.
1909: *
1910: * @return <code>Map</code>containing the attribute keys and values,
1911: * else an empty Map.
1912: */
1913: private Map getAttributes(String pfn) {
1914: return getAttributes(mLRC, pfn);
1915: }
1916:
1917: /**
1918: * Retrieves from the lrc associated with this instance, all the
1919: * attributes associated with the lfn-pfns in a map indexed by the lfn.
1920: * The value for each entry is a collection of
1921: * <code>ReplicaCatalogEntry</code> objects.
1922: * All the attribute values are stored as String.
1923: *
1924: * If the attribute value passed is not null, then explicit matching occurs
1925: * on attribute values in addition.
1926: *
1927: * @param lfnPfns a list of <code>RLSString2Bulk</code> objects containing
1928: * the lfn in s1 field, and pfn in s2 field. The list is
1929: * assumed to be grouped by lfns.
1930: * @param attrKey the name of attribute that needs to be queried for each
1931: * pfn. a value of null denotes all attributes.
1932: * @param attrVal the value of the attribute that should be matching.
1933: *
1934: * @return a map indexed by the LFN. Each value is a collection
1935: * of replica catalog entries for the LFN.
1936: */
1937: private Map getAttributes(List lfnPfns, String attrKey,
1938: Object attrVal) {
1939: Map result = new HashMap();
1940: String curr = null;
1941: String prev = null;
1942: //loss of information. i should have known the size at this pt!
1943: List l = new ArrayList();
1944: ArrayList pfns = new ArrayList(lfnPfns.size());
1945: int size = mBatchSize;
1946: ReplicaCatalogEntry entry = null;
1947: Map temp = new HashMap();
1948: Map pfnMap = new HashMap(); //contains pfn and their ReplicaCatalogEntry objects
1949:
1950: //sanity check
1951: if (lfnPfns == null || lfnPfns.isEmpty()) {
1952: return result;
1953: }
1954:
1955: //put just the pfns in a list that needs
1956: //to be sent to the RLS API
1957: for (Iterator it = lfnPfns.iterator(); it.hasNext();) {
1958: pfns.add(((RLSString2Bulk) it.next()).s2);
1959: }
1960: //now query for the attributes in bulk
1961: List attributes = null;
1962: try {
1963: attributes = mLRC.attributeValueGetBulk(pfns, attrKey,
1964: RLSAttribute.LRC_PFN);
1965: } catch (RLSException e) {
1966: //some other error, but we can live with it.
1967: //just flag as warning
1968: mLogMsg = "getAttributes(List,String,Object)";
1969: log(mLogMsg, e, LogManager.ERROR_MESSAGE_LEVEL);
1970: return result;
1971: }
1972:
1973: //we need to sort them on the basis of the pfns
1974: //which is the populate the key field
1975: Collections.sort(attributes, new RLSAttributeComparator());
1976: /*
1977: System.out.println("Sorted attributes are ");
1978: for(Iterator it = attributes.iterator(); it.hasNext();){
1979: RLSAttributeObject obj = (RLSAttributeObject) it.next();
1980: if(obj.rc == RLSClient.RLS_ATTR_NEXIST){
1981: System.out.print("\tAttribute does not exist");
1982: }
1983: System.out.println("\t" + obj.key + "->rc" + obj.rc);
1984: }
1985: */
1986:
1987: for (Iterator it = attributes.iterator(); it.hasNext();) {
1988: RLSAttributeObject attr = (RLSAttributeObject) it.next();
1989: Object value = (attr.rc == RLSClient.RLS_ATTR_NEXIST) ? null
1990: : //assign an empty value
1991: getAttributeValue(attr.attr);//retrieve the value
1992:
1993: curr = attr.key;
1994:
1995: //push in the attribute into the temp map only
1996: //if prev is null or the prev and current pfn's match
1997: if ((prev == null || curr.equalsIgnoreCase(prev))
1998: && (value != null)//value being null means no attribute associated
1999: && ((attrVal == null) || (attrVal.equals(value)))) {
2000: temp.put(attr.attr.name, value);
2001: } else {
2002: //push it into the map all attributes for a single pfn
2003: //only if the map is not empty or there was no matching
2004: //being done attrVal (i.e it is null)
2005: if (attrVal == null || !temp.isEmpty()) {
2006: entry = new ReplicaCatalogEntry(prev, temp);
2007: //System.out.println("0:Entry being made is " + entry);
2008: //the entry has to be put in a map keyed by the pfn name
2009: pfnMap.put(prev, entry);
2010: temp = new HashMap();
2011: }
2012: //added June 15,2005
2013: if (value != null
2014: && (attrVal == null || attrVal.equals(value))) {
2015: temp.put(attr.attr.name, value);
2016: }
2017: }
2018: //push in the last attribute entry
2019: if (!it.hasNext()) {
2020: //push it into the map all attributes for a single pfn
2021: //only if the map is not empty or there was no matching
2022: //being done attrVal (i.e it is null)
2023: if (attrVal == null || !temp.isEmpty()) {
2024: entry = new ReplicaCatalogEntry(curr, temp);
2025: //System.out.println("1:Entry being made is " + entry);
2026: //the entry has to be put in a map keyed by the pfn name
2027: pfnMap.put(curr, entry);
2028: }
2029: }
2030: prev = curr;
2031:
2032: }
2033:
2034: //the final iteration that groups the pfn and their
2035: //attributes according to the lfn
2036: prev = null;
2037: for (Iterator it = lfnPfns.iterator(); it.hasNext();) {
2038: RLSString2Bulk lfnPfn = (RLSString2Bulk) it.next();
2039: curr = lfnPfn.s1;
2040:
2041: entry = (ReplicaCatalogEntry) pfnMap.get(lfnPfn.s2);
2042: if (entry == null) {
2043: //means no match on attribute or attribute value was found
2044: continue;
2045: }
2046:
2047: if (!curr.equalsIgnoreCase(prev) && (prev != null)) {
2048: //push it into the map
2049: //we have entry for one lfn and all pfns constructed
2050: //System.out.println("Putting in entry for " + prev + " " + l);
2051: result.put(prev, l);
2052: l = new ArrayList();
2053: }
2054: l.add(entry);
2055: //if this was the last one push it in result
2056: if (!it.hasNext()) {
2057: //System.out.println("Putting in entry for " + curr + " " + l);
2058: result.put(curr, l);
2059: }
2060: prev = curr;
2061: }
2062:
2063: return result;
2064: }
2065:
2066: /**
2067: * Retrieves from the lrc, all the attributes associated with the <code>pfn
2068: * </code> in a map. All the attribute values are stored as String.
2069: *
2070: * @param lrc the handle to the lrc , where the attributes are stored.
2071: * @param pfn the pfn with which the attribute is associated.
2072: * @return <code>Map</code>containing the attribute keys and values,
2073: * else an empty Map.
2074: */
2075: private Map getAttributes(RLSClient.LRC lrc, String pfn) {
2076: String val = null;
2077: List attrList = null;
2078: Map m = new HashMap();
2079: RLSAttribute att = null;
2080:
2081: try {
2082: //passing null denotes to get
2083: //hold of all attributes
2084: attrList = lrc.attributeValueGet(pfn, null,
2085: RLSAttribute.LRC_PFN);
2086: } catch (RLSException e) {
2087: //attribute does not exist error means no attributes
2088: //associated, return empty map else just denote a warning
2089: if (e.GetRC() != RLSClient.RLS_ATTR_NEXIST) {
2090: //some other error, but we can live with it.
2091: //just flag as warning
2092: mLogMsg = "getAttributes(RLSClient.LRC,String)";
2093: log(mLogMsg, e, LogManager.ERROR_MESSAGE_LEVEL);
2094: }
2095: return m;
2096: }
2097:
2098: //iterate throught the list and push all
2099: //the attributes in the map
2100: for (Iterator it = attrList.iterator(); it.hasNext();) {
2101: att = (RLSAttribute) it.next();
2102: m.put(att.name, att.GetStrVal());
2103: }
2104:
2105: return m;
2106: }
2107:
2108: /**
2109: * Retrieves from the lrc associated with this instance all, the attribute
2110: * value associated with the <code>pfn</code> for a given attribute name.
2111: *
2112: * @param pfn the pfn with which the attribute is associated.
2113: * @param name the name of the attribute for which we want to search.
2114: *
2115: * @return value of the attribute if found
2116: * else null
2117: */
2118: private String getAttribute(String pfn, String name) {
2119: return getAttribute(mLRC, pfn, name);
2120: }
2121:
2122: /**
2123: * Retrieves from the lrc, the attribute value associated with the <code>pfn
2124: * </code> for a given attribute name.
2125: *
2126: * @param lrc the handle to the lrc , where the attributes are stored.
2127: * @param pfn the pfn with which the attribute is associated.
2128: * @param name the name of the attribute for which we want to search.
2129: *
2130: * @return value of the attribute if found
2131: * else null
2132: */
2133: private String getAttribute(RLSClient.LRC lrc, String pfn,
2134: String name) {
2135: String val = null;
2136: List attrList = null;
2137:
2138: try {
2139: attrList = lrc.attributeValueGet(pfn, name,
2140: RLSAttribute.LRC_PFN);
2141: } catch (RLSException e) {
2142: if (e.GetRC() == RLSClient.RLS_ATTR_NEXIST) {
2143: //attribute does not exist we return null
2144: } else {
2145: //some other error, but we can live with it.
2146: //just flag as warning
2147: mLogMsg = "getAttribute(String,String,String):";
2148: log(mLogMsg, e, LogManager.ERROR_MESSAGE_LEVEL);
2149: }
2150: return null;
2151: }
2152:
2153: return (attrList.isEmpty()) ? null :
2154: //we return the first attribute value
2155: //Does not make much sense for
2156: //more than one attribute value
2157: //for the same key and pfn
2158: attrList.get(0).toString();
2159: }
2160:
2161: /**
2162: * Retrieves the attribute value as an object from the <code>RLSAttribute</code>
2163: * object. Does automatic boxing (i.e converts int to Integer) etc.
2164: * The value is returned of the type as determined from the internal value
2165: * type.
2166: *
2167: * @param attr the <code>RLSAttribute</code> from which to extract the value.
2168: *
2169: * @return Object containing the value.
2170: *
2171: * @throws ReplicaCatalogException if illegal value associated.
2172: */
2173: private Object getAttributeValue(RLSAttribute attr) {
2174: Object obj = null;
2175: int type = attr.GetValType();
2176:
2177: switch (type) {
2178: case RLSAttribute.STR:
2179: obj = attr.GetStrVal();
2180: break;
2181:
2182: case RLSAttribute.DATE:
2183: obj = attr.GetDateVal();
2184: break;
2185:
2186: case RLSAttribute.DOUBLE:
2187: obj = new Double(attr.GetDoubleVal());
2188: break;
2189:
2190: case RLSAttribute.INT:
2191: obj = new Integer(attr.GetIntVal());
2192: break;
2193:
2194: default:
2195: throw new ReplicaCatalogException(
2196: "Invalid value type associated " + type);
2197: }
2198:
2199: return obj;
2200: }
2201:
2202: /**
2203: * Sets the number of lfns in each batch while querying the lrc in the
2204: * bulk mode.
2205: *
2206: * @param properties the properties passed while connecting.
2207: *
2208: */
2209: private void setBatchSize(Properties properties) {
2210: String s = properties.getProperty(this .BATCH_KEY);
2211: int size = this .RLS_BULK_QUERY_SIZE;
2212: try {
2213: size = Integer.parseInt(s);
2214: } catch (Exception e) {
2215: }
2216: mBatchSize = size;
2217: }
2218:
2219: /**
2220: * Returns the number of lfns in each batch while querying the lrc in the
2221: * bulk mode.
2222: *
2223: * @return the batch size.
2224: */
2225: private int getBatchSize() {
2226: return mBatchSize;
2227: }
2228:
2229: /**
2230: * Retrieves multiple entries for a given logical filename, up to the
2231: * complete LRC. It uses the bulk query api to the LRC to query for stuff.
2232: * Bulk query has been in RLS since version 2.0.8. All the lfns in set
2233: * are put in one single bulk query to the LRC. There is a risk of seeing
2234: * a timeout error in case of large set of lfns. User should use the
2235: * lookup function that internally does the bulk query in batches.
2236: * Passing a null value for the attribute key results in the querying for all
2237: * attributes. The function returns <code>ReplicaCatalogEntry</code> objects
2238: * that have the attribute identified by attribute key passed.
2239: *
2240: * @param lfns set of logical filename strings to look up.
2241: * @param attrKey the name of attribute that needs to be queried for each
2242: * pfn. a value of null denotes all attributes.
2243: *
2244: * @return a map indexed by the LFN. Each value is a collection
2245: * of replica catalog entries for the LFN.
2246: * @see ReplicaCatalogEntry
2247: * @see #lookup(Set)
2248: */
2249: private Map bulkLookup(Set lfns, String attrKey) {
2250: return bulkLookup(lfns, attrKey, null);
2251: }
2252:
2253: /**
2254: * Retrieves multiple entries for a given logical filename, up to the
2255: * complete LRC. It uses the bulk query api to the LRC to query for stuff.
2256: * Bulk query has been in RLS since version 2.0.8. All the lfns in set
2257: * are put in one single bulk query to the LRC. There is a risk of seeing
2258: * a timeout error in case of large set of lfns. User should use the
2259: * lookup function that internally does the bulk query in batches.
2260: * Passing a null value for the attribute key results in the querying for all
2261: * attributes. A null value for the attribute value, disables attribute matching
2262: * and results in the <code>ReplicaCatalogEntry</code> objects that have
2263: * the attribute identified by attribute key passed.
2264: *
2265: * @param lfns set of logical filename strings to look up.
2266: * @param attrKey the name of attribute that needs to be queried for each
2267: * pfn. a value of null denotes all attributes.
2268: * @param attrVal the value of the attribute that should be matching.
2269: *
2270: * @return a map indexed by the LFN. Each value is a collection
2271: * of replica catalog entries for the LFN.
2272: * @see ReplicaCatalogEntry
2273: * @see #lookup(Set)
2274: */
2275: private Map bulkLookup(Set lfns, String attrKey, Object attrVal) {
2276: List list = null;
2277: List lfnsFound = null;
2278: RLSString2Bulk curr = null;
2279: int size = mBatchSize;
2280: Map result = new HashMap(lfns.size());
2281:
2282: try {
2283: list = mLRC.getPFNBulk(new ArrayList(lfns));
2284: //we need to group pfns by lfn
2285: Collections.sort(list, new RLSString2BulkComparator());
2286: /*
2287: System.out.println("Sorted list is ");
2288: for(Iterator it = list.iterator(); it.hasNext();){
2289: RLSString2Bulk s2b = (RLSString2Bulk) it.next();
2290: System.out.println("\t" + s2b.s1 + "->" + s2b.s2);
2291: }
2292: */
2293: size = list.size() <= size ? list.size() : size;
2294: for (Iterator it = list.iterator(); it.hasNext();) {
2295: //the pfn themseleves need to be queried
2296: //in batches to avoid timeout errors but the batch size
2297: //should have all the pfns for a lfn!!
2298: List l = new ArrayList(size);
2299: String prev = "";
2300: if (curr != null) {
2301: //this is the case where the current
2302: //item is not in any of the sublists
2303: l.add(curr);
2304: }
2305: for (int j = 0; (it.hasNext());) {
2306: RLSString2Bulk s2b = (RLSString2Bulk) it.next();
2307: //s1 is the lfn
2308: //s2 denotes the pfn
2309: //rc is the exit status returned by the RLI
2310: if (s2b.rc == RLSClient.RLS_SUCCESS) {
2311: curr = s2b;
2312: if (s2b.s2 != null) {
2313: //query for the pool attribute
2314: //for that pfn to the lrc
2315: //if none is found or you do not
2316: //query for the attribute
2317: //pool is set to UNDEFINED_POOL
2318: if (!curr.s1.equalsIgnoreCase(prev)) {
2319: //do nothing
2320: //check if j > size
2321: if (j >= size) {
2322: //break out of the loop.
2323: //current needs to go into the next list
2324: break;
2325: }
2326: }
2327:
2328: l.add(s2b);
2329: j++;
2330: } else {
2331: mLogMsg = "bulkLookup(Set): Unexpected Mapping with no pfn for lfn: "
2332: + s2b.s1;
2333: log(mLogMsg, LogManager.ERROR_MESSAGE_LEVEL);
2334: }
2335: prev = curr.s1;
2336: } else if (s2b.rc != RLSClient.RLS_LFN_NEXIST) {
2337: mLogMsg = "bulkLookup(Set): "
2338: + mRLS.getErrorMessage(s2b.rc);
2339: log(mLogMsg, LogManager.ERROR_MESSAGE_LEVEL);
2340: }
2341: //prev = curr.s1;
2342: }
2343: //get hold of all attributes for the pfn's
2344: result.putAll(getAttributes(l, attrKey, attrVal));
2345:
2346: }
2347:
2348: } catch (Exception e) {
2349: log("bulkLookup(Set)", e, LogManager.FATAL_MESSAGE_LEVEL);
2350: System.exit(1);
2351: }
2352:
2353: return result;
2354: }
2355:
2356: /**
2357: * Retrieves multiple entries for a given logical filename, up to the
2358: * complete LRC. It uses the bulk query api to the LRC to query for stuff.
2359: * Bulk query has been in RLS since version 2.0.8. All the lfns in set
2360: * are put in one single bulk query to the LRC. There is a risk of seeing
2361: * a timeout error in case of large set of lfns. User should use the
2362: * lookup function that internally does the bulk query in batches.
2363: *
2364: * @param lfns is a set of logical filename strings to look up.
2365: *
2366: * @return a map indexed by the LFN. Each value is a set
2367: * of PFN strings.
2368: *
2369: * @see #lookupNoAttributes(Set)
2370: */
2371: private Map bulkLookupNoAttributes(Set lfns) {
2372: List list = null;
2373: List lfnsFound = null;
2374: Map result = new HashMap(lfns.size());
2375: String prev = null;
2376: String curr = null;
2377: Set s = new HashSet();
2378:
2379: try {
2380: list = mLRC.getPFNBulk(new ArrayList(lfns));
2381: //we need to group pfns by lfn
2382: Collections.sort(list, new RLSString2BulkComparator());
2383:
2384: for (Iterator it = list.iterator(); it.hasNext();) {
2385: RLSString2Bulk s2b = (RLSString2Bulk) it.next();
2386:
2387: //s1 is the lfn
2388: //s2 denotes the pfn
2389: //rc is the exit status returned by the RLI
2390: if (s2b.rc == RLSClient.RLS_SUCCESS) {
2391: curr = s2b.s1;
2392: if (s2b.s2 != null) {
2393: if (!curr.equalsIgnoreCase(prev)
2394: && (prev != null)) {
2395: //push it into the map
2396: //we have entry for one lfn and all pfns constructed
2397: result.put(prev, s);
2398: s = new HashSet();
2399: }
2400: s.add(s2b.s2);
2401: //if this was the last one push it in result
2402: if (!it.hasNext()) {
2403: result.put(curr, s);
2404: }
2405: } else {
2406: mLogMsg = "bulkLookupNoAttributes(Set): Unexpected Mapping with no pfn for lfn: "
2407: + s2b.s1;
2408: log(mLogMsg, LogManager.ERROR_MESSAGE_LEVEL);
2409: }
2410: prev = curr;
2411: } else if (s2b.rc != RLSClient.RLS_LFN_NEXIST) {
2412: mLogMsg = "bulkLookupNoAttributes(Set): "
2413: + mRLS.getErrorMessage(s2b.rc);
2414: log(mLogMsg, LogManager.ERROR_MESSAGE_LEVEL);
2415: }
2416: //prev = curr;
2417: }
2418: } catch (Exception e) {
2419: log("bulkLookupNoAttributes(Set):", e,
2420: LogManager.FATAL_MESSAGE_LEVEL);
2421: System.exit(1);
2422: }
2423:
2424: return result;
2425: }
2426:
2427: /**
2428: * Constructs replica catalog exception out the RLSException that is
2429: * thrown by the API underneath.
2430: *
2431: * @param prefix the prefix that is to be applied to the message
2432: * passed while creating the exception.
2433: * @param e the RLSException that is caught underneath.
2434: *
2435: * @return a ReplicaCatalogException
2436: */
2437: private ReplicaCatalogException exception(String prefix,
2438: RLSException e) {
2439: StringBuffer message = new StringBuffer(32);
2440: message.append("{LRC ").append(mLRCURL).append("} ").append(
2441: prefix).append(": ").append(e.getMessage());
2442: return new ReplicaCatalogException(message.toString(), e);
2443: }
2444:
2445: /**
2446: * Constructs an exception from the <code>RLSString2Bulk</code> object.
2447: *
2448: * @return a ReplicaCatalogException
2449: */
2450: private ReplicaCatalogException exception(RLSString2Bulk rs) {
2451: StringBuffer sb = new StringBuffer(32);
2452: sb.append("Error (lfn,pfn,ec)").append(" (").append(rs.s1)
2453: .append(',').append(rs.s2).append(',').append(rs.rc)
2454: .append(',').append(mRLS.getErrorMessage(rs.rc))
2455: .append(')');
2456: return new ReplicaCatalogException(sb.toString());
2457:
2458: }
2459:
2460: /**
2461: * Returns a subset of a collection of <code>ReplicaCatalogEntry</code>
2462: * objects that have attributes matchin to the attribute identified by
2463: * the parameters passed.
2464: *
2465: * @param collection the collection of <code>ReplicaCatalogEntry</code>
2466: * objects.
2467: * @param name the attribute name to match.
2468: * @param value the attribute value.
2469: *
2470: * @return Set of matching <code>ReplicaCatalogEntry</code> objects.
2471: */
2472: private Set subset(Collection collection, String name, Object value) {
2473: return subset(collection, name, value, false);
2474: }
2475:
2476: /**
2477: * Returns a subset of a collection of <code>ReplicaCatalogEntry</code>
2478: * objects that have attributes matchin to the attribute identified by
2479: * the parameters passed.
2480: *
2481: * @param collection the collection of <code>ReplicaCatalogEntry</code>
2482: * objects.
2483: * @param name the attribute name to match.
2484: * @param value the attribute value.
2485: * @param onlyPFN boolean to denote if we only want the PFN's
2486: *
2487: * @return Set of <code>ReplicaCatalogEntry</code> objects if onlyPfn
2488: * parameter is set to false, else a Set of pfns.
2489: */
2490: private Set subset(Collection collection, String name,
2491: Object value, boolean onlyPFN) {
2492: Set s = new HashSet();
2493: ReplicaCatalogEntry rce;
2494: Object attrVal;
2495: for (Iterator it = collection.iterator(); it.hasNext();) {
2496: rce = (ReplicaCatalogEntry) it.next();
2497: //System.out.println("RCE is " + rce);
2498: attrVal = rce.getAttribute(name);
2499: if (attrVal != null && attrVal.equals(value)) {
2500: //adding to the set only if
2501: //the attribute existed in the rce
2502: s.add(onlyPFN ? (Object) rce.getPFN() : rce);
2503: }
2504: }
2505:
2506: return s;
2507: }
2508:
2509: /**
2510: * A helper method that converts RLSString2 to MyRLSString2Bulk object.
2511: *
2512: * @param obj the <code>RLSString2</code> to convert.
2513: *
2514: * @return the converted <code>MyRLSString2</code> object.
2515: */
2516: private RLSString2Bulk convert(RLSString2 obj) {
2517: return new MyRLSString2Bulk(0, obj.s1, obj.s2);
2518: }
2519:
2520: /**
2521: * Logs to the logger object.
2522: *
2523: * @param message the message to be logged.
2524: * @param level the logger level at which the message is to be logged.
2525: */
2526: private void log(String message, int level) {
2527: message = "{LRC " + mLRCURL + "} " + message;
2528: mLogger.log(message, level);
2529: }
2530:
2531: /**
2532: * Logs to the logger object.
2533: *
2534: * @param message the message to be logged.
2535: * @param e the exception that occured.
2536: * @param level the logger level at which the message is to be logged.
2537: */
2538: private void log(String message, Exception e, int level) {
2539: message = "{LRC " + mLRCURL + "} " + message;
2540: mLogger.log(message, e, level);
2541: }
2542:
2543: /**
2544: * The comparator that is used to group the <code>RLSString2</code> objects by the
2545: * value in the s1 field. This comparator should only be used for grouping
2546: * purposes not in Sets or Maps etc.
2547: */
2548: private class RLSString2Comparator implements Comparator {
2549:
2550: /**
2551: * Compares this object with the specified object for order. Returns a
2552: * negative integer, zero, or a positive integer if the first argument is
2553: * less than, equal to, or greater than the specified object. The
2554: * RLSString2 are compared by their s1 field.
2555: *
2556: * @param o1 is the first object to be compared.
2557: * @param o2 is the second object to be compared.
2558: *
2559: * @return a negative number, zero, or a positive number, if the
2560: * object compared against is less than, equals or greater than
2561: * this object.
2562: * @exception ClassCastException if the specified object's type
2563: * prevents it from being compared to this Object.
2564: */
2565: public int compare(Object o1, Object o2) {
2566: if (o1 instanceof RLSString2 && o2 instanceof RLSString2) {
2567: return ((RLSString2) o1).s1
2568: .compareTo(((RLSString2) o2).s1);
2569: } else {
2570: throw new ClassCastException("object is not RLSString2");
2571: }
2572: }
2573:
2574: }
2575:
2576: /**
2577: * The comparator that is used to group the RLSString2Bulk objects by the
2578: * value in the s1 field. This comparator should only be used for grouping
2579: * purposes not in Sets or Maps etc.
2580: */
2581: private class RLSString2BulkComparator implements Comparator {
2582:
2583: /**
2584: * Compares this object with the specified object for order. Returns a
2585: * negative integer, zero, or a positive integer if the first argument is
2586: * less than, equal to, or greater than the specified object. The
2587: * RLSString2Bulk are compared by their s1 field.
2588: *
2589: * @param o1 is the first object to be compared.
2590: * @param o2 is the second object to be compared.
2591: *
2592: * @return a negative number, zero, or a positive number, if the
2593: * object compared against is less than, equals or greater than
2594: * this object.
2595: * @exception ClassCastException if the specified object's type
2596: * prevents it from being compared to this Object.
2597: */
2598: public int compare(Object o1, Object o2) {
2599: if (o1 instanceof RLSString2Bulk
2600: && o2 instanceof RLSString2Bulk) {
2601: return ((RLSString2Bulk) o1).s1
2602: .compareTo(((RLSString2Bulk) o2).s1);
2603: } else {
2604: throw new ClassCastException(
2605: "object is not RLSString2Bulk");
2606: }
2607: }
2608:
2609: }
2610:
2611: /**
2612: * The comparator that is used to group the RLSAttributeObject objects by the
2613: * value in the key field. This comparator should only be used for grouping
2614: * purposes not in Sets or Maps etc.
2615: */
2616: private class RLSAttributeComparator implements Comparator {
2617:
2618: /**
2619: * Compares this object with the specified object for order. Returns a
2620: * negative integer, zero, or a positive integer if the first argument is
2621: * less than, equal to, or greater than the specified object. The
2622: * RLSAttributeObject are compared by their s1 field.
2623: *
2624: * @param o1 is the first object to be compared.
2625: * @param o2 is the second object to be compared.
2626: *
2627: * @return a negative number, zero, or a positive number, if the
2628: * object compared against is less than, equals or greater than
2629: * this object.
2630: * @exception ClassCastException if the specified object's type
2631: * prevents it from being compared to this Object.
2632: */
2633: public int compare(Object o1, Object o2) {
2634: if (o1 instanceof RLSAttributeObject
2635: && o2 instanceof RLSAttributeObject) {
2636: return ((RLSAttributeObject) o1).key
2637: .compareTo(((RLSAttributeObject) o2).key);
2638: } else {
2639: throw new ClassCastException(
2640: "object is not RLSAttributeObject");
2641: }
2642: }
2643:
2644: }
2645:
2646: /**
2647: * The class that extends RLSString2Bulk and adds on the equals method,
2648: * that allows me to do the set operations
2649: */
2650: private class MyRLSString2Bulk extends RLSString2Bulk {
2651:
2652: /**
2653: * The overloaded constructor.
2654: *
2655: * @param rca the rls exitcode
2656: * @param s1a the String object usually containing the lfn
2657: */
2658: public MyRLSString2Bulk(int rca, java.lang.String s1a) {
2659: super (rca, s1a);
2660: }
2661:
2662: /**
2663: * The overloaded constructor.
2664: *
2665: * @param rca the rls exitcode.
2666: * @param s1a the String object usually containing the lfn.
2667: * @param s2a the String object usually containing the pfn.
2668: */
2669: public MyRLSString2Bulk(int rca, java.lang.String s1a,
2670: java.lang.String s2a) {
2671: super (rca, s1a, s2a);
2672: }
2673:
2674: /**
2675: * Indicates whether some other object is "equal to" this one.
2676: *
2677: * An object is considered equal if it is of the same type and
2678: * all the fields s1 and s2 match.
2679: *
2680: * @return boolean whether the object is equal or not.
2681: */
2682: public boolean equals(Object obj) {
2683: if (obj instanceof MyRLSString2Bulk) {
2684: MyRLSString2Bulk sec = (MyRLSString2Bulk) obj;
2685: return this .s1.equals(sec.s1) && this .s2.equals(sec.s2);
2686: }
2687: return false;
2688: }
2689:
2690: /**
2691: * Returns a string representation of the object.
2692: *
2693: * @return the String representation.
2694: */
2695: public String toString() {
2696: StringBuffer sb = new StringBuffer(10);
2697: sb.append("(").append(s1).append("->").append(s2).append(
2698: ",").append(rc).append(")");
2699: return sb.toString();
2700: }
2701: }
2702:
2703: /**
2704: * Testing function.
2705: */
2706: public static void main(String[] args) {
2707: LRC lrc = new LRC();
2708: lrc.connect("rls://sukhna.isi.edu");
2709: String lfn = "test";
2710: LogManager.getInstance().setLevel(
2711: LogManager.DEBUG_MESSAGE_LEVEL);
2712:
2713: /*
2714: ReplicaCatalogEntry rce = new ReplicaCatalogEntry("gsiftp://sukhna.isi.edu/tmp/test");
2715: rce.addAttribute("name","karan");
2716: lrc.insert("test",rce);
2717: lrc.insert("test","gsiftp://sukhna.isi.edu/tmp/test1","isi");
2718: lrc.insert("test","gsiftp://sukhna.isi.edu/constraint/testvahi","isi");
2719: lrc.insert("vahi.f.a","file:///tmp/vahi.f.a","isi");
2720: lrc.insert("testvahi.f.a","file:///tmp/testvahi.f.a","isi");
2721:
2722: rce = new ReplicaCatalogEntry("gsiftp://sukhna.isi.edu/tmp/testX");
2723: rce.addAttribute("name","karan");
2724: rce.addAttribute("pool","isi");
2725: lrc.insert("testX",rce);
2726: */
2727:
2728: /*
2729: System.out.println("Getting list of lfns");
2730: System.out.println("\t" + lrc.list());
2731:
2732:
2733:
2734: Set s = new HashSet();
2735: s.add("test");s.add("vahi.f.a");s.add("testX");
2736: s.add("unknown");
2737:
2738:
2739: System.out.println("\nQuerying for complete RCE for site " + s );
2740: System.out.println(lrc.lookup(s));
2741: */
2742:
2743: /*
2744: System.out.println("\n Deleting " + lfn);
2745: System.out.println(lrc.deleteByResource(lfn,"isi"));
2746:
2747:
2748: System.out.println("\nQuerying for PFN for site" + s );
2749: System.out.println(lrc.lookupNoAttributes(s,"isi"));
2750:
2751: System.out.println("\nRemoving lfns " + s);
2752: //System.out.println(lrc.remove(s));
2753: System.out.println(lrc.removeByAttribute("isi"));
2754:
2755:
2756: System.out.println("\n\nClearing catalog " + lrc.clear());
2757: */
2758:
2759: //System.out.println("Getting list of lfns");
2760: //System.out.println("\t" + lrc.listLFNPFN("*vahi*",false));
2761: /*
2762: System.out.println("Removing lfns in set " + s + " ");
2763: System.out.println(lrc.removeByAttribute("isi"));
2764:
2765: Map m = new HashMap();
2766: //m.put("pfn","*vahi*");
2767: m.put("lfn","test*");
2768: System.out.println("Getting lfns matching constraint");
2769: System.out.println("\t" + lrc.lookup(m));
2770: */
2771:
2772: //test bulk insert
2773: System.out.println("Clearing the database");
2774: //lrc.clear();
2775: Map inserts = new HashMap();
2776: Collection c1 = new ArrayList();
2777: c1.add(new ReplicaCatalogEntry("gsiftp://test/f.a", "isi"));
2778: Collection c2 = new ArrayList();
2779: c2.add(new ReplicaCatalogEntry("gsiftp://test/f.b", "isi"));
2780: Collection c3 = new ArrayList();
2781: c3.add(new ReplicaCatalogEntry("gsiftp://test/f.c", "isi1"));
2782: inserts.put("f.a", c1);
2783: inserts.put("f.b", c2);
2784: inserts.put("f.c", c3);
2785: System.out.println("Doing bulk inserts");
2786: try {
2787: System.out.println("Inserted " + lrc.insert(inserts)
2788: + " entries");
2789: } catch (ReplicaCatalogException rce) {
2790: do {
2791: System.out.println(rce.getMessage());
2792: rce = (ReplicaCatalogException) rce.getNextException();
2793: } while (rce != null);
2794:
2795: }
2796:
2797: lrc.close();
2798: }
2799:
2800: } //end of class LRC
|