Java CoG Kit Abstractions Guide
Kaizar Amin and Gregor von Laszewski
Contents
1 About this Document
This document includes basic information about the different Java CoG Kit abstractions and their intended
usage.
1.1 Reproduction
The material presented in this document can not be published, mirrored, electronically or otherwise
reproduced without prior written consent. As you can link to this document, this should not pose much of a
restriction.
1.2 Viewing
The best way to read this document is with Adobe Acrobat Reader. Please make sure you configure Adobe Acrobat
Reader appropriately so you can follow hyperlinks. This is the case if you follow the default installation. Acrobat
Reader is available at http://www.adobe.com/products/acrobat/readermain.html. Because the hyperlinks are
not available in the printed form of this manual and we support saving our environment we strongly discourage
printing this document.
We recommend that you save this manual locally on your machine and use Acrobat Reader. This has the advantage
that you do not lose your anchor points while switching back and forth between different hyperlinks. An HTML
version of this manual is planed, but not available yet.
1.3 Format
We have augmented the document with some comments at places where we found issues. Our intend is to address
these issues in a future release. The comments are marked by the icon to do and the name of the person that
will work on the removal of the issue.
2 Registration
Please be a team player and support us indirectly by registering with us or reporting your use of the Java CoG Kit.
Although this software is free, we still need to justify to our funders the usefulness of the projects.
If you want to help us with our efforts please take a few seconds to complete this information. We
do not use this information for other purposes. If you have special needs or concerns please contact
gregor@mcs.anl.gov. The registration form can filled out in a variety of formats. The online form can be found
at
This form is available also as ASCII text at
which you can FAX to
Gregor von Laszewski, Fax: 630 252 1997
3 Introduction
The Java Cog Kit abstractions offers a programming model that supports elementary Grid patterns such as job
execution, file transfer, and file operations. It also provides advanced patterns such as execution (control) flows in
the form of directed acyclic graphs (DAG).
The abstractions module is based on a Grid abstraction model, de-coupling the Grid patterns from their
implementation. The applications developed with the offered Grid abstractions are independent of the low-level Grid
implementations. Hence, applications are shielded from changes in the low-level Grid protocols and
interfaces.
The abstractions module offers the following benefits to Grid application programmers:
- develop client applications that will be interoperable across multiple Grid backend implementations;
- provide reusable code to support rapid prototyping of basic Grid access patterns;
- provide an open-source and extensible architecture that can be built collectively and incrementally
based on community feedback; and
- access the same set of interfaces implemented in disparate technologies.
The job execution pattern in cog-abstractions currently supports GT v2.4.3, GT v3.0.2, GT v3.2.0, GT v3.2.1, GT
v4.0.0, Condor, and SSH implementations. Other platforms (Condor and Unicore) will be supported in
future releases upon request by the community. We like to invite the community to participate in these
activities.
The file transfer pattern in cog-bastractions allows file transfers between GridFTP, FTP, WebDAV, and SSH
resources.
The file operation pattern in cog-abstractions permits remote file access operations (such as ls, chmod, cd, get, put)
on files hosted on GridFTP, FTP, and WebDAV resources.
4 Installation
Cog-abstractions source is available with the Java CoG Kit v4. Instructions for downloading the Java Cog Kit are
available in the Java CoG Kit Installation Guide at Url: \MANUALBASE/install.pdf.
We note that cog-abstractions is explicitly a client-side library. The current version of cog-abstractions provides
support for GT v2.4.3, GT v3.0.2, GT v3.2.0 GT v3.2.1, GT v4.0.0, Condor, SSH, FTP, and WebDAV. In future, we
will provide also support for GT4.
Hence, in order to execute job submission tasks with our abstractions, the reader is directed to install GT v2.4.3,
GT v3.0.2, GT v3.2.0, GT v3.2.1, GT v4.0.0, Condor, or an SSH job submission server. Likewise, in order to execute
file transfer and file operation tasks, the reader is directed to install the GridFTP, FTP, and WebDAV file
servers.
For details on installing the Globus Toolkit please visit the Globus Alliance Web page http://www.globus.org
4.1 Examples
Several examples that demonstrate the ease of use and functionality of the Java CoG Kit abstractions are provided
with the Java CoG Kit distribution. These examples are well documented in the Java CoG Kit Example Guide at
Url: \MANUALBASE/examples.pdf.
The examples are further divided into the following packages:
-
execution
- examples demonstrating the execution of a job on a remote job execution service (GT v2.4.3,
GT v3.0.2, GT v3.2.0, GT v3.2.1, GT v4.0.0, Condor, and SSH).
-
transfer
- examples demonstrating the transfer of files and directories between two file servers (GridFTP,
FTP, and WebDAV).
-
file
- examples demonstrating the operations on files hosted on remote file servers (GridFTP, FTP, and
WebDAV).
-
taskgraph
- examples demonstrating the execution of hierarchical task graphs and control dependencies
between Grid tasks.
-
queue and set
- examples demonstrating the execution of hierarchical queues and sets of tasks respectively.
-
xml
- examples demonstrating the ability to checkpoint partially executed task graphs to an xml document
and construct task graphs from checkpointed xml documents.
After successfully compiling the Java CoG Kit, these examples can be executed from the launcher scripts available
in cog/dist/cog-<version>/bin/examples directory.
5 Design
One of the most elementary usage pattern in Grid computing is the execution of a Grid task (job submission, file
transfer, file operation, or information query). An extension to this basic Grid pattern is a Grid workflow pattern
that enables the user to submit a set of Grid tasks along with an execution dependency. Therefore, the initial design
of cog-abstractions concentrates on providing the elements required to support these important usage patterns.
Other Grid patterns can be supported by extending the flexible cog-abstractions design based on community
feedback.
Figure 1 shows the class diagram of cog-abstractions. A detailed listing of the attributes and functions for each class
has been omitted for simplicity. In the rest of this section we describe the important entities listed in Figure 1 and
outline their semantics as a part of the offered Grid functionality.
5.1 ExecutableObject
An ExecutableObject provides a high-level abstraction for artifacts that can be executed on the Grid. It can be
specialized as a Grid Task or a TaskGraph. An ExecutableObject in the Java CoG Kit has a unique identity, name,
and an execution status.
public interface ExecutableObject {
public static final int TASK = 1;
public static final int TASKGRAPH = 2;
public int getObjectType();
public void setName(String name);
public String getName();
public void setIdentity(Identity id);
public Identity getIdentity();
public void setStatus(Status status);
public void setStatus(int status);
public Status getStatus();
public void addStatusListener(StatusListener listener);
public void removeStatusListener(StatusListener listener);
}
5.2 Task
A Task is an atomic unit of execution in cog-abstractions. It represents a generic Grid functionality including
remote job execution, file transfer request, file operation, or information query. It has a unique identity, name,
execution status, specification, and set of services (for remote execution).
The task identity helps in uniquely representing the task across the Grid. The task specification represents the
actual attributes or parameters required for the execution of the Grid-centric task. The generalized specification can
be extended for common Grid tasks such as remote job execution, file transfer, and information query. A Grid task
also contains a set of Grid services that enable the remote execution of the task. For example, a job submission
task contains a remote job execution service that will ultimately enable the execution of the task.
Likewise, the file transfer task contains a source file server and a destination file server as its supporting
services.
A Grid task contains the abstract elements required for any Grid functionality. However, the actual
execution of a Grid task requires a specific abstract-to-protocol mapping that translates all the abstract
components into backend protocol-specific entities. This translation is done by the Handlers (see 5.7). A
task of a given type (execution, file transfer, or file operation) is submitted to an appropriate task
handler (execution task handler, file transfer task handler, or a file operation task handler respectively).
Based on the provider attribute of the task, the handler provides the appropriate abstract-to-protocol
transformation.
public interface Task extends ExecutableObject {
public static final int JOB˘SUBMISSION = 1;
public static final int FILE˘TRANSFER = 2;
public static final int INFORMATION˘QUERY = 3;
public static final int FILE˘OPERATION = 4;
public void setType(int type);
public int getType();
public void setProvider(String provider);
public String getProvider();
public void setService(int index, Service service);
public void addService(Service service);
public Service removeService(int index);
public Collection removeAllServices();
public void removeService(Collection collection);
public Service getService(int index);
public Collection getAllServices();
public void setRequiredService(int value);
public int getRequiredServices();
public void setSpecification(Specification specification);
public Specification getSpecification();
public void setStdOutput(String output);
public String getStdOutput();
public void setStdError(String error);
public String getStdError();
public void setAttribute(String name, Object value);
public Object getAttribute(String name);
public Enumeration getAllAttributes();
public void addOutputListener(OutputListener listener);
public void removeOutputListener(OutputListener listener);
public void toXML(File file) throws MarshalException;
public String toString();
public boolean isUnsubmitted();
public boolean isActive();
public boolean isCompleted();
public boolean isSuspended();
public boolean isFailed();
public boolean isCanceled();
public Calendar getSubmittedTime();
public Calendar getCompletedTime();
}
5.3 Specification
Every Grid Task has an associated Specification that dictates the objective of the task and the environment required
to achieve the objective. The TaskHandler manages the tasks based on the parameters specified in the task
specification.
public interface Specification {
public static final int JOB˘SUBMISSION = 1;
public static final int FILE˘TRANSFER = 2;
public static final int INFORMATION˘QUERY = 3;
public void setType(int type);
public int getType();
public void setSpecification(String specification);
public String getSpecification();
}
A task specification is a generalized concept and can be further extended as JobSpecification, FileSpecification, and
InformationSpecification .
We note that the specific parameters required in a task specification depend on the underlying Grid implementation
used for the execution of the Task. For example, GT4 has several required parameters that are not supported by
GT2 (and vice versa). However, the specification classes in cog-abstractions offer some commonly used
attributes that can be extended or omitted based on the requirements of the task and specific Grid
implementation.
The JobSpecification mentions the common parameters needed for the remote job execution independent of the
low-level implementation. Implementation-specific parameters can be added to the specification as additional
attributes.
public interface JobSpecification extends Specification {
public void setExecutable(String executable);
public String getExecutable();
public void setDirectory(String directory);
public String getDirectory();
public String setArgument(String argument);
public String setArgument(Vector argument);
public String getArgument(int index);
public String getArgumentsAsString();
public Vector getArgumentsAsVector();
public void addArgument(String argument);
public void addArgument(int index, String argument);
public removeArgument(int index);
public removeArgument(String argument);
public void setStdOutput(String output);
public String getStdOutput();
public void setStdInput(String input);
public String getStdInput();
public void setStdError(String error);
public String getStdError();
public void setBatchJob(boolean bool);
public boolean isBatchJob();
public void setRedirected(boolean bool);
public boolean isRedirected();
public void setLocalExecutable(boolean bool);
public boolean isLocalExecutable();
public void setLocalInput(boolean bool);
public boolean isLocalInput();
public void setAttribute(String name, Object value);
public Object getAttribute(String name);
public Enumeration getAllAttributes();
}
The FileTransferSpecification provides the commonly used attributes for file transfers between Grid resources. We
note once again that not all attributes are supported by every Grid implementation.
public interface FileTransferSpecification extends Specification {
public void setSourceDirectory(String directory);
public String getSourceDirectory();
public void setDestinationDirectory(String directory);
public String getDestinationDirectory();
public void setSourceFile(String file);
public String getSourceFile();
public void setDestinationFile(String file);
public String getDestinationFile();
public void setSource(String source);
public String getSource();
public void setDestination(String destination);
public String getDestination();
public void setThirdParty(boolean bool);
public boolean isThirdParty();
public void setAttribute(String name, Object value);
public Object getAttribute(String name);
public Enumeration getAllAttributes();
}
The FileOperationSpecification offers the functionality to invoke important operations on files hosted on remote Grid
resources.
A list of all the supported operations and their corresponding arguments are presented in table 1.
| Table 1: | Valid command names for FileOperationSpecifications. |
|
|
|
| Operation | Argument 0 | Argument 1 | Usage |
|
|
|
| start | | | Initializes the connection to the file
server |
|
|
|
| stop | | | Terminates the connection to the file
server |
|
|
|
| pwd | | | Returns the
current working directory of the file
server as a String |
|
|
|
| cd | String:
directoryName | | Sets the working directory of the file
server |
|
|
|
| ls | | | Returns all files in the current
directory of the file server as a
Collection of GridFiles. |
|
|
|
| ls | String:
directoryName | | Returns all files in the specified
directory of the file server as a
Collection of GridFiles |
|
|
|
| mkdir | String:
directoryName | | Creates a directory on the file server
with the specified name |
|
|
|
| rmdir | String:
directoryName | | Deletes the given directory on the
file server, only if it is empty. |
|
|
|
| rmdir | String:
directoryName | boolean:
force | Deletes the specified directory on
the file server either if it is empty or
if force==true |
|
|
|
| rmfile | String:
fileName | | Deletes the given file from the file
server |
|
|
|
| exists | String:
fileName | | Returns a Boolean specifying if the
file exists on the file server |
|
|
|
| isDirectory | String:
directoryName | | Returns a Boolean specifying if
the given directoryName is a valid
directory on the file server |
|
|
|
| getfile | String:
remoteFilename | String:
localFileName | Transfers the remote file on the file
server to the local file on he client
machine |
|
|
|
| putfile | String:
localFilename | String:
remoteFileName | Transfers the local file on the client
machine to the remote file on the file
server |
|
|
|
| getdir | String:
remoteDirectoryName | String:
localDirectoryName | Transfers the remote directory on
the file server to the local directory
on the client machine |
|
|
|
| putdir | String:
localDirectoryName | String:
remoteDirectoryName | Transfers the local directory on
the client machine to the remote
directory on the file server |
|
|
|
| rename | String:
oldFileName | String
newFileName | Change the name of the old name of
the file to the given new name |
|
|
|
| chmod | String:
fileName | Integer:
mode | Changes permissions of file on the
file server; the mode argument is as
per the Unix chmod command. |
|
|
|
| | |
|
public interface FileOperationSpecification extends Specification {
public static String START = __start'';
public static String STOP = __stop'';
public static String PWD = __pwd'';
public static String CD = __cd'';
public static String LS = __ls'';
public static String MKDIR = __mkdir'';
public static String RMDIR = __rmdir'';
public static String RMFILE = __rmfile'';
public static String GETFILE = __getfile'';
public static String PUTFILE = __putfile'';
public static String GETDIR = __getdir'';
public static String PUTDIR = __putfile'';
public static String MGET = __mget'';
public static String MPUT = __mput'';
public static String RENAME = __rename'';
public static String CHMOD = __chmod'';
public static String EXISTS = __exists'';
public static String ISDIRECTORY = __isDirectory'';
public void setOperation(String operation);
public String getOperation();
public void setArgument(String arguments, int index);
public int addArgument(String argument);
public Collection getArguments();
public String getArgument(int n);
public int getArgumentSize();
public void setAttribute(String name, Object value);
public Object getAttribute(String name);
public Enumeration getAllAttributes();
}
5.4 Service
Every Grid Task has a set of remote Services that support the actual execution of the task. The service interface is a
local representation of the remote Grid service. Every service has a provider attribute that specifies the technology
and provider supported by that service. It also has a service contact and a security context specific to that
provider.
public interface Service {
public static final int JOB˘SUBMISSION = 1;
public static final int FILE˘TRANSFER = 2;
public static final int INFORMATION˘QUERY = 3;
public static final int FILE˘OPERATION = 4;
public static final int JOB˘SUBMISSION˘SERVICE = 0;
public static final int DEFAULT˘SERVICE = 0;
public static final int FILE˘TRANSFER˘SOURCE˘SERVICE = 0;
public static final int FILE˘TRANSFER˘DESTINATION˘SERVICE = 1;
public void setIdentity(Identity identity);
public Identity getIdentity();
public void setName(String name);
public String getName();
public void setProvider(String provider);
public String getProvider();
public void setType(int type);
public int getType();
public void setServiceContact(ServiceContact serviceContact);
public ServiceContact getServiceContact();
public void setSecurityContext(SecurityContext securityContext);
public SecurityContext getSecurityContext();
public void setAttribute(String name, Object value);
public Object getAttribute(String name);
public Enumeration getAllAttributes();
}
5.5 TaskGraph
A TaskGraph provides a building block for expressing complex dependencies between tasks. Advanced applications
require mechanisms to execute client-side workflows that process the tasks based on user-defined control
dependencies. Hence, the data structure representing the TaskGraph aggregates a set of ExecutableObjects (Tasks
and TaskGraphs) and allows the user to define dependencies between these tasks. In graph theoretical terms, a
TaskGraph provides the elements to express workflows as a hierarchical directed acyclic graph (see Figure 2). A
TaskGraph can theoretically contain infinite levels of hierarchy. However, practically it is constrained with the
availability of resources (memory) on a particular system.
public interface TaskGraph extends ExecutableObject {
public void add(ExecutableObject graphNode) throws Exception;
public ExecutableObject remove(Identity id) throws Exception;
public ExecutableObject get(Identity id);
public ExecutableObject[] toArray();
public Enumeration elements();
public void setDependency(Dependency dependency);
public Dependency getDependency();
public void addDependency(Identity from, Identity to);
public boolean removeDependency(Identity from, Identity to);
public void setAttribute(String name, Object value);
public Object getAttribute(String name);
public Enumeration getAllAttributes();
public int getSize();
public boolean isEmpty();
public boolean contains(Identity id);
public int getUnsubmittedCount();
public int getSubmittedCount();
public int getActiveCount();
public int getCompletedCount();
public int getSuspendedCount();
public int getResumedCount();
public int getFailedCount();
public int getCanceledCount();
public void toXML(File file) throws MarshalException;
public Calendar getSubmittedTime();
public Calendar getCompletedTime();
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
}
Cog-abstractions provides two additional utility classes that specialize the functionality of the TaskGraph. The Set
is a special type of TaskGraph with no dependencies. Intuitively, it represents a bag of tasks that can be executed in
parallel. The Queue is another specialized TaskGraph that represents a first-in-first-out (FIFO) queue. The
dependencies in a Queue are not set explicitly but are maintained implicitly based on the addition of a Task to the
Queue.
5.6 Status
Every ExecutableObject (Task or TaskGraph) has an associated execution status. An ExecutableObject
can be in one of the following status: unsubmitted, submitted, active, suspended, resumed, failed,
canceled, and completed. We note that not every status is supported by every Grid implementation. In
other words, for some Grid implementations it may not be possible to suspend and resume remote
execution.
It is easy to associate a simple Task with one of the above mentioned status. For example, initially the task is
unsubmitted; its status changes to submitted when it is handled by a handler; its status changes to active when it is
being executed remotely; and so on. However, it is not apparent how a TaskGraph is mapped to one the
supported status. Cog-abstractions uses the following logic to map a TaskGraph to its appropriate
status.
public interface Status {
public static final int UNSUBMITTED = 0;
public static final int SUBMITTED = 1;
public static final int ACTIVE = 2;
public static final int SUSPENDED = 3;
public static final int RESUMED = 4;
public static final int FAILED = 5;
public static final int CANCELED = 6;
public static final int COMPLETED = 7;
public static final int UNKNOWN = 9999;
public abstract void setStatusCode(int status);
public abstract int getStatusCode();
public abstract void setPrevStatusCode(int status);
public abstract int getPrevStatusCode();
public abstract void setException(Exception exception);
public abstract Exception getException();
public abstract void setMessage(String message);
public abstract String getMessage();
public void setTime(Calendar time);
public Calendar getTime();
}
5.7 Handlers
Cog-abstractions contains the TaskHandler and the TaskGraphHandler, to process a Task and a TaskGraph
respectively. Once a Task or a TaskGraph is submitted to the appropriate handler, the handler interacts with the
desired Grid implementation and accomplishes the necessary tasks. The handlers in cog-abstractions can be viewed
as adaptors that translate the abstract definitions of a Task and TaskGraph into implementation-specific constructs
understood by the backend Grid services. For example, a GT3 execution TaskHandler will extract the appropriate
attributes from the execution Task and make the necessary calls to the remote Grid service factory, retrieve the Grid
service handle, and interact with the newly created service instance. Symmetric translations would be
done for other Grid implementations. Intuitively, a handler is specific to the backed implementation
and is the only part of cog-abstractions that needs to be extended for supporting additional Grid
implementations.
public interface TaskHandler {
public void setType(int type);
public int getType();
public void submit(Task task)
throws
IllegalSpecException,
InvalidSecurityContextException,
InvalidServiceContactException,
TaskSubmissionException;
public void suspend(Task task)
throws InvalidSecurityContextException,
TaskSubmissionException;
public void resume(Task task)
throws InvalidSecurityContextException,
TaskSubmissionException;
public void cancel(Task task)
throws InvalidSecurityContextException,
TaskSubmissionException;
public void remove(Task task)
throws ActiveTaskException;
public Task[] getAllTasks();
public Collection getActiveTasks();
public Collection getFailedTasks();
public Collection getCompletedTasks();
public Collection getSuspendedTasks();
public Collection getResumedTasks();
public Collection getCanceledTasks();
}
The TaskGraphHandler provides a similar functionality as the task handler interface. However, it has an additional
responsibility of enforcing the dependency on the graph-like task sets submitted to it. It can be implemented as an
advanced workflow engine coordinating the execution of tasks on corresponding Grid resources honoring the
user-defined dependencies.
public interface TaskGraphHandler {
public void submit(TaskGraph taskgraph)
throws
IllegalSpecException,
InvalidSecurityContextException,
InvalidServiceContactException,
TaskSubmissionException;
public void suspend()
throws InvalidSecurityContextException,
TaskSubmissionException;
public void resume()
throws InvalidSecurityContextException,
TaskSubmissionException;
public void cancel()
throws InvalidSecurityContextException,
TaskSubmissionException;
public Task[] getAllTask();
public Collection getActiveTasks();
public Collection getFailedTasks();
public Collection getCompletedTasks();
public Collection getSuspendedTasks();
public Collection getResumedTasks();
public Collection getCanceledTasks();
}
5.8 FileResource
An alternate model of abstraction for file operations, bypassing the task model, is also available for applications that
desire direct interactions with the file hosting Grid servers. A FileResource provides all the necessary functionality
to directly invoke remote file operations. Methods of a FileResource bear close correspondence with the commands
outlined in Table 1.
public interface FileResource{
public static final String FTP = __ftp'';
public static final String GridFTP = __gridftp'';
public static final String WebDAV = __webdav'';
public static final String Local = __local'';
public String getProtocol();
public void setServiceContact(ServiceContact serviceContact);
public ServiceContact getServiceContact();
public void setSecurityContext(SecurityContext securityContext);
public SecurityContext getSecurityContext();
public void start() throws IllegalHostException,
InvalidSecurityContextException, GeneralException;
public void stop() throws GeneralException;
public boolean isStarted();
public void setCurrentDirectory(String directoryName)
throws DirectoryNotFoundException, GeneralException;
public String getCurrentDirectory() throws GeneralException;
public Collection list() throws GeneralException;
public Collection list(String directoryName)
throws DirectoryNotFoundException, GeneralException;
public void createDirectory(String directoryName) throws GeneralException;
public void deleteDirectory(String directoryName, boolean force)
throws DirectoryNotFoundException, GeneralException;
public void deleteFile(String fileName)
throws FileNotFoundException, GeneralException;
public void getFile(String remoteFileName, String localFileName)
throws FileNotFoundException, GeneralException;
public void putFile(String localFileName, String remoteFileName)
throws FileNotFoundException, GeneralException;
public void getDirectory(String remoteDirectoryName, String localDirectoryName)
throws DirectoryNotFoundException, GeneralException;
public void putDirectory(String localDirectoryName, String remoteDirectoryName)
throws DirectoryNotFoundException, GeneralException;
public void getMultipleFiles(String[] remoteFileNames, String[] localFileNames)
throws FileNotFoundException, GeneralException;
public void getMultipleFiles(String[] remoteFileNames, String localDirectoryName)
throws FileNotFoundException, DirectoryNotFoundException,
GeneralException;
public void putMultipleFiles(String[] localFileNames, String[] remoteFileNames)
throws FileNotFoundException, GeneralException;
public void putMultipleFiles(String[] localFileNames, String remoteDirectoryName)
throws FileNotFoundException, DirectoryNotFoundException,
GeneralException;
public void rename(String oldFileName, String newFileName)
throws FileNotFoundException, GeneralException;
public void changeMode(String fileName, int mode)
throws FileNotFoundException, GeneralException;
public void changeMode(GridFile gridFile)
throws FileNotFoundException, GeneralException;
public GridFile getGridFile(String fileName)
throws FileNotFoundException, GeneralException;
public boolean exists(String fileName)
throws FileNotFoundException, GeneralException;
public boolean isDirectory(String directoryName)
throws GeneralException;
public void submit(ExecutableObject commandWorkflow)
throws IllegalSpecException, TaskSubmissionException;
public void setAttribute(String name, Object value);
public Enumeration getAllAttributes();
public Object getAttribute(String name);
}
5.9 GridFile
A GridFile is an abstract representation of a remote file or directory. It represents the basic properties
of a file such as size, name, modification date, access permissions etc. This abstraction is a passive
information carrier and cannot be used to modify the properties or contents of a remote resource directly.
It can be used as an input to the file resource abstraction to change access permissions of a remote
resource.
public interface GridFile {
public static final byte UNKNOWN˘TYPE = 0;
public static final byte FILE˘TYPE = 1;
public static final byte DIRECTORY˘TYPE = 2;
public static final byte SOFTLINK˘TYPE = 3;
public static final byte DEVICE˘TYPE = 4;
public void setSize(long size);
public long getSize();
public void setName(String name);
public String getName();
public void setAbsolutePathName(String name);
public String getAbsolutePathName();
public void setLastModified(String date);
public String getLastModified();
public void setFileType(byte type);
public byte getFileType();
public boolean isFile();
public boolean isDirectory();
public boolean isSoftLink();
public boolean isDevice();
public void setMode(String mode);
public String getMode();
public void setUserPermissions(Permissions userPermissions);
public Permissions getUserPermissions();
public void setGroupPermissions(Permissions groupPermissions);
public Permissions getGroupPermissions();
public void setAllPermissions(Permissions allPermissions);
public Permissions getAllPermissions();
public boolean userCanRead();
public boolean userCanWrite();
public boolean userCanExecute();
public boolean groupCanRead();
public boolean groupCanWrite();
public boolean groupCanExecute();
public boolean allCanRead();
public boolean allCanWrite();
public boolean allCanExecute();
}
5.10 Permissions
The permissions interface provides a means to get and set permissions for a class of users along with GridFile and
FileResource abstractions.
public interface Permissions{
public void setRead(boolean canRead);
public boolean getRead();
public void setWrite(boolean canWrite);
public boolean getWrite();
public void setExecute(boolean canExecute);
public boolean getExecute();
public String toString();
}
6 Programmer’s Guide
- How to execute a remote job execution task (6.1)
- How to execute a file transfer task (6.2)
- How to execute a file operation task (6.3)
- How to execute a simple task graph (DAG) (6.4)
- How to execute a hierarchical task graph (6.5)
- How to checkpoint a task (6.6)
- How to execute a checkpointed task (6.7)
- How to checkpoint a task graph (6.8)
- How to resume a checkpointed task graph (6.9)
- How to invoke remote file operations without adhering to the task model (6.10)
- How to run a native Condor job with the CoG Kit abstractions (6.11)
- How to integrate a new provider module in the Java CoG Kit(6.12)
6.1 How to execute a remote job execution task
Executing a remote job becomes extremely simple with cog-abstractions. To begin with, create a Task with the
appropriate attributes.
Task task = new TaskImpl(__myTestTask'', Task.JOB˘SUBMISSION);
/⋆ Set the desired provider. Default options are
GT2, GT3.0.2, GT3.2.0, GT3.2.1, GT4.0.0, Condor, or SSH
⋆/
task.setProvider(__GT4.0.0'');
Then, create a JobSpecification for the task and set the appropriate attributes as per the task requirements.
JobSpecification spec = new JobSpecificationImpl();
/⋆ Set the location and name of the executable.
If the executable is a local executable, then
spec.setLocalExecutable(true)
⋆/
spec.setExecutable(__/bin/ls'');
/⋆ Set the arguments (if any)
for the executable
⋆/
spec.addArguments(__-l'');
spec.addArguments(__-a'');
/⋆ Set the name of the file which serves
as the input to the executable
If the input file needs to be redirected
from the local machine, then
spec.setLocalInput(true)
⋆/
spec.setStdInput(__abstractions-testInput'');
/⋆ Set the name of the file to which the remote
output must be stored in.
If the remote output needs to be redirected
to the local machine, then
spec.setRedirected(true)
If the remote output needs to be manipulated at
the local machine rather than storing it in a
file, then
spec.setRedirected(true);
spec.setStdOutput(null);
The output is now available from
task.getOutput(); and can be used
or displayed as desired.
⋆/
spec.setStdOutput(__abstractions-testOutput'');
/⋆ Set the execution mode of the job ⋆/
spec.setBatchJob(true);
/⋆ Add additional attributes that are not
provided by default. These add on
attributes will be considered by the
handler only if it supports it.
⋆/
spec.setAttribute(__count'',__546'');
/⋆ Assign this specification to the task ⋆/
task.setSpecification(spec);
Next, assign an appropriate service to the task with a provider, service contact, and security context.
This step assumes you have a valid user certificate successfully obtained from appropriate certificate
authority.
Service service = new ServiceImpl(Service.JOB˘SUBMISSION);
/⋆ Assign a provider to this service.
The provider assigned to the service
must be the same as that assigned to the task.
⋆/
service.setProvider(__GT4.0.0'');
/⋆ Retrieve the appropriate security context
for this provider from the AbstractionFactory class
⋆/
SecurityContext securityContext =
AbstractionFactory.newSecurityContext(__GT4.0.0'');
/⋆ Assign the default credentials
available as a valid proxy certificate
whose location is specified in the
cog.properties file present in the
HOME/.globus directory
To assign non-default credentials
create a GSSCredential and pass
this GSSCredential as the argument
instead of null
⋆/
securityContext.setCredentials(null);
/⋆ Assign this security credential to the service ⋆/
service.setSecurityContext(securityContext);
/⋆ Create a new service contact with the
appropriate service endpoint address
⋆/
ServiceContact serviceContact =
new ServiceContactImpl(
__https://127.0.0.1:8443/wsrf/services/ManagedJobFactoryService'');
/⋆ Assign this service contact with the service ⋆/
service.setServiceContact(serviceContact);
/⋆ Assign the service to the task ⋆/
task.setService(Service.JOB˘SUBMISSION˘SERVICE, service);
Next, create a TaskHandler and submit the task for execution.
try {
handler.submit(task);
} catch (InvalidSecurityContextException ise) {
logger.error(__Security Exception'', ise);
System.exit(1);
} catch (TaskSubmissionException tse) {
logger.error(__TaskSubmission Exception'', tse);
System.exit(1);
} catch (IllegalSpecException ispe) {
logger.error(__Specification Exception'', ispe);
System.exit(1);
} catch (InvalidServiceContactException isce) {
logger.error(__Service Contact Exception'', isce);
System.exit(1);
}
If it is required to monitor the status of the task (desired in most interactive tasks), then the monitoring class must
implement the StatusListener interface and before submitting the task to a handler subscribe to the task for its
status changes.
task.addStatusListener(this);
If registered to listen to the status notification of the task, implement the statusChanged() function.
public void statusChanged(StatusEvent event)
{
Status status = event.getStatus();
logger.debug(__Status changed to ''
+ status.getStatusString());
if (status.getStatusCode() == Status.COMPLETED) {
/⋆ Makes sense if
spec.setRedirected(true);
spec.setStdOutput(null);
⋆/
logger.debug(__Output = ''
+ task.getStdOutput());
System.exit(1);
}
}
6.2 How to execute a file transfer task
Executing a file transfer is extremely simple with cog-abstractions. To begin with, create a Task with the
appropriate attributes.
Task task = new TaskImpl(__myTestTask'', Task.FILE˘TRANSFER);
/⋆ Since a file transfer task has two providers:
the source provider and the destination provider,
we do not set the provider attribute of the task.
⋆/
Then, create a FileTransferSpecification for the task and set the appropriate attributes as per the task
requirements.
FileTransferSpecification spec = new FileTransferSpecificationImpl();
/⋆ Set the source and destination files ⋆/
spec.setSourceDirectory(__/home/username'');
spec.setSourceFile(__sourceFile'');
spec.setDestinationDirectory(__/home/username'');
spec.setDestinationFile(__destinationFile'');
/⋆ Assign this specification to the task ⋆/
task.setSpecification(spec);
Next, assign the appropriate source and destination services service to the task.
Service sourceService = new ServiceImpl(Service.FILE˘TRANSFER);
/⋆ Assign a provider to this service.
⋆/
sourceService.setProvider(__GridFTP'');
/⋆ Retrieve the appropriate security context
for this provider from the AbstractionFactory class
⋆/
SecurityContext sourceSecurityContext =
AbstractionFactory.newSecurityContext(__GridFTP'');
/⋆ Assign the default credentials
available as a valid proxy certificate
whose location is specified in the
cog.properties file present in the
HOME/.globus directory
To assign non-default credentials
create a GSSCredential and pass
this GSSCredential as the argument
instead of null
⋆/
sourceSecurityContext.setCredentials(null);
/⋆ Assign this security credential to the source service ⋆/
sourceService.setSecurityContext(sourceSecurityContext);
/⋆ Create a new service contact with the
appropriate service endpoint address
⋆/
ServiceContact sourceServiceContact =
new ServiceContactImpl();
sourceServiceContact.setHost(__hot.anl.gov'');
sourceServiceContact.setPort(2811);
/⋆ Assign this service contact with the service ⋆/
sourceService.setServiceContact(sourceServiceContact);
/⋆ Assign the service to the task ⋆/
task.setService(Service.SOURCE˘FILE˘TRANSFER˘SERVICE, sourceService);
/⋆ Create a destination file transfer service ⋆/
Service destinationService = new ServiceImpl(Service.FILE˘TRANSFER);
/⋆ Assign a provider to this service.
The provider assigned to the service
must be the same as that assigned to the task.
⋆/
destinationService.setProvider(__GridFTP'');
/⋆ Retrieve the appropriate security context
for this provider from the AbstractionFactory class
⋆/
SecurityContext destinationSecurityContext =
AbstractionFactory.newSecurityContext(__GridFTP'');
/⋆ Assign the default credentials
available as a valid proxy certificate
whose location is specified in the
cog.properties file present in the
HOME/.globus directory
To assign non-default credentials
create a GSSCredential and pass
this GSSCredential as the argument
instead of null
⋆/
destinationSecurityContext.setCredentials(null);
/⋆ Assign this security credential to the destination service ⋆/
destinationService.setSecurityContext(destinationSecurityContext);
/⋆ Create a new service contact with the
appropriate service endpoint address
⋆/
ServiceContact destinationServiceContact =
new ServiceContactImpl();
destinationServiceContact.setHost(__cold.anl.gov'');
destinationServiceContact.setPort(2811);
/⋆ Assign this service contact with the service ⋆/
destinationService.setServiceContact(destinationServiceContact);
/⋆ Assign the service to the task ⋆/
task.setService(Service.DESTINATION˘FILE˘TRANSFER˘SERVICE, destinationService);
Next, create a TaskHandler and submit the task for execution.
try {
handler.submit(task);
} catch (InvalidSecurityContextException ise) {
logger.error(__Security Exception'', ise);
System.exit(1);
} catch (TaskSubmissionException tse) {
logger.error(__TaskSubmission Exception'', tse);
System.exit(1);
} catch (IllegalSpecException ispe) {
logger.error(__Specification Exception'', ispe);
System.exit(1);
} catch (InvalidServiceContactException isce) {
logger.error(__Service Contact Exception'', isce);
System.exit(1);
}
If it is required to monitor the status of the task (desired in most interactive tasks), then the monitoring class must
implement the StatusListener interface and before submitting the task to a handler subscribe to the task for its
status changes.
task.addStatusListener(this);
If registered to listen to the status notification of the task, implement the statusChanged() function.
public void statusChanged(StatusEvent event) {
Status status = event.getStatus();
logger.debug(__Status changed to ''
+ status.getStatusString());
if (status.getStatusCode() == Status.COMPLETED }}
status.getStatusCode() == Status.FAILED) {
logger.info(__Task Done'');
System.exit(1);
}
}
6.3 How to execute a file operation task
Execution of file operation tasks work slightly differently compared to other tasks. Execution and file transfer tasks
are submitted independently of other tasks, thereby displaying a connectionless behavior between the client machine
and the remote server. On the other hand, file operation tasks are dependent on each other showing a
connection-oriented behavior between the client machine and the remote server. For example, lets assume the client
executes a file operation task to “start” a remote connection. The client then executes a task to “list” all
the files in the current directory. It can be seen that the two task are not independent, and that the
execution of the second task must be done in the context of the connection established in the first
task.
Therefore, to execute connection-oriented file operation tasks, we adopt a notion of “sessionID”. To begin with, we
create a Task with appropriate attributes.
Task task = new TaskImpl(__myFirstTask'', Task.FILE˘OPERATION);
/⋆ Set the desired provider. Default options are
GridFTP, FTP, or WebDAV
⋆/
task.setProvider(__gridftp'');
Then, create a FileOperationSpecification for the task and set the appropriate attributes as per the task
requirements.
FileOperationSpecification spec = new FileOperationSpecificationImpl();
/⋆ Set the operation and the corresponding arguments.
In our example, the operation is __start'' since we want to
establish a new connection with the file server. We note that
__start'' is ALWAYS the first operation to be executed in any
sequence of related file operations.
⋆/
spec.setOperation(FileOperationSpecification.START);
/⋆ The __start'' operation has no arguments ⋆/
/⋆ Assign this specification to the task ⋆/
task.setSpecification(spec);
Next, assign an appropriate service to the task with a provider, service contact, and security context.
Service service = new ServiceImpl(Service.FILE˘OPERATION);
/⋆ Assign a provider to this service.
The provider assigned to the service
must be the same as that assigned to the task.
⋆/
service.setProvider(__gridftp'');
/⋆ Retrieve the appropriate security context
for this provider from the AbstractionFactory class
⋆/
SecurityContext securityContext =
AbstractionFactory.newSecurityContext(__gridftp'');
/⋆ Assign the default credentials
available as a valid proxy certificate
whose location is specified in the
cog.properties file present in the
HOME/.globus directory
To assign non-default credentials
create a GSSCredential and pass
this GSSCredential as the argument
instead of null
⋆/
securityContext.setCredentials(null);
/⋆ Assign this security credential to the service ⋆/
service.setSecurityContext(securityContext);
/⋆ Create a new service contact with the
appropriate service endpoint address
⋆/
ServiceContact serviceContact =
new ServiceContactImpl(__hot.anl.gov:2119'');
/⋆ Assign this service contact with the service ⋆/
service.setServiceContact(serviceContact);
/⋆ Assign the service to the task ⋆/
task.setService(Service.FILE˘OPERATION˘SERVICE, service);
Next, create a TaskHandler and submit the task for execution.
try {
handler.submit(task);
} catch (InvalidSecurityContextException ise) {
logger.error(__Security Exception'', ise);
System.exit(1);
} catch (TaskSubmissionException tse) {
logger.error(__TaskSubmission Exception'', tse);
System.exit(1);
} catch (IllegalSpecException ispe) {
logger.error(__Specification Exception'', ispe);
System.exit(1);
} catch (InvalidServiceContactException isce) {
logger.error(__Service Contact Exception'', isce);
System.exit(1);
}
Since file operation tasks are always interactive tasks, we monitor the status of the task. The monitoring class must
implement the StatusListener interface and before submitting the task to a handler subscribe to the task for its
status changes.
task.addStatusListener(this);
The monitoring class listen to the status notification of the task, by implementing the statusChanged()
method.
public void statusChanged(StatusEvent event)
{
Status status = event.getStatus();
logger.debug(__Status changed to ''
+ status.getStatusString());
if (status.getStatusCode() == Status.COMPLETED) {
/⋆ The output of the __start'' operation is
a sessionID. This sessionID can be used
for all successive file operation tasks
to invoke operations with context to this
newly established connection.
⋆/
logger.debug(__SessionID = ''
+ task.getAttribute(__output''));
}
}
We note that rather than extracting the output from task.getStdOutput() (which returns a String), we retrieve the
output as task.getAttribute(“output”) (which returns an Object). The output Object can then be type cast to the
target class as specified in Table 1.
Once we have obtained the connection sessionID, we can submit any file operation specified in Table 1.
For example, lets execute the “list directoryName” operation. We create a Task with appropriate
attributes.
Task task = new TaskImpl(__mySecondTask'', Task.FILE˘OPERATION);
/⋆ Set the desired provider. Default options are
GridFTP, FTP, or WebDAV
⋆/
task.setProvider(__gridftp'');
Then, create a FileOperationSpecification for the task and set the appropriate attributes as per the task
requirements.
FileOperationSpecification spec = new FileOperationSpecificationImpl();
/⋆ Set the operation and the corresponding arguments.
In our example, the operation is __list directoryName''.
⋆/
spec.setOperation(FileOperationSpecification.LS);
/⋆ We then set the arguments for this operations ⋆/
spec.addArgument(__/home/amin/test'');
/⋆ Assign this specification to the task ⋆/
task.setSpecification(spec);
Since, we have already retrieved a sessionID for this connection, we do not need to create a new Service for this task.
Instead, we simply specify the sessionID.
executing the __start'' operation. We note here the
importance of the initial __start'' operation. Without
that operation, we will not get any sessionID.
⋆/
task.setAttribute(__sessionID'', sessionID);
Next, create a TaskHandler and submit the task for execution.
try {
handler.submit(task);
} catch (InvalidSecurityContextException ise) {
logger.error(__Security Exception'', ise);
System.exit(1);
} catch (TaskSubmissionException tse) {
logger.error(__TaskSubmission Exception'', tse);
System.exit(1);
} catch (IllegalSpecException ispe) {
logger.error(__Specification Exception'', ispe);
System.exit(1);
} catch (InvalidServiceContactException isce) {
logger.error(__Service Contact Exception'', isce);
System.exit(1);
}
Once again we monitor the status of the task. The monitoring class must implement the StatusListener interface
and before submitting the task to a handler subscribe to the task for its status changes.
task.addStatusListener(this);
The monitoring class listen to the status notification of the task, by implementing the statusChanged()
method.
public void statusChanged(StatusEvent event)
{
Status status = event.getStatus();
logger.debug(__Status changed to ''
+ status.getStatusString());
if (status.getStatusCode() == Status.COMPLETED) {
/⋆ The output of the __list'' operation is
a Collection of GridFile objects. This Collection is
manipulated as desired.
⋆/
}
}
Table 1 lists all valid operations, their input arguments, and their corresponding outputs.
6.4 How to execute a simple task graph (DAG)
To create a TaskGraph, we assume that we have created three tasks: task1, task2, and task3. Instructions for
creating job submission and file transfer tasks are available in Sections 6.1 and 6.2 respectively. We then create a
TaskGraph and add a dependency between these tasks.
/⋆ Give a convenient name to the TaskGraph ⋆/
tg.setName(__testGraph'');
/⋆ Add the tasks to the TaskGraph ⋆/
tg.add(task1);
tg.add(task2);
tg.add(task3);
/⋆ Add dependencies between these tasks.
Dependency is added as
task1 --> task2 --> task3.
This implies task1 is executed before task2
and task2 is executed before task3.
⋆/
tg.addDependency(task1,task2);
tg.addDependency(task2,task3);
Next, create a TaskGraphHandler and submit the task for execution.
try {
handler.submit(tg);
} catch (InvalidSecurityContextException ise) {
logger.error(__Security Exception'', ise);
System.exit(1);
} catch (TaskSubmissionException tse) {
logger.error(__TaskSubmission Exception'', tse);
System.exit(1);
} catch (IllegalSpecException ispe) {
logger.error(__Specification Exception'', ispe);
System.exit(1);
} catch (InvalidServiceContactException isce) {
logger.error(__Service Contact Exception'', isce);
System.exit(1);
}
If it is required to monitor the status of the task graph (desired in most interactive task graphs), then the
monitoring class must implement the StatusListener interface and before submitting the task graph to a handler
subscribe to the task graph for its status changes.
tg.addStatusListener(this);
If registered to listen to the status notification of the task graph, implement the statusChanged()
function.
public void statusChanged(StatusEvent event) {
Status status = event.getStatus();
logger.debug(__Status changed to ''
+ status.getStatusString());
if (status.getStatusCode() == Status.COMPLETED }}
status.getStatusCode() == Status.FAILED) {
logger.info(__Task Graph Done'');
System.exit(1);
}
}
6.5 How to execute a hierarchical task graph
To create a hierarchical TaskGraph, we assume that we have created three tasks and one TaskGraph: task1, task2,
task3, and tg. Instructions for creating job submission and file transfer tasks and simple TaskGraphs are available in
Sections 6.1, 6.2, and 6.4 respectively. We then create a TaskGraph and add a dependency between these
ExecutableObjects.
/⋆ Give a convenient name to the TaskGraph ⋆/
htg.setName(__testGraph'');
/⋆ Add the ExecutableObjects to the TaskGraph ⋆/
htg.add(task1);
htg.add(task2);
htg.add(task3);
htg.add(tg);
/⋆ Add dependencies between these ExecutableObjects.
Dependency is added as
task1 --> task2 --> task3 --> tg.
This implies task1 is executed before task2
and task2 is executed before task3, and
task3 is executed before TaskGraph tg.
⋆/
htg.addDependency(task1,task2);
htg.addDependency(task2,task3);
htg.addDependency(task3,tg);
Next, create a TaskGraphHandler and submit the task for execution.
try {
handler.submit(htg);
} catch (InvalidSecurityContextException ise) {
logger.error(__Security Exception'',ise);
System.exit(1);
} catch (TaskSubmissionException tse) {
logger.error(__TaskSubmission Exception'',tse);
System.exit(1);
} catch (IllegalSpecException ispe) {
logger.error(__Specification Exception'',ispe);
System.exit(1);
} catch (InvalidServiceContactException isce) {
logger.error(__Service Contact Exception'',isce);
System.exit(1);
}
If it is required to monitor the status of the task graph (desired in most interactive task graphs), then the
monitoring class must implement the StatusListener interface and before submitting the task graph to a handler
subscribe to the task graph for its status changes.
htg.addStatusListener(this);
If registered to listen to the status notification of the task graph, implement the statusChanged()
function.
public void statusChanged(StatusEvent event) {
Status status = event.getStatus();
logger.debug(__Status changed to ''
+ status.getStatusString());
if (status.getStatusCode() == Status.COMPLETED }}
status.getStatusCode() == Status.FAILED) {
logger.info(__Task Graph Done'');
System.exit(1);
}
}
6.6 How to checkpoint a task
We assume you have created a Grid task as mentioned in Sections 6.1 and 6.2. To checkpoint this task you need to
invoke the “marshall” method of the TaskMarshaller class, supplying it with the task and details of the
checkpointing file.
try {
File xmlFile = new File(__Task.xml'');
xmlFile.createNewFile();
TaskMarshaller.marshal(task, xmlFile);
} catch (Exception e) {
logger.error(__Cannot marshal the task'', e);
}
6.7 How to execute a checkpointed task
We assume the Grid task is checkpointed in an XML file called “Task.xml”. First, unmrshal the checkpointed file
into a task object.
File xmlFile = new File(__Task.xml'');
task = TaskUnmarshaller.unmarshal(xmlFile);
} catch (Exception e) {
logger.error(__Cannot unmarshal task'', e);
}
Next, create a TaskHandler and submit the task for execution.
try {
handler.submit(task);
} catch (InvalidSecurityContextException ise) {
logger.error(__Security Exception'', ise);
System.exit(1);
} catch (TaskSubmissionException tse) {
logger.error(__TaskSubmission Exception'', tse);
System.exit(1);
} catch (IllegalSpecException ispe) {
logger.error(__Specification Exception'', ispe);
System.exit(1);
} catch (InvalidServiceContactException isce) {
logger.error(__Service Contact Exception'', isce);
System.exit(1);
}
If it is required to monitor the status of the task (desired in most interactive tasks), then the monitoring class must
implement the StatusListener interface and before submitting the task to a handler subscribe to the task for its
status changes.
task.addStatusListener(this);
If registered to listen to the status notification of the task, implement the statusChanged() function.
public void statusChanged(StatusEvent event) {
Status status = event.getStatus();
logger.debug(__Status changed to ''
+ status.getStatusString());
if (status.getStatusCode() == Status.COMPLETED }}
status.getStatusCode() == Status.FAILED) {
logger.info(__Task Done'');
System.exit(1);
}
}
6.8 How to checkpoint a task graph
We assume you have created a task graph as mentioned in Sections 6.4 and 6.5. To checkpoint this task graph, you
need to invoke the “marshall” method of the TaskGraphMarshaller class, supplying it with the task graph and
details of the checkpointing file.
File xmlFile = new File(__TaskGraph.xml'');
xmlFile.createNewFile();
TaskGraphMarshaller.marshal(taskGraph, xmlFile);
} catch (Exception e) {
logger.error(__Cannot marshal the task graph'', e);
}
6.9 How to resume a checkpointed task graph
We assume the task graph is checkpointed in an XML file called “TaskGraph.xml”. First, unmrshal the
checkpointed file into a task graph object.
try {
File xmlFile = new File(__TaskGraph.xml'');
taskGraph = TaskGraphUnmarshaller.unmarshal(xmlFile);
} catch (Exception e) {
logger.error(__Cannot unmarshal task graph'', e);
}
Next, create a TaskGraphHandler and submit the task graph for execution.
try {
handler.submit(taskGraph);
} catch (InvalidSecurityContextException ise) {
logger.error(__Security Exception'', ise);
System.exit(1);
} catch (TaskSubmissionException tse) {
logger.error(__TaskSubmission Exception'', tse);
System.exit(1);
} catch (IllegalSpecException ispe) {
logger.error(__Specification Exception'', ispe);
System.exit(1);
} catch (InvalidServiceContactException isce) {
logger.error(__Service Contact Exception'', isce);
System.exit(1);
}
This will initiate the re-execution of all previously uncompleted elements of the task graph. If it is required to
monitor the status of the task graph, then the monitoring class must implement the StatusListener
interface and before submitting the taskgraph to a handler subscribe to the task graph for its status
changes.
taskGraph.addStatusListener(this);
If registered to listen to the status notification of the task graph, implement the statusChanged()
function.
public void statusChanged(StatusEvent event) {
Status status = event.getStatus();
logger.debug(__Status changed to ''
+ status.getStatusString());
if (status.getStatusCode() == Status.COMPLETED }}
status.getStatusCode() == Status.FAILED) {
logger.info(__Task graph Done'');
System.exit(1);
}
}
6.10 How to invoke remote file operations without adhering to the task model
File operations can invoked on any file server without adhering to the traditional task model. Create a FileResource
object
FileResource resource = AbstractionFactory.newFileResource(provider);
/⋆ Set an appropriate name for this resource ⋆/
resource.setName(__MyFileResource'');
/⋆ Create appropriate security context for this resource ⋆/
securityContext = AbstractionFactory.newSecurityContext(__local'');
/⋆ Set the security context for this resource ⋆/
resource.setSecurityContext(securityContext);
/⋆ Create a new service contact with the
appropriate service endpoint address
⋆/
ServiceContact serviceContact =
new ServiceContactImpl(__hot.anl.gov:2119'');
/⋆ Set the service contact for this resource ⋆/
resource.setServiceContact(serviceContact);
/⋆ Initialize the file resource connection ⋆/
resource.start();
/⋆ Invoke any method available on the file
resource object and process its input
as required
⋆/
/⋆ When done with this file resource,
terminate the connection
⋆/
resource.stop();
6.11 How to run a native Condor job using the CoG Kit abstractions
Native Condor jobs are submitted to the Condor pool using job description files. This is in contrast to the interface-
and API-based approach adopted in the Java CoG Kit. Nevertheless, the abstractions offered by the CoG Kit can be
used to submit native Condor jobs without explicitly creating description files. Since the Condor job
submission paradigm requires all job submissions to be done locally from a Condor submit machine,
throughout this example we assume that the job will be executed locally from the Condor submit
machine.
To begin with, create a Task with the appropriate attributes.
Task task = new TaskImpl(__myCondorTask'', Task.JOB˘SUBMISSION);
/⋆ Set the provider as Condor.
⋆/
task.setProvider(__Condor'');
Then, create a JobSpecification for the task and set the appropriate attributes as per the task requirements.
JobSpecification spec = new JobSpecificationImpl();
/⋆ Set the location and name of the executable.
⋆/
spec.setExecutable(__/bin/ls'');
/⋆ Set the arguments (if any)
for the executable
⋆/
spec.addArguments(__-l'');
spec.addArguments(__-a'');
/⋆ Set the path name of the initial
directory. This method is equivalent
to the Initialdir attribute of the
Condor submit description file.
⋆/
spec.setDirectory(__/home/amin'')
/⋆ Set the name of the file which serves
as the input to the executable
⋆/
spec.setStdInput(__condor-input'');
/⋆ Set the name of the file to which the remote
output and remote error must be stored in.
If left blank or null, the output and error
will be redirected to the /dev/null of the
remote machine.
⋆/
spec.setStdOutput(__condor-output'');
spec.setStdError(__condor-error'');
/⋆ Add additional attributes that are not
provided by in the JobSpecification.
All the attributes that are acceptable in
Condor job submit file can be specified
as a (name,value) pair.
For example, to specify the LOG file
in a job, the user can set the value as:
⋆/
spec.setAttribute(__log'', __condor-log'');
/⋆ Assign this specification