/** * 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.client; import java.util.HashMap; import java.util.Map; import edu.isi.pegasus.common.logging.LogManager; import edu.isi.pegasus.common.logging.LogManagerFactory; import edu.isi.pegasus.common.util.FactoryException; import edu.isi.pegasus.common.util.Version; import edu.isi.pegasus.planner.catalog.TransformationCatalog; import edu.isi.pegasus.planner.catalog.transformation.TransformationFactory; import edu.isi.pegasus.planner.catalog.transformation.client.TCAdd; import edu.isi.pegasus.planner.catalog.transformation.client.TCDelete; import edu.isi.pegasus.planner.catalog.transformation.client.TCQuery; import gnu.getopt.Getopt; import gnu.getopt.LongOpt; /** * A common client to add, modify, delete, query any Transformation Catalog * implementation. * * @author Gaurang Mehta * @version $Revision$ */ public class TCClient extends Executable{ public String classname; private int add = 0; private int query = 0; private int delete = 0; private int bulk = 0; private int islfn = 0; private int ispfn = 0; private int isresource = 0; private int isprofile = 0; private int istype = 0; private int issysinfo = 0; private boolean isxml = false; private boolean isoldformat = false; private String lfn = null; private String pfn = null; private String profile = null; private String type = null; private String resource = null; private String system = null; private String file = null; private TransformationCatalog tc = null; private Map argsmap = null; private Version version = Version.instance(); public TCClient() { super(); } public void initialize(String[] opts){ super.initialize(opts); } public void loadProperties() { } /** * Sets up the logging options for this class. Looking at the properties * file, sets up the appropriate writers for output and stderr. */ protected void setupLogging(){ //setup the logger for the default streams. mLogger = LogManagerFactory.loadSingletonInstance( mProps ); mLogger.logEventStart( "event.pegasus.tc-client", "client.version", mVersion, LogManager.DEBUG_MESSAGE_LEVEL ); } public LongOpt[] generateValidOptions() { LongOpt[] longopts = new LongOpt[16 ]; longopts[ 0 ] = new LongOpt( "add", LongOpt.NO_ARGUMENT, null, 'a' ); longopts[ 1 ] = new LongOpt( "delete", LongOpt.NO_ARGUMENT, null, 'd' ); longopts[ 2 ] = new LongOpt( "query", LongOpt.NO_ARGUMENT, null, 'q' ); longopts[ 3 ] = new LongOpt( "lfn", LongOpt.REQUIRED_ARGUMENT, null, 'l' ); longopts[ 4 ] = new LongOpt( "pfn", LongOpt.REQUIRED_ARGUMENT, null, 'p' ); longopts[ 5 ] = new LongOpt( "profile", LongOpt.REQUIRED_ARGUMENT, null, 'e' ); longopts[ 6 ] = new LongOpt( "type", LongOpt.REQUIRED_ARGUMENT, null, 't' ); longopts[ 7 ] = new LongOpt( "file", LongOpt.REQUIRED_ARGUMENT, null, 'f' ); longopts[ 8 ] = new LongOpt( "help", LongOpt.NO_ARGUMENT, null, 'h' ); longopts[ 9 ] = new LongOpt( "version", LongOpt.NO_ARGUMENT, null, 'V' ); longopts[ 10 ] = new LongOpt( "verbose", LongOpt.NO_ARGUMENT, null, 'v' ); longopts[ 11 ] = new LongOpt( "resource", LongOpt.REQUIRED_ARGUMENT, null, 'r' ); longopts[ 12 ] = new LongOpt( "system", LongOpt.REQUIRED_ARGUMENT, null, 's' ); longopts[ 13 ] = new LongOpt( "xml", LongOpt.NO_ARGUMENT, null, 'x' ); longopts[ 14 ] = new LongOpt( "oldformat", LongOpt.NO_ARGUMENT, null, 'o' ); longopts[ 15 ] = new LongOpt( "conf", LongOpt.REQUIRED_ARGUMENT, null, 'c' ); return longopts; } /** * Call the correct commands depending on options. * @param opts String[] The arguments obtained from the command line. */ public void executeCommand() { String[] opts = getCommandLineOptions(); if(opts.length == 0){ mLogger.log("Please provide the required options.",LogManager.ERROR_MESSAGE_LEVEL); this.printShortVersion(); System.exit(1); } LongOpt[] longOptions = generateValidOptions(); Getopt g = new Getopt( "TCClient", opts, "adqhvxoVLPERTBSs:t:l:p:r:e:f:c:", longOptions, false ); int option = 0; int level = 0; while ( ( option = g.getopt() ) != -1 ) { switch ( option ) { case 'q': //output query = 1; break; case 'a': add = 2; break; case 'd': delete = 4; break; case 'B': bulk = 1; break; case 'L': islfn = 2; break; case 'P': ispfn = 4; break; case 'R': isresource = 8; break; case 'E': isprofile = 16; break; case 'T': istype = 32; break; case 'S': issysinfo = 64; break; case 't': type = g.getOptarg(); break; case 's': system = g.getOptarg(); break; case 'l': lfn = g.getOptarg(); break; case 'p': pfn = g.getOptarg(); break; case 'e': if ( profile != null ) { profile = profile + ";" + g.getOptarg(); } else { profile = g.getOptarg(); } break; case 'f': file = g.getOptarg(); break; case 'r': resource = g.getOptarg(); break; case 'h': //help printLongVersion(); System.exit( 0 ); break; case 'V': //version System.out.println(version.toString()); System.exit( 0 ); case 'v': //Verbose mode level++; break; case 'x': //Is XML isxml = true; if(isoldformat){ throw new IllegalArgumentException("Error: Illegal Argument passed. Options -x and -o cannot be set at the same time"); } break; case 'o': //Is Old format isoldformat = true; if(isxml){ throw new IllegalArgumentException("Error: Illegal Argument passed. Options -x and -o cannot be set at the same time"); } break; case 'c': //do nothing break; default: mLogger.log( "Unrecognized option or Invalid argument to option " + (char)g.getOptopt(), LogManager.FATAL_MESSAGE_LEVEL ); printShortVersion(); System.exit( 1 ); break; } } if(level >0){ mLogger.setLevel( level ); }else{ mLogger.setLevel(LogManager.WARNING_MESSAGE_LEVEL); } //calculating the value of the trigger int trigger = bulk + islfn + ispfn + isresource + isprofile + istype + issysinfo; argsmap = new HashMap( 11 ); argsmap.put( "trigger", new java.lang.Integer( trigger ) ); argsmap.put( "lfn", lfn ); argsmap.put( "pfn", pfn ); argsmap.put( "profile", profile ); argsmap.put( "type", type ); argsmap.put( "resource", resource ); argsmap.put( "system", system ); argsmap.put( "file", file ); argsmap.put( "isxml", new Boolean( isxml ) ); argsmap.put( "isoldformat", new Boolean( isoldformat ) ); //Select what operation is to be performed. int operationcase = query + add + delete; //load the transformation catalog if required try{ if (operationcase == 1 || operationcase == 4 || operationcase == 2) { this.mProps.setProperty(TransformationCatalog.MODIFY_FOR_FILE_URLS_KEY, "false"); tc = TransformationFactory.loadInstance(this.mProps); } } catch ( FactoryException fe){ mLogger.log( convertException(fe,mLogger.getLevel()) , LogManager.FATAL_MESSAGE_LEVEL); System.exit( 2 ); } try{ switch ( operationcase ) { case 1: //QUERY OPERATION SELECTED TCQuery tcquery = new TCQuery( tc, mLogger, argsmap ); tcquery.doQuery(); break; case 2: //ADD OPERATION SELECTED TCAdd tcadd = new TCAdd( tc, mLogger, argsmap ); tcadd.doAdds(); break; case 4: //DELETE OPERATION SELECTED TCDelete tcdelete = new TCDelete( tc, mLogger, argsmap ); tcdelete.doDelete(); break; default: //ERROR IN SELECTION OPERATION mLogger.log( "Please specify the correct operation for the client." + "Only one operation can be done at a time.", LogManager.FATAL_MESSAGE_LEVEL ); this.printShortVersion(); System.exit( -1 ); } }finally{ if(tc != null){ if(!tc.isClosed()){ tc.close(); } } } mLogger.logEventCompletion( LogManager.DEBUG_MESSAGE_LEVEL ); } public void printShortVersion() { String text = "\n " + version.toString() + "\n Usage :pegasus-tc-client [ operation ] [ operation arguments ]" + "\n Type pegasus-tc-client -h for more details"; System.out.println(text); System.exit( 1 ); } public void printLongVersion() { String text = "\n" + version.toString() + "\n" + "\n pegasus-tc-client - This client is used to add, delete, query any Tranformation Catalog implemented to the TC interface." + "\n" + "\n Usage: pegasus-tc-client [Operation] [Triggers] [Options]...." + "\n" + "\n Operations :" + "\n ------------" + "\n Always one of these operations have to be specified." + "\n" + "\n -a | --add Perform addition operations on the TC." + "\n -d | --delete Perform delete operations on the TC." + "\n -q | --query Perform query operations on the TC." + "\n" + "\n Triggers :" + "\n ----------" + "\n" + "\n -L Triggers an operation on a logical transformation" + "\n -P Triggers an operation on a physical transformation" + "\n -R Triggers an operation on a resource" + "\n -E Triggers an operation on a Profile" + "\n -T Triggers an operation on a Type" + "\n -B Triggers a bulk operation." + "\n" + "\n Options :" + "\n ---------" + "\n" + "\n -l | --lfn <logical txmation> The logical transformation to be added in the format NAMESPACE::NAME:VERSION." + "\n (The name is always required, namespace and version are optional.)" + "\n -p | ---pfn <physical txmation> The physical transfromation to be added. " + "\n For INSTALLED executables its a local file path, for all others its a url." + "\n -t | --type <type of txmation> The type of physical transformation. Valid values are :" + "\n INSTALLED, STAGEABLE. " + "\n -r | --resource <resource id> The Id of the resource where the transformation is located. " + "\n -e | --profile <profiles> The profiles belonging to the transformation." + "\n Mulitple profiles of same namespace can be added simultaneously" + "\n by seperating them with a comma \",\"." + "\n Each profile section is written as NAMESPACE::KEY=VALUE,KEY2=VALUE2 " + "\n e.g. ENV::JAVA_HOME=/usr/bin/java2,PEGASUS_HOME=/usr/local/vds" + "\n To add muliple namespaces you need to repeat the -e option for each namespace." + "\n e.g -e ENV::JAVA_HOME=/usr/bin/java -e GLOBUS::JobType=MPI,COUNT=10" + "\n -s | --system <system type> The architecture,os and glibc if any for the executable." + "\n Each system info is written in the form ARCH::OS:OSVER:GLIBC" + "\n The allowed ARCH's are x86, x86_64, ppc, ppc_64, ia64, sparcv7, sparcv9, amd64" + "\n The allowed OS's are LINUX, SUNOS, AIX, MACOSX, WINDOWS" + "\n" + "\n Other Options :" + "\n ---------------" + "\n" + "\n --xml | -x Generates the output in the xml format " + "\n --oldformat | -o Generates the output in the old single line format " + "\n --conf | -c path to property file" + "\n --verbose | -v increases the verbosity level" + "\n --version | -V Displays the version number of the Griphyn Virtual Data System software " + "\n --help | -h Generates this help" + "\n" + "\n Valid Combinations :" + "\n --------------------" + "\n ADD" + "\n ---" + "\n " + "\n\tAdd TC Entry : -a -l <lfn> -p <pfn> -r <resource> [-t <type>] [-s <system>] [-e <profiles> ....]" + "\n\tAdd PFN Profile : -a -P -E -p <pfn> -t <type> -r <resource> -e <profiles> ...." + "\n\tAdd LFN Profile : -a -L -E -l <lfn> -e <profiles> ...." + "\n\tAdd Bulk Entries : -a -B -f <file>" + "\n" + "\n DELETE" + "\n ------" + "\n" + "\n\tDelete all TC : -d -BPRELST " + "\n\t (!!!WARNING : THIS DELETES THE ENTIRE TC!!!)" + "\n\tDelete by LFN : -d -L -l <lfn> [-r <resource>] [-t <type>]" + "\n\tDelete by PFN : -d -P -l <lfn> -p <pfn> [-r <resource>] [-t type]" + "\n\tDelete by Type : -d -T -t <type> [-r <resource>]" + "\n\tDelete by Resource : -d -R -r <resource>" + "\n\tDelete by SysInfo : -d -S -s <sysinfo>" + "\n\tDelete Pfn Profile : -d -P -E -p <pfn> -r <resource> -t <type> [-e <profiles> ....]" + "\n\tDelete Lfn Profile : -d -L -E -l <lfn> [-e <profiles> .....]" + "\n" + "\n QUERY" + "\n -----" + "\n " + "\n\tQuery Bulk : -q -B" + "\n\tQuery LFN : -q -L [-r <resource>] [-t <type>]" + "\n\tQuery PFN : -q -P -l <lfn> [-r <resource>] [-t <type>]" + "\n\tQuery Resource : -q -R -l <lfn> [-t <type>]" + "\n\tQuery Lfn Profile : -q -L -E -l <lfn>" + "\n\tQuery Pfn Profile : -q -P -E -p <pfn> -r <resource> -t <type>" + "\n"; System.out.println(text); System.exit( 0 ); } public static void main( String[] args ) throws Exception { TCClient client = new TCClient(); client.initialize(args); client.executeCommand( ); } }