/** * Copyright 2015 Cloudera Inc. * * 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 org.kitesdk.data.oozie; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.oozie.ErrorCode; import org.apache.oozie.service.HadoopAccessorException; import org.apache.oozie.service.HadoopAccessorService; import org.apache.oozie.service.Service; import org.apache.oozie.service.ServiceException; import org.apache.oozie.service.Services; import org.apache.oozie.util.XConfiguration; import org.apache.oozie.util.XLog; public class KiteConfigurationService implements Service { public static final String CONF_PREFIX = Service.CONF_PREFIX + "KiteConfigurationService."; public static final String KITE_CONFIGURATION = CONF_PREFIX + "kite.configuration"; private static XLog LOG = XLog.getLog(KiteConfigurationService.class); private Configuration kiteConf; @Override public void init(Services services) throws ServiceException { try { loadKiteConf(services); } catch(IOException ioe) { throw new ServiceException(ErrorCode.E0100, KiteConfigurationService.class.getName(), "An exception occured while attempting" + "to load the Kite Configuration", ioe); } } public Configuration getKiteConf() { return kiteConf; } // largely borrowed with from the HCatAccessorService // configuration methodology. Modification includes the // ability to specify multiple paths to configurations private void loadKiteConf(Services services) throws IOException { String[] paths = services.getConf().getStrings(KITE_CONFIGURATION); if (paths != null && paths.length != 0) { kiteConf = new Configuration(false); for(String path : paths) { if (path.startsWith("hdfs")) { Path p = new Path(path); HadoopAccessorService has = services.get(HadoopAccessorService.class); try { FileSystem fs = has.createFileSystem( System.getProperty("user.name"), p.toUri(), has.createJobConf(p.toUri().getAuthority())); if (fs.exists(p)) { FSDataInputStream is = null; try { is = fs.open(p); Configuration partialConf = new XConfiguration(is); kiteConf = merge(kiteConf, partialConf); } finally { if (is != null) { is.close(); } } LOG.info("Loaded Kite Configuration: " + path); } else { LOG.warn("Kite Configuration could not be found at [" + path + "]"); } } catch (HadoopAccessorException hae) { throw new IOException(hae); } } else { File f = new File(path); if (f.exists()) { InputStream is = null; try { is = new FileInputStream(f); Configuration partialConf = new XConfiguration(is); kiteConf = merge(kiteConf, partialConf); } finally { if (is != null) { is.close(); } } LOG.info("Loaded Kite Configuration: " + path); } else { LOG.warn("Kite Configuration could not be found at [" + path + "]"); } } } } else { LOG.info("Kite Configuration not specified"); } } @Override public void destroy() { //no-op } @Override public Class<? extends Service> getInterface() { return KiteConfigurationService.class; } //borrowed from spring-hadoop ConfigurationUtils. Alternative for CDH5 compatibility //where Configuration.addResource(configuration) is not available private static Configuration merge(Configuration one, Configuration two) { if (one == null) { if (two == null) { return new Configuration(); } return new Configuration(two); } Configuration c = new Configuration(one); if (two == null) { return c; } for (Map.Entry<String, String> entry : two) { c.set(entry.getKey(), entry.getValue()); } return c; } }