/**
* Copyright 2007-2008 University Of Southern California
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package edu.isi.pegasus.planner.catalog.transformation.impl;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import edu.isi.pegasus.common.logging.LogManager;
import edu.isi.pegasus.common.logging.LogManagerFactory;
import edu.isi.pegasus.common.util.Boolean;
import edu.isi.pegasus.common.util.FileUtils;
import edu.isi.pegasus.common.util.ProfileParser;
import edu.isi.pegasus.common.util.ProfileParserException;
import edu.isi.pegasus.common.util.Separator;
import edu.isi.pegasus.planner.catalog.TransformationCatalog;
import edu.isi.pegasus.planner.catalog.classes.SysInfo;
import edu.isi.pegasus.planner.catalog.transformation.TransformationCatalogEntry;
import edu.isi.pegasus.planner.catalog.transformation.classes.NMI2VDSSysInfo;
import edu.isi.pegasus.planner.catalog.transformation.classes.TCType;
import edu.isi.pegasus.planner.catalog.transformation.classes.VDSSysInfo;
import edu.isi.pegasus.planner.classes.Notifications;
import edu.isi.pegasus.planner.classes.PegasusBag;
import edu.isi.pegasus.planner.classes.Profile;
import edu.isi.pegasus.planner.common.PegasusProperties;
import edu.isi.pegasus.planner.parser.ScannerException;
/**
* This is the new file based TC implementation storing the contents of the file
* in memory. For the old tc file implementation see OldTC.java
*
* @author Gaurang Mehta
* @author Karan Vahi
* @version $Revision$
*/
public class File extends Abstract
implements TransformationCatalog{
/**
* The singleton handler to the contents of the transformation catalog.
*/
private static File mTCFileHandle = null;
/**
* The LogManager object which is used to log all the messages.
* It's values are set in the CPlanner (the main toolkit) class.
*/
protected LogManager mLogger;
/**
* The List containing the user specified list of pools on which he wants
* the dag to run.
*/
protected List mvExecPools;
/**
* The Tree Map which stores the contents of the file.
* The key is the transformationname.
*/
private Map mTreeMap;
/**
* The path to the file based TC.
*/
private String mTCFile;
/**
* The handle to the properties object.
*/
private PegasusProperties mProps;
/**
* Boolean indicating whether to flush the contents back to the file on
* close.
*/
private boolean mFlushOnClose;
/**
* Boolean indicating whether to modify the file URL or not
*
*/
private boolean modifyFileURL = true;
/**
* Returns an instance of the File TC.
*
* @return TransformationCatalog
* @deprecated
*/
public static TransformationCatalog getInstance() {
if (mTCFileHandle == null) {
PegasusBag bag = new PegasusBag();
bag.add( PegasusBag.PEGASUS_LOGMANAGER, LogManagerFactory.loadSingletonInstance() );
bag.add( PegasusBag.PEGASUS_PROPERTIES, PegasusProperties.nonSingletonInstance() );
mTCFileHandle = new File();
mTCFileHandle.initialize( bag );
}
return mTCFileHandle;
}
/**
* The default constructor.
*/
public void File(){
}
/**
* Initialize the implementation, and return an instance of the implementation.
*
* @param bag the bag of Pegasus initialization objects.
*
*/
public void initialize ( PegasusBag bag ){
mProps = bag.getPegasusProperties();
mLogger = bag.getLogger();
mFlushOnClose = false;
modifyFileURL = Boolean.parse(mProps.getProperty( MODIFY_FOR_FILE_URLS_KEY),
true );
mTCFile = mProps.getTCPath();
mTreeMap = new TreeMap();
mLogger.log("TC Mode being used is " + this.getDescription(),
LogManager.CONFIG_MESSAGE_LEVEL);
mLogger.log("TC File being used is " + mTCFile,
LogManager.CONFIG_MESSAGE_LEVEL);
if (mTCFile == null) {
throw new RuntimeException( "The File to be used as TC should be " +
"defined with the property pegasus.catalog.transformation.file");
} else {
java.io.File f = new java.io.File( mTCFile );
if( f.exists() ){
populateTC();
}
else{
mLogger.log("The Transformation Catalog file " + mTCFile +
" was not found", LogManager.DEBUG_MESSAGE_LEVEL);
}
}
}
/**
* Returns a textual description of the transformation mode.
*
* @return String containing the description.
*/
@Override
public String getDescription() {
String st = "New FILE TC Mode";
return st;
}
/**
* Returns TC entries for a particular logical transformation and/or on a
* number of resources and/or of a particular type.
*
* @param namespace String The namespace of the logical transformation.
* @param name String the name of the logical transformation.
* @param version String The version of the logical transformation.
* @param resourceids List The List resourceid where the transformation is located.
* If <b>NULL</b> it returns all resources.
* @param type TCType The type of the transformation to search for.
* If <b>NULL</b> it returns all types.
*
* @return List Returns a list of TransformationCatalogEntry objects containing
* the corresponding entries from the TC. Returns null if no entry found.
* @throws Exception
* @see edu.isi.pegasus.planner.catalog.transformation.classes.TCType
* @see edu.isi.pegasus.planner.catalog.TransformationCatalogEntry
*/
@Override
public List<TransformationCatalogEntry> lookup( String namespace, String name, String version,
List resourceids, TCType type ) throws Exception {
logMessage("getTCEntries(String namespace,String name,String version," +
"List resourceids, TCType type");
logMessage("\tgetTCEntries(" + namespace + ", " + name + ", " +
version + ", " +
resourceids + ", " + type);
List results = null;
if (resourceids != null) {
for (Iterator i = resourceids.iterator(); i.hasNext(); ) {
List tempresults = lookup(namespace, name, version,
(String) i.next(), type);
if (tempresults != null) {
if (results == null) {
results = new ArrayList();
}
results.addAll(tempresults);
}
}
}
else {
List tempresults = lookup(namespace, name, version, (String)null,
type);
if (tempresults != null) {
results = new ArrayList(tempresults.size());
results.addAll(tempresults);
}
}
return results;
}
/**
* Returns TC entries for a particular logical transformation and/or on a
* particular resource and/or of a particular type.
*
* @param namespace String The namespace of the logical transformation.
* @param name String the name of the logical transformation.
* @param version String The version of the logical transformation.
* @param resourceid String The resourceid where the transformation is located.
* If <B>NULL</B> it returns all resources.
* @param type TCType The type of the transformation to search for.
* If <B>NULL</b> it returns all types.
*
* @return List Returns a list of TransformationCatalogEntry objects
* containing the corresponding entries from the TC.
* Returns null if no entry found.
* @throws Exception
*
* @see edu.isi.pegasus.planner.catalog.transformation.classes.TCType
* @see edu.isi.pegasus.planner.catalog.TransformationCatalogEntry
*/
public List<TransformationCatalogEntry> lookup( String namespace, String name, String version,
String resourceid, TCType type ) throws Exception {
logMessage(
"getTCEntries(String namespace, String name, String version, " +
"String resourceId, TCType type)");
logMessage("\t getTCEntries(" + namespace + ", " + name + ", " +
version +
"," + resourceid + ", " + type);
List results = null;
String lfn = Separator.combine(namespace, name, version);
mLogger.log("Trying to get TCEntries for " +
lfn +
" on resource " + ( (resourceid == null) ? "ALL" :
resourceid) + " of type " +
( (type == null) ? "ALL" : type.toString()),
LogManager.DEBUG_MESSAGE_LEVEL);
if (resourceid != null) {
if (mTreeMap.containsKey(resourceid)) {
Map lfnMap = (Map) mTreeMap.get(resourceid);
if (lfnMap.containsKey(lfn)) {
List l = (List) lfnMap.get(lfn);
if (type != null && l != null) {
for (Iterator i = l.iterator(); i.hasNext(); ) {
TransformationCatalogEntry tc = (
TransformationCatalogEntry) i.next();
if (tc.getType().equals(type)) {
if (results == null) {
results = new ArrayList();
}
results.add(tc);
}
}
}
else {
results = l;
}
}
}
}
else {
//since resourceid is null return entries for all sites
if (!mTreeMap.isEmpty()) {
for (Iterator j = mTreeMap.values().iterator(); j.hasNext(); ) {
//check all maps for the executable.
Map lfnMap = (Map) j.next();
if (lfnMap.containsKey(lfn)) {
List l = (List) lfnMap.get(lfn);
if (type != null && l != null) {
for (Iterator i = l.iterator(); i.hasNext(); ) {
TransformationCatalogEntry tc = (
TransformationCatalogEntry) i.next();
if (tc.getType().equals(type)) {
if (results == null) {
results = new ArrayList();
}
results.add(tc);
}
}
}
else {
//if the list returned is not empty keep adding to the result list.
if (l != null) {
if (results == null) {
results = new ArrayList();
}
results.addAll(l);
}
}
}
}
}
}
return results;
}
/**
* Get the list of Resource ID's where a particular transformation may reside.
* @param namespace String The namespace of the transformation to search for.
* @param name String The name of the transformation to search for.
* @param version String The version of the transformation to search for.
* @param type TCType The type of the transformation to search for.<BR>
* (Enumerated type includes SOURCE, STATIC-BINARY, DYNAMIC-BINARY, PACMAN, INSTALLED, SCRIPT)<BR>
* If <B>NULL</B> it returns all types.
*
* @return List Returns a list of Resource Id's as strings. Returns <B>NULL</B> if no results found.
*
* @throws Exception NotImplementedException if not implemented
* @see edu.isi.pegasus.planner.catalog.transformation.classes.TCType
*/
public List<String> lookupSites( String namespace, String name, String version,
TCType type ) throws Exception {
logMessage(
"List getTCResourceIds(String namespace, String name, String " +
"version, TCType type");
logMessage("\t getTCResourceIds(" + namespace + ", " + name + ", " +
version +
", " + type);
List results = null;
List lfnList = new ArrayList();
if (name == null) {
if (type == null) {
//return all the resources only
results = new ArrayList(mTreeMap.keySet());
return results;
}
}
//return all the entries to search for type
lfnList.addAll(mTreeMap.values());
List entries = null;
for (Iterator i = lfnList.iterator(); i.hasNext(); ) {
Map lfnMap = (Map) i.next();
if (entries == null) {
entries = new ArrayList();
}
if (name == null) {
for (Iterator j = lfnMap.values().iterator(); j.hasNext(); ) {
entries.addAll( (List) j.next());
}
}
else {
if (lfnMap.containsKey(Separator.combine(namespace, name,
version))) {
entries.addAll( (List) lfnMap.get(Separator.combine(
namespace,
name,
version)));
}
}
}
TreeSet rset = null;
for (Iterator i = entries.iterator(); i.hasNext(); ) {
if (rset == null) {
rset = new TreeSet();
}
TransformationCatalogEntry entry = (TransformationCatalogEntry) i.
next();
if (type == null) {
rset.add(entry.getResourceId());
}
else {
if (entry.getType().equals(type)) {
rset.add(entry.getResourceId());
}
}
}
if (rset != null) {
results = new ArrayList();
for (Iterator i = rset.iterator(); i.hasNext(); ) {
results.add( (String) i.next());
}
}
return results;
}
/**
* Get the list of PhysicalNames for a particular transformation on a site/sites
* for a particular type/types;
*
* @param namespace String The namespace of the transformation to search for.
* @param name String The name of the transformation to search for.
* @param version String The version of the transformation to search for.
* @param resourceid String The id of the resource on which you want to search. <BR>
* If <B>NULL</B> then returns entries on all resources
* @param type TCType The type of the transformation to search for. <BR>
* (Enumerated type includes source, binary, dynamic-binary, pacman, installed)<BR>
* If <B>NULL</B> then returns entries of all types.
*
* @return List Returns a List of <TransformationCatalongEntry> objects
* with the profiles not populated.
*
* @throws Exception NotImplementedException if not implemented.
* @see edu.isi.pegasus.planner.catalog.transformation.classes.TCType
*/
public List <TransformationCatalogEntry> lookupNoProfiles( String namespace,
String name,String version,String resourceid, TCType type ) throws Exception {
logMessage("List getTCPhysicalNames(String namespace, String name," +
"String version, String resourceid,TCType type)");
logMessage("\t getTCPhysicalNames(" + namespace + ", " + name + ", " +
version + ", " + resourceid + ", " + type + ")");
List<TransformationCatalogEntry> results = null;
List lfnMap = new ArrayList();
/*
int count[] = {
0, 0, 0};
*/
if (resourceid == null) {
lfnMap.addAll(mTreeMap.values());
}
else {
if (mTreeMap.containsKey(resourceid)) {
lfnMap.add(mTreeMap.get(resourceid));
}
else {
return null;
}
}
for (Iterator i = lfnMap.iterator(); i.hasNext(); ) {
Map lMap = (Map) i.next();
if (lMap.containsKey(Separator.combine(namespace, name, version))) {
for (Iterator j = ( (List) lMap.get(Separator.combine(
namespace,
name, version))).iterator(); j.hasNext(); ) {
TransformationCatalogEntry entry = (
TransformationCatalogEntry) j.next();
if (type != null) {
if (!entry.getType().equals(type)) {
continue;
}
}
if (results == null) {
results = new ArrayList<TransformationCatalogEntry>();
}
results.add(entry);
}
}
}
/*
if (results != null) {
results.add(count);
}
*/
return results;
}
/**
* Get the list of LogicalNames available on a particular resource.
* @param resourceid String The id of the resource on which you want to search
* @param type TCType The type of the transformation to search for. <BR>
* (Enumerated type includes source, binary, dynamic-binary, pacman, installed)<BR>
* If <B>NULL</B> then return logical name for all types.
*
* @return List Returns a list of String Arrays.
* Each array contains the resourceid, logical transformation
* in the format namespace::name:version and type.
* Returns <B>NULL</B> if no results found.
*
* @throws Exception NotImplementedException if not implemented.
*/
public List<String[]> getTCLogicalNames( String resourceid, TCType type ) throws
Exception {
logMessage("List getTCLogicalNames(String resourceid, TCType type)");
logMessage("\t getTCLogicalNames(" + resourceid + "," + type + ")");
List result = null;
/*
int[] length = {
0, 0};
*/
List lfnMap = new ArrayList();
String lfn = null, resource = null, tctype = null;
if (resourceid == null) {
lfnMap.addAll(mTreeMap.values());
}
else {
if (mTreeMap.containsKey(resourceid)) {
lfnMap.add( (Map) mTreeMap.get(resourceid));
}
else {
lfnMap = null;
}
}
if (lfnMap != null) {
for (Iterator i = lfnMap.iterator(); i.hasNext(); ) {
for (Iterator j = ( (Map) i.next()).values().iterator();
j.hasNext(); ) {
for (Iterator k = ( (List) j.next()).iterator();
k.hasNext(); ) {
TransformationCatalogEntry tc = (
TransformationCatalogEntry) k.next();
String l = null, r = null, t = null;
if (type == null) {
l = tc.getLogicalTransformation();
r = tc.getResourceId();
t = tc.getType().toString();
}
else {
if (tc.getType().equals(type)) {
l = tc.getLogicalTransformation();
r = tc.getResourceId();
t = tc.getType().toString();
}
}
if (l != null && r != null && t != null) {
if (lfn == null ||
! (lfn.equalsIgnoreCase(l) &&
resource.equalsIgnoreCase(r) &&
tctype.equalsIgnoreCase(t))) {
lfn = l;
resource = r;
tctype = t;
String[] s = {
r, l, t};
//columnLength(s, length);
if (result == null) {
result = new ArrayList(5);
}
result.add(s);
}
}
}
}
}
}
/*
if (result != null) {
result.add(length);
}
*/
return result;
}
/**
* Get the list of Profiles associated with a particular logical transformation.
* @param namespace String The namespace of the transformation to search for.
* @param name String The name of the transformation to search for.
* @param version String The version of the transformation to search for.
*
* @return List Returns a list of Profile Objects containing profiles
* assocaited with the transformation.
* Returns <B>NULL</B> if no profiles found.
*
* @throws Exception NotImplementedException if not implemented.
* @see org.griphyn.cPlanner.classes.Profile
*/
public List<Profile> lookupLFNProfiles( String namespace, String name, String version ) throws
Exception {
throw new UnsupportedOperationException("Not Implemented");
}
/**
* Get the list of Profiles associated with a particular physical transformation.
* @param pfn The physical file name to search the transformation by.
* @param resourceid String The id of the resource on which you want to search.
* @param type TCType The type of the transformation to search for. <br>
* (Enumerated type includes source, binary, dynamic-binary, pacman, installed)<br>
*
* @throws Exception NotImplementedException if not implemented.
* @return List Returns a list of Profile Objects containing profiles
* assocaited with the transformation.
* Returns <B>NULL</B> if no profiless found.
*
* @see org.griphyn.cPlanner.classes.Profile
*/
public List<Profile> lookupPFNProfiles( String pfn, String resourceid, TCType type ) throws
Exception {
logMessage(
"getTCPfnProfiles(String pfn, String resourceid, TCType type)");
logMessage("\t getTCPfnProfiles(" + pfn + "," + resourceid + "," +
type + ")");
List result = null;
List lfnMap = new ArrayList();
if (mTreeMap.containsKey(resourceid)) {
lfnMap.add( (Map) mTreeMap.get(resourceid));
}
for (Iterator i = lfnMap.iterator(); i.hasNext(); ) {
for (Iterator j = ( (Map) i.next()).values().iterator();
j.hasNext(); ) {
for (Iterator k = ( (List) j.next()).iterator(); k.hasNext(); ) {
TransformationCatalogEntry tc = (
TransformationCatalogEntry) k.next();
List profiles = null;
if (tc.getPhysicalTransformation().equals(pfn)) {
if (type == null || tc.getType().equals(type)) {
profiles = tc.getProfiles();
}
if (profiles != null) {
if (result == null) {
result = new ArrayList(10);
}
result.addAll(profiles);
}
}
}
}
}
return result;
}
/**
* List all the contents of the TC
*
* @return List Returns a List of TransformationCatalogEntry objects.
* @throws Exception
*/
public List<TransformationCatalogEntry> getContents() throws Exception {
List result = new ArrayList();
for (Iterator i = mTreeMap.values().iterator(); i.hasNext(); ) {
for (Iterator j = ( (Map) i.next()).values().iterator();
j.hasNext(); ) {
for (Iterator k = ( (List) j.next()).iterator(); k.hasNext(); ) {
TransformationCatalogEntry tc = (
TransformationCatalogEntry) k.next();
result.add(tc);
}
}
}
/* List result = null;
int[] length = {0, 0, 0, 0, 0};
for ( Iterator i = mTreeMap.values().iterator(); i.hasNext(); ) {
for ( Iterator j = ( ( Map ) i.next() ).values().iterator();
j.hasNext(); ) {
for ( Iterator k = ( ( List ) j.next() ).iterator(); k.hasNext(); ) {
TransformationCatalogEntry tc = (
TransformationCatalogEntry ) k.next();
if ( result == null ) {
result = new ArrayList( 10 );
}
String[] s = {tc.getResourceId(),
tc.getLogicalTransformation(),
tc.getPhysicalTransformation(),
tc.getType().toString(), tc.getVDSSysInfo().toString(),
( ( tc.getProfiles() != null ) ?
ProfileParser.combine( tc.getProfiles() ) : "NULL" )};
columnLength( s, length );
result.add( s );
}
}
}
if ( result != null ) {
result.add( length );
}
*/
return result;
}
/**
* ADDITIONS
*/
/**
* Add multiple TCEntries to the Catalog.
*
* @param tcentry List Takes a list of TransformationCatalogEntry objects as input
*
* @throws Exception
* @return number of insertions On failure,throw an exception, don't use zero.
*
* @see edu.isi.pegasus.planner.catalog.TransformationCatalogEntry
*/
public int insert(List<TransformationCatalogEntry> entries) throws
Exception {
for (int i = 0; i < entries.size(); i++) {
TransformationCatalogEntry entry = ( (TransformationCatalogEntry)
entries.get(i));
this.insert(entry);
}
return entries.size();
}
/**
* Add single TCEntry to the Catalog.
* @param tcentry Takes a single TransformationCatalogEntry object as input
* @throws Exception
*
* @return number of insertions, should always be 1. On failure,
* throw an exception, don't use zero.
*
* @see edu.isi.pegasus.planner.catalog.TransformationCatalogEntry
*/
public int insert(TransformationCatalogEntry entry) throws
Exception {
return this.insert(entry.getLogicalNamespace(),
entry.getLogicalName(), entry.getLogicalVersion(),
entry.getPhysicalTransformation(),
entry.getType(), entry.getResourceId(), null,
entry.getProfiles(), entry.getSysInfo()) ;
}
/**
* Add single TCEntry object temporarily to the in memory Catalog.
* This is a hack to get around for adding soft state entries to the TC
* @param tcentry Takes a single TransformationCatalogEntry object as input
* @param write boolean enable write commits to backed catalog or not.
* @throws Exception
*
* @return number of insertions, should always be 1. On failure,
* throw an exception, don't use zero.
*
*
* @see edu.isi.pegasus.planner.catalog.TransformationCatalogEntry
*/
public int insert(TransformationCatalogEntry entry, boolean write) throws
Exception {
if (this.addTCEntry(entry.getLogicalNamespace(),
entry.getLogicalName(), entry.getLogicalVersion(),
entry.getPhysicalTransformation(),
entry.getType(), entry.getResourceId(), null,
entry.getProfiles(), entry.getSysInfo(),
entry.getNotifications(), write)){
return 1;
}else{
throw new RuntimeException("Failed to add TransformationCatalogEntry " + entry.getLogicalName());
}
}
/**
* Add an single entry into the transformation catalog.
*
* @param namespace String The namespace of the transformation to be added (Can be null)
* @param name String The name of the transformation to be added.
* @param version String The version of the transformation to be added. (Can be null)
* @param physicalname String The physical name/location of the transformation to be added.
* @param type TCType The type of the physical transformation.
* @param resourceid String The resource location id where the transformation is located.
* @param lfnprofiles List The List of Profile objects associated with a Logical Transformation. (can be null)
* @param pfnprofiles List The List of Profile objects associated with a Physical Transformation. (can be null)
* @param sysinfo SysInfo The System information associated with a physical transformation.
*
* @return number of insertions, should always be 1. On failure,
* throw an exception, don't use zero.
*
*
* @throws Exception
*
* @see edu.isi.pegasus.planner.catalog.TransformationCatalogEntry
* @see edu.isi.pegasus.planner.catalog.classes.SysInfo
* @see org.griphyn.cPlanner.classes.Profile
*/
public int insert(String namespace, String name,
String version,
String physicalname, TCType type,
String resourceid,
List pfnprofiles, List lfnprofiles,
SysInfo system) throws
Exception {
if(this.addTCEntry(namespace, name, version, physicalname, type,
resourceid, lfnprofiles, pfnprofiles, system, null, true)) {
return 1;
}else{
throw new RuntimeException("Failed to add TransformationCatalogEntry " + name);
}
}
/**
* Add an single entry into the transformation catalog.
*
* @param namespace the namespace of the transformation to be added (Can be null)
* @param name the name of the transformation to be added.
* @param version the version of the transformation to be added. (Can be null)
* @param physicalname the physical name/location of the transformation to be added.
* @param type the type of the physical transformation.
* @param resourceid the resource location id where the transformation is located.
* @param lfnprofiles the List of <code>Profile</code> objects associated
* with a Logical Transformation. (can be null)
* @param pfnprofiles the list of <code>Profile</code> objects associated
* with a Physical Transformation. (can be null)
* @param system the System information associated with a physical
* transformation.
* @param invokes the Notifications associated with the
* transformation.
* @param write boolean to commit changes to backend catalog
* @return boolean true if succesfully added, returns false if error and
* throws exception.
*
* @throws Exception
*
* @see org.griphyn.common.catalog.TransformationCatalogEntry
* @see edu.isi.pegasus.planner.catalog.classes.SysInfo
* @see org.griphyn.cPlanner.classes.Profile
*/
protected boolean addTCEntry(String namespace, String name,
String version,
String physicalname, TCType type,
String resourceid,
List pfnprofiles, List lfnprofiles,
SysInfo system,
Notifications invokes,
boolean write) throws
Exception {
TransformationCatalogEntry entry = new TransformationCatalogEntry();
entry.setLogicalNamespace(namespace);
entry.setLogicalName(name);
entry.setLogicalVersion(version);
entry.setPhysicalTransformation(physicalname);
entry.setType(type);
entry.setResourceId(resourceid);
entry.addProfiles(lfnprofiles);
entry.addProfiles(pfnprofiles);
entry.setVDSSysInfo( NMI2VDSSysInfo.nmiToVDSSysInfo(system) );
entry.addNotifications(invokes);
Map lfnMap = null;
if (mTreeMap.containsKey(resourceid)) {
lfnMap = (Map) mTreeMap.get(resourceid);
}
else {
lfnMap = new TreeMap();
mTreeMap.put(resourceid, lfnMap);
}
List pfnList = null;
if (lfnMap.containsKey(entry.getLogicalTransformation())) {
pfnList = (List) lfnMap.get(entry.getLogicalTransformation());
}
else {
pfnList = new ArrayList(2);
lfnMap.put(entry.getLogicalTransformation(), pfnList);
}
boolean add = true;
for (Iterator i = pfnList.iterator(); i.hasNext(); ) {
TransformationCatalogEntry test = (TransformationCatalogEntry) i.
next();
if (test.equals(entry)) {
add = false;
}
}
if (add) {
pfnList.add(entry);
if (write) {
mFlushOnClose = true;
//writeTC();
}
}
else {
mLogger.log("TC Entry already exists. Skipping",
LogManager.DEBUG_MESSAGE_LEVEL);
}
return true;
}
/**
* Add additional profile to a logical transformation .
*
* @param namespace String The namespace of the transformation to be added. (can be null)
* @param name String The name of the transformation to be added.
* @param version String The version of the transformation to be added. (can be null)
* @param profiles List The List of Profile objects that are to be added
* to the transformation.
*
* @return number of insertions. On failure, throw an exception, don't use zero.
*
* @throws Exception
* @see org.griphyn.cPlanner.classes.Profile
*/
public int addLFNProfile(String namespace, String name,
String version,
List profiles) throws Exception {
throw new UnsupportedOperationException("Not Implemented");
}
/**
* Add additional profile to a physical transformation.
* @param pfn String The physical name of the transformation
* @param type TCType The type of transformation that the profile is
* associated with.
* @param resourcename String The resource on which the physical transformation exists
* @param profiles The List of Profile objects that are to be added
* to the transformation.
* @return number of insertions. On failure, throw an exception, don't use zero.
*
* @throws Exception
* @see org.griphyn.cPlanner.classes.Profile
*/
public int addPFNProfile(String pfn, TCType type,
String resourcename,
List profiles) throws Exception {
throw new UnsupportedOperationException("Not Implemented");
}
/**
* DELETIONS
*/
/**
* Delete all entries in the transformation catalog for a give logical tranformation and/or on a resource and/or of
* a particular type
* @param namespace String The namespace of the transformation to be deleted. (can be null)
* @param name String The name of the transformation to be deleted.
* @param version String The version of the transformation to be deleted. ( can be null)
* @param resourceid String The resource id for which the transformation is to be deleted.
* If <B>NULL</B> then transformation on all resource are deleted
* @param type TCType The type of the transformation. If <B>NULL</B> then all types are deleted for the transformation.
* @throws Exception
*
* @return the number of removed entries.
*
* @see edu.isi.pegasus.planner.catalog.transformation.classes.TCType
*/
public int removeByLFN(String namespace, String name,
String version, String resourceid,
TCType type) throws Exception {
throw new UnsupportedOperationException("Not Implemented");
}
/**
* Delete all entries in the transformation catalog for pair of logical and physical transformation.
* @param physicalname String The physical name of the transformation
* @param namespace String The namespace assocaited in the logical name of the transformation.
* @param name String The name of the logical transformation.
* @param version String The version number of the logical transformation.
* @param resourceid String The resource on which the transformation is to be deleted.
* If <B>NULL</B> then it searches all the resource id.
* @param type TCType The type of transformation. If <B>NULL</B> then it search and deletes entries for all types.
* @throws Exception
*
* @return the number of removed entries.
*
* @see edu.isi.pegasus.planner.catalog.transformation.classes.TCType
*/
public int removeByPFN(String physicalname,
String namespace,
String name, String version,
String resourceid, TCType type) throws
Exception {
throw new UnsupportedOperationException("Not Implemented");
}
/**
* Delete a particular type of transformation, and/or on a particular resource
* @param type TCType The type of the transformation
* @param resourceid String The resource on which the transformation exists.
* If <B>NULL</B> then that type of transformation is deleted from all the resources.
* @throws Exception
*
* @return the number of removed entries.
*
* @see edu.isi.pegasus.planner.catalog.transformation.classes.TCType
*/
public int removeByType(TCType type, String resourceid) throws
Exception {
throw new UnsupportedOperationException("Not Implemented");
}
/**
* Deletes entries from the catalog which have a particular system information.
* @param sysinfo SysInfo The System Information by which you want to delete
*
* @return the number of removed entries.
*
* @see edu.isi.pegasus.planner.catalog.classes.SysInfo
* @throws Exception
*/
public int removeBySysInfo( SysInfo sysinfo) throws
Exception {
throw new UnsupportedOperationException("Not Implemented");
}
/**
* Delete all entries on a particular resource from the transformation catalog.
* @param resourceid String The resource which you want to remove.
* @throws Exception
*
* @return the number of removed entries.
*/
public int removeBySiteID(String resourceid) throws Exception {
if (mTreeMap.containsKey(resourceid)) {
mTreeMap.remove(resourceid);
mFlushOnClose = true;
//writeTC();
return 1;
}else{
return 0;
}
}
/**
* Deletes the entire transformation catalog. CLEAN............. USE WITH CAUTION.
*
* @return the number of removed entries.
*
* @throws Exception
*/
public int clear() throws Exception {
int length = mTreeMap.size();
mTreeMap.clear();
mFlushOnClose = true;
return length;
}
/**
* Delete a list of profiles or all the profiles associated with a pfn on a
* resource and of a type.
*
* @param physicalname String The physical name of the transformation.
* @param type TCType The type of the transformation.
* @param resourceid String The resource of the transformation.
* @param profiles List The list of profiles to be deleted. If <B>NULL</B> then all profiles for that pfn+resource+type are deleted.
*
* @return the number of removed entries.
*
* @see org.griphyn.cPlanner.classes.Profile
* @throws Exception
*/
public int deletePFNProfiles(String physicalname, TCType type,
String resourceid, List profiles) throws
Exception {
throw new UnsupportedOperationException("Not Implemented");
}
/**
* Delete a list of profiles or all the profiles associated with a logical
* transformation.
*
* @param namespace String The namespace of the logical transformation.
* @param name String The name of the logical transformation.
* @param version String The version of the logical transformation.
* @param profiles List The List of profiles to be deleted. If <B>NULL</B>
* then all profiles for the logical transformation are deleted.
*
* @return the number of removed entries.
*
* @see org.griphyn.cPlanner.classes.Profile
* @throws Exception
*/
public int deleteLFNProfiles(String namespace, String name,
String version, List profiles) throws
Exception {
throw new UnsupportedOperationException("Not Implemented");
}
public boolean connect(java.util.Properties props) {
//not implemented
return true;
}
public boolean isClosed() {
return (this.mTreeMap == null);
}
public void close() {
try{
if(mFlushOnClose){
writeTC();
this.mFlushOnClose = false;
}
}finally{
this.mTreeMap = null;
this.mTCFile = null;
}
}
private void writeTC() {
PrintWriter writer = null;
try {
mLogger.log("Starting to write the TC file",
LogManager.DEBUG_MESSAGE_LEVEL);
writer = new PrintWriter(new BufferedWriter(new FileWriter(
mTCFile, false)));
}
catch (IOException e) {
mLogger.log(
"Unable to open TC File for writing\"" + mTCFile, e,
LogManager.ERROR_MESSAGE_LEVEL);
}
int count = 0;
for (Iterator i = mTreeMap.values().iterator(); i.hasNext(); ) {
//get all the values from the main map
for (Iterator j = ( (Map) i.next()).values().iterator();
j.hasNext(); ) {
//for each resource and each logical transformatino get the arraylist.
for (Iterator k = ( (List) j.next()).iterator(); k.hasNext(); ) {
//start printing each entry
writer.println( ( (TransformationCatalogEntry) k.next()).
toTCString());
count++;
}
}
}
mLogger.log("Written " + count +
" entries back to the TC file",
LogManager.DEBUG_MESSAGE_LEVEL);
writer.flush();
writer.close();
mLogger.log( "Starting to write the TC file - DONE",
LogManager.DEBUG_MESSAGE_LEVEL);
}
/**
* Computes the maximum column lenght for pretty printing.
*
* @param s String[]
* @param count int[]
*/
/*
private static void columnLength(String[] s, int[] count) {
for (int i = 0; i < count.length; i++) {
if (s[i].length() > count[i]) {
count[i] = s[i].length();
}
}
}*/
/**
* Populates the internal copy of the transformation catalog from a byte
* stream (input stream). Used in webservices, when clients upload their files.
* It uses the default character encoding.
*
* @param reader the <code>InputStrean</code> containing the bytes to be
* read.
* @return boolean
*/
private boolean populateTC(InputStream reader) {
return populateTC(new InputStreamReader(reader));
}
/**
* Populates the internal copy of the transformation catalog from the file
* containing the transformation catalog in the 6 column format.
*
* @return boolean
*/
private boolean populateTC() {
boolean result = false;
try {
result = populateTC(new FileReader(mTCFile));
} catch (IOException e) {
mLogger.log("Unable to open the file " +
mTCFile, e, LogManager.ERROR_MESSAGE_LEVEL);
return false;
}
return result;
}
/**
* Adds multiple entries into the TC. Calls the above api multiple times.
*
* @param reader the input stream from where to read the contents of the
* transformation catalog.
* @return boolean
*/
private boolean populateTC(Reader reader) {
BufferedReader buf = new BufferedReader(reader);
// String profilestring = null;
int linecount = 0;
int count = 0;
try {
String line = null;
//buf = new BufferedReader( new FileReader( mTCFile ) );
while ( (line = buf.readLine()) != null) {
boolean profile_error=false;
linecount++;
if (! (line.startsWith("#") ||
line.trim().length() == 0)) {
TransformationCatalogEntry tc = new
TransformationCatalogEntry();
String[] tokens = line.trim().split("[ \t]+", 6);
if (tokens.length < 5) {
throw new ScannerException(linecount,
"Invalid TC entry format.");
}
for (int i = 0; i < tokens.length; i++) {
switch (i) {
case 0: //poolname
tc.setResourceId(tokens[i]);
break;
case 1: //logical transformation name
if (tokens[i].indexOf("__") != -1) {
mLogger.log(
"Logical Transformations in the new File TC " +
"are represented as NS::NAME:VER",
LogManager.ERROR_MESSAGE_LEVEL);
mLogger.log("Assuming " + tokens[i] +
" as just the transformation NAME.",
LogManager.DEBUG_MESSAGE_LEVEL);
}
tc.setLogicalTransformation(tokens[i]);
break;
case 2: //pfn
tc.setPhysicalTransformation(tokens[i]);
break;
case 3: //type
if( tokens[i].equalsIgnoreCase( "null") ){
tc.setType( TCType.INSTALLED );
}
else if ( tokens[i].equalsIgnoreCase( "STATIC_BINARY") ){
//if entry is static binary we set it to stageable
tc.setType( TCType.STAGEABLE );
}
else{
//set to whatever the value was
tc.setType(TCType.valueOf(tokens[i]));
}
/*
tc.setType( (tokens[i].equalsIgnoreCase(
"null")) ?
TCType.INSTALLED :
TCType.valueOf(tokens[i]));
*/
break;
case 4: //systeminfo
tc.setVDSSysInfo( (tokens[i].equalsIgnoreCase(
"null")) ?
new VDSSysInfo(null) :
new VDSSysInfo(tokens[i]));
break;
case 5: //profile string
if (!tokens[i].equalsIgnoreCase("null")) {
try {
tc.addProfiles(ProfileParser.parse(
tokens[
i]));
}
catch (ProfileParserException ppe) {
mLogger.log(
"Could not parse profile(s) for transformation \""+
tc.getLogicalTransformation()+
"\" on site \""+ tc.getResourceId()+
"\" on line " + linecount,
LogManager.ERROR_MESSAGE_LEVEL);
mLogger.log(
ppe.getMessage() + " at position "+ ppe.getPosition() +
" for the string \"" + tokens[i]+"\"",
LogManager.ERROR_MESSAGE_LEVEL);
mLogger.log("Ignoring the current transformation. Please fix the profiles shown above."
,LogManager.ERROR_MESSAGE_LEVEL);
profile_error=true;
continue;
}
catch (RuntimeException e) {
mLogger.log(
"Ignoring errors while parsing profile in Transformation Catalog on line " +
linecount, e,
LogManager.WARNING_MESSAGE_LEVEL);
}
}
break;
default:
mLogger.log("Line " + linecount +
" : Humm no need to be in default",
LogManager.ERROR_MESSAGE_LEVEL);
} //end of switch
} //end of for loop
if (profile_error){
//if there is an error while parsing the profile
//Skip adding the entry to TC (As Per JIRA PM-164
continue;
}
// if (count > 0) {
// mLogger.logMessage("Loading line number" + linecount +
// " to the map", 1);
Map lfnMap = null;
if (!mTreeMap.containsKey(tc.getResourceId())) {
lfnMap = new TreeMap();
}
else {
lfnMap = (Map) mTreeMap.get(tc.getResourceId());
}
List entries = null;
if (!lfnMap.containsKey(tc.getLogicalTransformation())) {
entries = new ArrayList(3);
}
else {
entries = (List) lfnMap.get(tc.
getLogicalTransformation());
}
if(modifyFileURL){
entries.add( Abstract.modifyForFileURLS(tc) );
}else{
entries.add(tc);
}
lfnMap.put(tc.getLogicalTransformation(), entries);
mTreeMap.put(tc.getResourceId(), lfnMap);
count++;
} //end of if "#"
} //end of while line
mLogger.log("Loaded " + count + " entries to the TC Map",
LogManager.DEBUG_MESSAGE_LEVEL);
buf.close();
return true;
}
catch (FileNotFoundException ex) {
mLogger.log("The tc text file " + mTCFile +
" was not found", LogManager.ERROR_MESSAGE_LEVEL);
mLogger.log("Considering it as Empty TC",
LogManager.ERROR_MESSAGE_LEVEL);
return true;
}
catch (IOException e) {
mLogger.log("Unable to open the file " +
mTCFile, e, LogManager.ERROR_MESSAGE_LEVEL);
return false;
}
catch (IllegalStateException e) {
mLogger.log("On line " + linecount + "in File " +
mTCFile + "\n", e, LogManager.ERROR_MESSAGE_LEVEL);
return false;
}
catch (Exception e) {
mLogger.log(
"While loading entries into the map on line " + linecount +
"\n", e, LogManager.ERROR_MESSAGE_LEVEL);
return false;
}
}
/**
* Returns the file source.
*
* @return the file source if it exists , else null
*/
public java.io.File getFileSource(){
if( mTCFile != null ){
java.io.File f = new java.io.File( mTCFile );
if( f.canRead() ){
return f;
}
}
return null;
}
/**
* Logs the message to a logging stream. Currently does not log to any stream.
*
* @param msg the message to be logged.
*/
protected void logMessage(String msg) {
//mLogger.logMessage("[Shishir] Transformation Catalog : " + msg);
}
}