/* * * 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"); } }