blob: 32ca80147460bb34a59c9f50b6366f4b71725a1f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.oodt.cas.resource.mux;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.oodt.cas.resource.scheduler.Scheduler;
import org.apache.oodt.cas.resource.structs.exceptions.RepositoryException;
import org.apache.oodt.cas.resource.util.GenericResourceManagerObjectFactory;
import org.apache.oodt.commons.xml.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* Class to load BackendManager from XML file.
* @author starchmd
*/
public class XmlBackendRepository implements BackendRepository {
private static final Logger LOG = Logger.getLogger(XmlBackendRepository.class.getName());
private String uri;
//Constants
private static final String SCHEDULER = "scheduler";
private static final String BATCHMGR = "batchmgr";
private static final String MONITOR = "monitor";
private static final String MONITOR_PROPERTY = "resource.monitor.factory";
private static final String BATCHMGR_PROPERTY = "resource.batchmgr.factory";
/**
* Ctor
* @param uri - uri of XML file containing mapping
*/
public XmlBackendRepository(String uri) {
if (uri == null)
throw new NullPointerException("URI for queue-to-backend xml file cannot be null");
this.uri = uri;
}
/* (non-Javadoc)
* @see org.apache.oodt.cas.resource.mux.BackendRepository#load()
*/
@Override
public BackendManager load() throws RepositoryException {
LOG.log(Level.INFO,"Reading backend set manager from: "+this.uri);
BackendManager bm = new StandardBackendManager();
String origMon = System.getProperty(MONITOR_PROPERTY);
String origBat = System.getProperty(BATCHMGR_PROPERTY);
try {
File file = new File(new URI(this.uri));
Document root = XMLUtils.getDocumentRoot(new FileInputStream(file));
NodeList list = root.getElementsByTagName("queue");
if (list != null && list.getLength() > 0) {
for (int k = 0; k < list.getLength(); k++) {
Element node = (Element)list.item(k);
String queue = node.getAttribute("name");
//Set properties for batch and monitor factories
//So scheduler builds as repository specifies
try {
String mfact = getMonitor(queue,node);
LOG.log(Level.INFO,"Setting monitor factory property to: "+mfact);
System.setProperty(MONITOR_PROPERTY, mfact);
} catch (RepositoryException e) {
LOG.log(Level.INFO, "No monitor factory for queue "+queue+", using system property.");
}
try {
String bfact = getBatchmgr(queue,node);
LOG.log(Level.INFO,"Setting batchmgr factory property to: "+bfact);
System.setProperty(BATCHMGR_PROPERTY, bfact);
} catch (RepositoryException e) {
LOG.log(Level.INFO, "No batchmgr factory for queue "+queue+", using system property.");
}
//Build scheduler
Scheduler sch = getScheduler(queue,node);
bm.addSet(queue, sch.getMonitor(), sch.getBatchmgr(), sch);
//Reset Properties for next item
resetAlteredProperty(MONITOR_PROPERTY,origMon);
resetAlteredProperty(BATCHMGR_PROPERTY,origBat);
}
}
} catch (URISyntaxException e) {
LOG.log(Level.SEVERE,"Malformed URI: "+this.uri);
throw new RepositoryException(e);
} catch(FileNotFoundException e) {
LOG.log(Level.SEVERE,"File not found: "+this.uri+" from working dir: "+new File(".").getAbsolutePath());
throw new RepositoryException(e);
} catch (ClassCastException e) {
LOG.log(Level.SEVERE,"Queue tag must represent XML element.");
throw new RepositoryException(e);
} finally {
resetAlteredProperty(MONITOR_PROPERTY,origMon);
resetAlteredProperty(BATCHMGR_PROPERTY,origBat);
}
return bm;
}
/**
* Resets a property. Allows nulls
* @param prop - property name to reset
* @param value - value to reset to, can be null
*/
private static void resetAlteredProperty(String prop,String value) {
if (value == null) {
System.clearProperty(prop);
return;
}
System.setProperty(prop,value);
}
/**
* Get monitor factory from XML
* @param queue - current queue, for error reporting
* @param node - node that is being read
* @return monitor factory string
* @throws RepositoryException
*/
private static String getMonitor(String queue,Element node) throws RepositoryException {
return getFactoryAttribute(queue, node, MONITOR);
}
/**
* Get scheduler from XML
* @param queue - current queue, for error reporting
* @param node - node that is being read
* @return newly constructed Scheduler
* @throws RepositoryException
*/
private static Scheduler getScheduler(String queue,Element node) throws RepositoryException {
String factory = getFactoryAttribute(queue, node, SCHEDULER);
LOG.log(Level.INFO,"Loading monitor from: "+factory);
Scheduler sch = GenericResourceManagerObjectFactory.getSchedulerServiceFromFactory(factory);
if (sch != null)
return sch;
throw new RepositoryException("Could instantiate from: "+factory);
}
/**
* Get batchmgr factory from XML
* @param queue - current queue, for error reporting
* @param node - node that is being read
* @return batch manager factory name
* @throws RepositoryException
*/
private static String getBatchmgr(String queue,Element node) throws RepositoryException {
return getFactoryAttribute(queue, node, BATCHMGR);
}
/**
* Pull out the factory attribute from tag with given name.
* @param queue - current queue, for error reporting
* @param elem - element that contains tags as children
* @param tag - string name of tag looked for. i.e. "monitor"
* @return name of factory class
* @throws RepositoryException - thrown if more than one child matches, no children match, or other error
*/
private static String getFactoryAttribute(String queue,Element elem, String tag) throws RepositoryException {
NodeList children = elem.getElementsByTagName(tag);
try {
String attr = "";
if (children.getLength() != 1 || (attr = ((Element)children.item(0)).getAttribute("factory")) == "") {
throw new RepositoryException("Could not find exactly one "+tag+", with factory set, in queue: "+queue);
}
return attr;
} catch (ClassCastException e) {
throw new RepositoryException("Tag "+tag+" does not represent XML element in queue: "+queue,e);
}
}
}