/*
*
* 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.site.classes;
import edu.isi.pegasus.common.util.Currently;
import edu.isi.pegasus.planner.catalog.site.classes.Directory.TYPE;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Prints the Site Catalog compatible with Site Catalog schema version 3
*
* https://pegasus.isi.edu/wms/docs/schemas/sc-4.0/sc-3.0.html
*
* @author Rajiv Mayani
* @version $Revision: 5858 $
*/
public class XML3PrintVisitor extends AbstractXMLPrintVisitor {
/**
* The "official" namespace URI of the site catalog schema.
*/
public static final String SCHEMA_NAMESPACE = "http://pegasus.isi.edu/schema/sitecatalog";
/**
* The "not-so-official" location URL of the DAX schema definition.
*/
public static final String SCHEMA_LOCATION = "http://pegasus.isi.edu/schema/sc-3.0.xsd";
/**
* The version to report.
*/
public static final String SCHEMA_VERSION = "3.0";
/**
*
* @author mayani
*/
private enum DirectoryTypes {
HEADFS_SCRATCH, HEADFS_STORAGE, WORKERFS_SCRATCH, WORKERFS_STORAGE;
}
/**
* Keep track of which directories are found in the site.
*/
private Directory[] mDirectory = null;
/**
* Keep track of which file servers are listed in the specified directories.
*/
private List<FileServer>[] mFileServer = null;
/**
* Track which type of directory was traversed last.
*/
private TYPE mLastDirectoryTraversed;
/**
* Ensure that Directory information is written only once.
*/
private boolean isFSWritten = false;
/**
* Visit the SiteStore object
*
* @param store
* the site store
*/
public void visit(SiteStore store) throws IOException {
String indent = getCurrentIndent();
// write out the xml element
mWriter.write(indent);
indent = (indent != null && indent.length() > 0) ? indent : "";
mWriter.write(indent);
mWriter.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
mWriter.write(mNewLine);
mWriter.write(indent);
mWriter.write("<!-- generated: ");
mWriter.write(Currently.iso8601(false));
mWriter.write(" -->");
mWriter.write(mNewLine);
// who generated this document
mWriter.write(indent);
mWriter.write("<!-- generated by: ");
mWriter.write(System.getProperties()
.getProperty("user.name", "unknown"));
mWriter.write(" [");
mWriter.write(System.getProperties().getProperty("user.region", "??"));
mWriter.write("] -->");
mWriter.write(mNewLine);
// root element with elementary attributes
mWriter.write(indent);
mWriter.write('<');
mWriter.write("sitecatalog xmlns");
mWriter.write("=\"");
mWriter.write(SCHEMA_NAMESPACE);
mWriter.write("\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"");
mWriter.write(SCHEMA_NAMESPACE);
mWriter.write(' ');
mWriter.write(SCHEMA_LOCATION);
mWriter.write('"');
writeAttribute(mWriter, "version", SCHEMA_VERSION);
mWriter.write('>');
mWriter.write(mNewLine);
incrementIndentIndex();
}
/**
* Depart the Site Store object.
*
* @param store
* the SiteStore
*/
public void depart(SiteStore store) throws IOException {
decrementIndentIndex();
closeElement("sitecatalog");
}
/**
* Visit the Site CatalogEntry object
*
* @param entry
* the site catalog entry
*
* @throws IOException
* in case of problem of writing
*/
public void visit(SiteCatalogEntry entry) throws IOException {
String indent = getCurrentIndent();
// write out the xml element
mWriter.write(indent);
mDirectory = new Directory[4];
mFileServer = new List[4];
isFSWritten = false;
mWriter.write("<site ");
writeAttribute(mWriter, "handle", entry.getSiteHandle());
writeAttribute(mWriter, "arch", entry.getArchitecture().toString());
writeAttribute(mWriter, "os", entry.getOS().toString());
String val = null;
if ((val = entry.getOSRelease()) != null && val.length() > 0) {
writeAttribute(mWriter, "osrelease", val);
}
if ((val = entry.getOSVersion()) != null && val.length() > 0) {
writeAttribute(mWriter, "osversion", val);
}
if ((val = entry.getGlibc()) != null && val.length() > 0) {
writeAttribute(mWriter, "glibc", val);
}
mWriter.write(">");
mWriter.write(mNewLine);
// for our nested elements we have to increment the index
incrementIndentIndex();
}
/**
* Depart the Site Catalog Entry object.
*
* @param entry
* the site catalog entry
*/
public void depart(SiteCatalogEntry entry) throws IOException {
String indent = getCurrentIndent();
if (!isFSWritten) {
writeFS();
isFSWritten = true;
}
entry.getProfiles().toXML(mWriter, indent);
closeElement("site");
}
private void writeFS() throws IOException {
writeHeadFS();
writeWorkerFS();
}
private void writeHeadFS() throws IOException {
if (mDirectory[DirectoryTypes.HEADFS_STORAGE.ordinal()] != null
|| mDirectory[DirectoryTypes.HEADFS_SCRATCH.ordinal()] != null
|| mDirectory[DirectoryTypes.WORKERFS_STORAGE.ordinal()] != null) {
String indent = getCurrentIndent();
mWriter.write(indent);
mWriter.write("<head-fs>");
mWriter.write(mNewLine);
incrementIndentIndex();
writeHeadFSScratch();
writeHeadFSStorage();
decrementIndentIndex();
mWriter.write(indent);
mWriter.write("</head-fs>");
mWriter.write(mNewLine);
}
}
private void writeHeadFSScratch() throws IOException {
String indent = getCurrentIndent();
// write out the xml element
mWriter.write(indent);
mWriter.write("<scratch>");
mWriter.write(mNewLine);
Directory directory = mDirectory[DirectoryTypes.HEADFS_SCRATCH
.ordinal()];
incrementIndentIndex();
indent = getCurrentIndent();
// write out the xml element
mWriter.write(indent);
mWriter.write("<shared>");
mWriter.write(mNewLine);
incrementIndentIndex();
indent = getCurrentIndent();
writeFileServer(directory, DirectoryTypes.HEADFS_SCRATCH);
// write out the internal mount point
directory.getInternalMountPoint().toXML(mWriter, indent);
decrementIndentIndex();
indent = getCurrentIndent();
mWriter.write(indent);
mWriter.write("</shared>");
mWriter.write(mNewLine);
decrementIndentIndex();
indent = getCurrentIndent();
mWriter.write(indent);
mWriter.write("</scratch>");
mWriter.write(mNewLine);
}
private void writeFileServer(Directory directory, DirectoryTypes type)
throws IOException {
String indent = getCurrentIndent();
// iterate through all the file servers
List<FileServer> servers = mFileServer[type.ordinal()];
for (FileServer server : servers) {
// write out the xml element
mWriter.write(indent);
mWriter.write("<file-server");
writeAttribute(mWriter, "protocol", server.getProtocol());
writeAttribute(mWriter, "url", server.getURLPrefix());
writeAttribute(mWriter, "mount-point", server.getMountPoint());
if (server.getProfiles().isEmpty()) {
mWriter.write("/>");
} else {
mWriter.write(">");
mWriter.write(mNewLine);
incrementIndentIndex();
indent = getCurrentIndent();
server.getProfiles().toXML(mWriter, indent);
decrementIndentIndex();
indent = getCurrentIndent();
mWriter.write(indent);
mWriter.write("</file-server>");
}
mWriter.write(mNewLine);
}
}
private void writeHeadFSStorage() throws IOException {
String indent = getCurrentIndent();
// write out the xml element
mWriter.write(indent);
mWriter.write("<storage>");
mWriter.write(mNewLine);
Directory directory = mDirectory[DirectoryTypes.HEADFS_STORAGE
.ordinal()];
if (directory != null) {
incrementIndentIndex();
indent = getCurrentIndent();
// write out the xml element
mWriter.write(indent);
mWriter.write("<shared>");
mWriter.write(mNewLine);
incrementIndentIndex();
indent = getCurrentIndent();
writeFileServer(directory, DirectoryTypes.HEADFS_STORAGE);
// write out the internal mount point
directory.getInternalMountPoint().toXML(mWriter, indent);
decrementIndentIndex();
indent = getCurrentIndent();
mWriter.write(indent);
mWriter.write("</shared>");
mWriter.write(mNewLine);
decrementIndentIndex();
indent = getCurrentIndent();
}
// Local
directory = mDirectory[DirectoryTypes.WORKERFS_STORAGE.ordinal()];
if (directory != null) {
incrementIndentIndex();
indent = getCurrentIndent();
// write out the xml element
mWriter.write(indent);
mWriter.write("<local>");
mWriter.write(mNewLine);
incrementIndentIndex();
indent = getCurrentIndent();
writeFileServer(directory, DirectoryTypes.WORKERFS_STORAGE);
// write out the internal mount point
directory.getInternalMountPoint().toXML(mWriter, indent);
decrementIndentIndex();
indent = getCurrentIndent();
mWriter.write(indent);
mWriter.write("</local>");
mWriter.write(mNewLine);
decrementIndentIndex();
indent = getCurrentIndent();
}
mWriter.write(indent);
mWriter.write("</storage>");
mWriter.write(mNewLine);
}
private void writeWorkerFS() throws IOException {
String indent = getCurrentIndent();
Directory directory = mDirectory[DirectoryTypes.WORKERFS_SCRATCH
.ordinal()];
if (directory != null) {
// write out the xml element
mWriter.write(indent);
mWriter.write("<worker-fs>");
mWriter.write(mNewLine);
incrementIndentIndex();
writeWorkerFSScratch();
decrementIndentIndex();
mWriter.write(indent);
mWriter.write("</worker-fs>");
mWriter.write(mNewLine);
}
}
private void writeWorkerFSScratch() throws IOException {
String indent = getCurrentIndent();
Directory directory = mDirectory[DirectoryTypes.WORKERFS_SCRATCH
.ordinal()];
// write out the xml element
mWriter.write(indent);
mWriter.write("<scratch>");
mWriter.write(mNewLine);
incrementIndentIndex();
indent = getCurrentIndent();
// write out the xml element
mWriter.write(indent);
mWriter.write("<local>");
mWriter.write(mNewLine);
incrementIndentIndex();
indent = getCurrentIndent();
writeFileServer(directory, DirectoryTypes.WORKERFS_SCRATCH);
// write out the internal mount point
directory.getInternalMountPoint().toXML(mWriter, indent);
decrementIndentIndex();
indent = getCurrentIndent();
mWriter.write(indent);
mWriter.write("</local>");
mWriter.write(mNewLine);
decrementIndentIndex();
indent = getCurrentIndent();
mWriter.write(indent);
mWriter.write("</scratch>");
mWriter.write(mNewLine);
}
/**
* Visit the GridGateway object
*
* @param gateway
* the grid gateway
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void visit(GridGateway gateway) throws IOException {
String indent = getCurrentIndent();
// write out the xml element
mWriter.write(indent);
mWriter.write("<grid ");
writeAttribute(mWriter, "type", gateway.getType().toString());
writeAttribute(mWriter, "contact", gateway.getContact());
writeAttribute(mWriter, "scheduler", gateway.getScheduler().toString());
writeAttribute(mWriter, "jobtype", gateway.getJobType().toString());
if (gateway.getOS() != null) {
writeAttribute(mWriter, "os", gateway.getOS().toString());
}
if (gateway.getArchitecture() != null) {
writeAttribute(mWriter, "arch", gateway.getArchitecture()
.toString());
}
String val = null;
if ((val = gateway.getOSRelease()) != null) {
writeAttribute(mWriter, "osrelease", val);
}
if ((val = gateway.getOSVersion()) != null) {
writeAttribute(mWriter, "osversion", val);
}
if ((val = gateway.getGlibc()) != null) {
writeAttribute(mWriter, "glibc", val);
}
if (gateway.getIdleNodes() != -1) {
writeAttribute(mWriter, "idle-nodes",
Integer.toString(gateway.getIdleNodes()));
}
if (gateway.getTotalNodes() != -1) {
writeAttribute(mWriter, "total-nodes",
Integer.toString(gateway.getTotalNodes()));
}
mWriter.write("/>");
mWriter.write(mNewLine);
}
/**
* Depart the GridGateway object
*
* @param entry
* GridGateway object
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void depart(GridGateway entry) throws IOException {
}
/**
* Visit the directory object
*
* @param directory
* the directory
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void visit(Directory directory) throws IOException {
// sanity check?
if (directory.isEmpty()) {
return;
}
switch (directory.getType()) {
case shared_scratch:
mLastDirectoryTraversed = TYPE.shared_scratch;
mDirectory[DirectoryTypes.HEADFS_SCRATCH.ordinal()] = directory;
break;
case shared_storage:
mLastDirectoryTraversed = TYPE.shared_storage;
mDirectory[DirectoryTypes.HEADFS_STORAGE.ordinal()] = directory;
break;
case local_scratch:
mLastDirectoryTraversed = TYPE.local_scratch;
mDirectory[DirectoryTypes.WORKERFS_SCRATCH.ordinal()] = directory;
break;
case local_storage:
mLastDirectoryTraversed = TYPE.local_storage;
mDirectory[DirectoryTypes.WORKERFS_STORAGE.ordinal()] = directory;
break;
default:
break;
}
}
/**
* Depart the shared directory
*
* @param directory
* the directory
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void depart(Directory directory) throws IOException {
}
/**
* Visit FileServer site data object
*
* @param server
* the object corresponding to the FileServer
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void visit(FileServer server) throws IOException {
if (mLastDirectoryTraversed == null) {
// Should never happen
}
if (mFileServer[mLastDirectoryTraversed.ordinal()] == null) {
mFileServer[mLastDirectoryTraversed.ordinal()] = new ArrayList<FileServer>();
}
mFileServer[mLastDirectoryTraversed.ordinal()].add(server);
}
/**
* Depart the Directory object
*
* @param server
* the object corresponding to the FileServer
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void depart(FileServer server) throws IOException {
}
/**
* Visit the ReplicaCatalog object
*
* @param catalog
* the object describing the catalog
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void visit(ReplicaCatalog catalog) throws IOException {
String indent = this.getCurrentIndent();
if (!isFSWritten) {
writeFS();
isFSWritten = true;
}
// write out the xml element
mWriter.write(indent);
mWriter.write("<replica-catalog ");
// fixed for time being
writeAttribute(mWriter, "type", catalog.getType());
writeAttribute(mWriter, "url", catalog.getURL());
mWriter.write(">");
mWriter.write(mNewLine);
// for our nested elements we have to increment the index
incrementIndentIndex();
}
/**
* Depart the ReplicaCatalog object
*
* @param catalog
* the object describing the catalog
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void depart(ReplicaCatalog catalog) throws IOException {
String indent = getCurrentIndent();
// list all the aliases first
for (Iterator<String> it = catalog.getAliasIterator(); it.hasNext();) {
catalog.writeAlias(mWriter, indent, it.next());
}
closeElement("replica-catalog");
}
/**
* Visit the connection object
*
* @param c
* the connection.
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void visit(Connection c) throws IOException {
String indent = this.getCurrentIndent();
// write out the xml element
// write out the xml element
mWriter.write(indent);
mWriter.write("<connection ");
writeAttribute(mWriter, "key", c.getKey());
mWriter.write(">");
mWriter.write(c.getValue());
mWriter.write("</connection>");
mWriter.write(mNewLine);
// for our nested elements we have to increment the index
incrementIndentIndex();
}
/**
* Depart the connection object
*
* @param c
* the connection.
*
* @throws IOException
* in case of error while writing to underlying stream
*/
public void depart(Connection c) throws IOException {
closeElement("connection");
}
}