/**
* 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.transfer;
import edu.isi.pegasus.planner.common.PegasusProperties;
import edu.isi.pegasus.common.logging.LogManager;
import edu.isi.pegasus.common.logging.LogManagerFactory;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.StringTokenizer;
/**
* A common class, that builds up the state from the properties to determine
* whether a user wants certain type of transfer jobs for particular site to
* run remotely. This allows a user to override the default behavior of how
* Pegasus decides whether a transfer job runs locally ( on the submit host) or
* remotely.
*
*
* @author Karan Vahi
* @version $Revision$
*/
public class RemoteTransfer {
/**
* The constant to apply to all sites.
*/
public static final String ALL_SITES = "*";
/**
* The property name to get the sites for which all transfers need to
* be executed remotely.
*/
public static final String ALL_TRANSFERS_REMOTE_PROPERTY =
"pegasus.transfer.*.remote.sites";
/**
* The property name to get the sites for which stage-in transfers need to
* be executed remotely.
*/
public static final String STAGE_IN_TRANSFERS_REMOTE_PROPERTY =
"pegasus.transfer.stagein.remote.sites";
/**
* The property name to get the sites for which inter site transfers need
* to be executed remotely.
*/
public static final String INTER_TRANSFERS_REMOTE_PROPERTY =
"pegasus.transfer.inter.remote.sites";
/**
* The property name to get the sites for which stage-out transfers need to
* be executed remotely.
*/
public static final String STAGE_OUT_TRANSFERS_REMOTE_PROPERTY =
"pegasus.transfer.stageout.remote.sites";
/**
* An internal table that maps remote transfer type to the corresponding
* property.
*/
private static Map mPropertyTable;
/**
* The handle to the properties object holding the properties relevant to
* Pegasus.
*/
private PegasusProperties mProps;
/**
* The handle to the logging object.
*/
private LogManager mLogger;
/**
* The map indexed by site name, that contains the state for all the sites.
*/
private Map mStateMap;
/**
* Singleton access to the type table
* Contains the mapping of a property to the third party transfer type
*
* @return map
*/
private static Map propertyTable(){
//singleton access
if (mPropertyTable == null) {
mPropertyTable = new TreeMap();
mPropertyTable.put(new Integer(TransferState.STAGE_IN_REMOTE_TYPE),
STAGE_IN_TRANSFERS_REMOTE_PROPERTY);
mPropertyTable.put(new Integer(TransferState.INTER_REMOTE_TYPE),
INTER_TRANSFERS_REMOTE_PROPERTY);
mPropertyTable.put(new Integer(TransferState.STAGE_OUT_REMOTE_TYPE),
STAGE_OUT_TRANSFERS_REMOTE_PROPERTY);
mPropertyTable.put(new Integer(TransferState.ALL_REMOTE_TYPE),
ALL_TRANSFERS_REMOTE_PROPERTY);
}
return mPropertyTable;
}
/**
* The default constructor.
*/
public RemoteTransfer() {
mProps = PegasusProperties.getInstance();
mLogger = LogManagerFactory.loadSingletonInstance( );
mStateMap = new TreeMap();
}
/**
* The overloaded constructor.
*
* @param properties handle to the properties required.
*/
public RemoteTransfer(PegasusProperties properties) {
mProps = properties;
mLogger = LogManagerFactory.loadSingletonInstance( properties );
mStateMap = new TreeMap();
}
/**
* Builds up the remote transfers state for all the sites. This reflects what is
* set in the properties file.
*/
public void buildState(){
String site;
Set sites;
//build for stagein transfers
buildState(TransferState.STAGE_IN_REMOTE_TYPE);
//build for inter site transfers
buildState(TransferState.INTER_REMOTE_TYPE);
//build for stage out transfers
buildState(TransferState.STAGE_OUT_REMOTE_TYPE);
//build for all transfers
buildState(TransferState.ALL_REMOTE_TYPE);
//put the all sites (site = *) entry
TransferState allState;
if(containsKey(ALL_SITES)){
allState = get(ALL_SITES);
}
else{
allState = new TransferState();
put(ALL_SITES,allState);
}
if(allState.getState() != 0x0){
//apply the state to all sites
for(Iterator it = mStateMap.values().iterator();it.hasNext();){
TransferState state = (TransferState)it.next();
state.set(allState.getState());
}
}
}
/**
* Adds to the existing state table, state information for a particular
* type of transfers.
*
* @param type the type of transfer.
*/
private void buildState(int type){
String property = (String)propertyTable().get(new Integer(type));
Set sites = getThirdPartySites(
(type > TransferState.ALL_REMOTE_TYPE)?
mProps.getThirdPartySitesRemote(property):
mProps.getThirdPartySites(property)
);
String site;
for(Iterator it = sites.iterator();it.hasNext();){
site = (String)it.next();
TransferState state = containsKey(site)?
get(site):
new TransferState();
state.set(type);
put(site, state);
}
}
/**
* Returns a boolean indicating whether to execute stage-in transfers on
* remote site or not.
*
* @return boolean
*/
public boolean stageInOnRemoteSite(String site){
return containsKey(site)?
get(site).get(TransferState.STAGE_IN_REMOTE_TYPE):
//return the value for all sites
get(ALL_SITES).get(TransferState.STAGE_IN_REMOTE_TYPE);
}
/**
* Returns a boolean indicating whether to execute inter site transfers on
* remote site or not.
*
* @return boolean
*/
public boolean interOnRemoteSite(String site){
return containsKey(site)?
get(site).get(TransferState.INTER_REMOTE_TYPE):
//return the value for all sites
get(ALL_SITES).get(TransferState.INTER_REMOTE_TYPE);
}
/**
* Returns a boolean indicating whether to execute stage-out transfers on
* remote site or not.
*
* @return boolean
*/
public boolean stageOutOnRemoteSite(String site){
return containsKey(site)?
get(site).get(TransferState.STAGE_OUT_REMOTE_TYPE):
//return the value for all sites
get(ALL_SITES).get(TransferState.STAGE_OUT_REMOTE_TYPE);
}
/**
* Prints out the third party state for the various sites.
*/
public void print(){
StringBuffer sb = new StringBuffer();
TransferState allSitesState = null;
Object key;
sb.append("Site | SI_REMOTE, IN_REMOTE , SO_REMOTE");
for(Iterator it = mStateMap.entrySet().iterator();it.hasNext();){
Map.Entry entry = (Map.Entry)it.next();
key = entry.getKey();
if(key.equals(ALL_SITES)){
//store value for printing in the end
allSitesState = (TransferState)entry.getValue();
}
else{
sb.append('\n').append(key).append(" | ").append(entry.getValue());
}
}
if(allSitesState != null){
sb.append('\n').append(ALL_SITES).append(" ").append(" | ").append(allSitesState);
}
System.out.println(sb.toString());
}
/**
* Returns whether there is an entry for a particular site or not.
*
* @param site the site handle for a site.
*
* @return boolean
*/
private boolean containsKey(String site){
return mStateMap.containsKey(site);
}
/**
* Inserts an entry in to the State Map, that maintains state of various
* sites.
*
* @param site the site handle for a site.
* @param state the thirdparty state for the site.
*/
private void put(String site,TransferState state){
mStateMap.put(site, state);
}
/**
* Returns the TPT state for a particular site.
*
* @param site the site handle for the site.
* @return state the third party state for the site if there is an entry,
* else null.
*/
private TransferState get(String site){
Object state = mStateMap.get(site);
return (state == null)?null:(TransferState)state;
}
/**
* Returns a set of third party sites. An empty set is returned if value is
* null.
*
* @param value the value in the properties file.
*
* @return Set containing the names of the pools.
*/
private Set getThirdPartySites(String value) {
HashSet set = new HashSet();
String site;
if (value == null) {
return set;
}
for (StringTokenizer st = new StringTokenizer(value, ",");st.hasMoreTokens();){
site = (String) st.nextToken();
/*
mLogger.log(site + " is a third party enabled site " +
"for " + desc + " transfers",
LogManager.DEBUG_MESSAGE_LEVEL);
*/
set.add(site);
}
return set;
}
/**
* An inner class that holds the state for a particular site,as to whether to
* execute transfers remotely or not.
*
*/
private static class TransferState{
/**
* The constant to denote that a stage-in transfer is to be exectuted remotely
*/
public static final int STAGE_IN_REMOTE_TYPE= 0x1; //000001
/**
* The constant to denote that an inter site transfer is to be exectuted remotely
*/
public static final int INTER_REMOTE_TYPE = 0x2; //000010
/**
* The constant to denote that a stage-out transfer is to be exectuted remotely
*/
public static final int STAGE_OUT_REMOTE_TYPE = 0x4;//000100
/**
* The constant to denote that all transfers are to be exectuted remotely
*/
public static final int ALL_REMOTE_TYPE = 0x7; //000111
/**
* Stores the state as an integer.
*/
private int mState;
/**
* The default constructor.
*/
public TransferState(){
mState = 0x0;
}
/**
* Returns the state.
*
* @return the state as an int
*/
public int getState(){
return mState;
}
/**
* Sets a type of transfer to be third party.
*
* @param type the type of transfer to be set TPT
*/
public void set(int type){
//no type checking for time being
mState = mState | type;
}
/**
* Returns a boolean indicating whether the attribute passed is set
* in the transfer state or not.
* The attribute types are as constants in this class.
*
* @param type the attribute type.
*/
public boolean get(int type){
return ((mState & type) == type);
}
/**
* Returns a textual description of the state as
* (stageinRemote,interRemote,stageoutRemote).
*
* @return the textual description.
*/
public String toString(){
StringBuffer sb = new StringBuffer(36);
sb.append('(').
append(this.get(TransferState.STAGE_IN_REMOTE_TYPE)).append(" ").append(',').
append(this.get(TransferState.INTER_REMOTE_TYPE)).append(" ").append(',').
append(this.get(TransferState.STAGE_OUT_REMOTE_TYPE)).
append(')');
return sb.toString();
}
}
}