/*
* 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 com.github.sakserv.minicluster.oozie.sharelib.util;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import com.github.sakserv.minicluster.oozie.sharelib.Framework;
import org.apache.commons.io.FileUtils;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.sakserv.minicluster.http.HttpUtils;
import com.github.sakserv.propertyparser.PropertyParser;
public class OozieShareLibUtil {
// Logger
private static final Logger LOG = LoggerFactory.getLogger(OozieShareLibUtil.class);
// Setup the property parser
private static final String PROP_FILE = "sharelib.properties";
private static PropertyParser propertyParser;
static {
try {
propertyParser = new PropertyParser(PROP_FILE);
propertyParser.parsePropsFile();
} catch (IOException e) {
LOG.error("Unable to load property file: {}", PROP_FILE);
}
}
// Constants
private static final String SHARE_LIB_PREFIX = "lib_";
private static final String SHARE_LIB_LOCAL_TEMP_PREFIX = "oozie_share_lib_tmp";
// Instance variables
String oozieHdfsShareLibDir;
Boolean oozieShareLibCreate;
String shareLibCacheDir;
Boolean purgeLocalShareLibCache;
FileSystem hdfsFileSystem;
List<Framework> oozieShareLibFrameworks;
// Constructor
public OozieShareLibUtil(String oozieHdfsShareLibDir, Boolean oozieShareLibCreate, String shareLibCacheDir,
Boolean purgeLocalShareLibCache, FileSystem hdfsFileSystem,
List<Framework> oozieShareLibFrameworks) {
this.oozieHdfsShareLibDir = oozieHdfsShareLibDir;
this.oozieShareLibCreate = oozieShareLibCreate;
this.shareLibCacheDir = shareLibCacheDir;
this.purgeLocalShareLibCache = purgeLocalShareLibCache;
this.hdfsFileSystem = hdfsFileSystem;
this.oozieShareLibFrameworks = oozieShareLibFrameworks;
}
// Main driver that downloads, extracts, and deploys the oozie sharelib
public void createShareLib() {
if (!oozieShareLibCreate) {
LOG.info("OOZIE: Share Lib Create Disabled... skipping");
} else {
final String fullOozieTarFilePath = shareLibCacheDir + Path.SEPARATOR + getOozieTarFileName();
try {
// Get and extract the oozie release
getOozieTarFileFromRepo();
String oozieExtractTempDir = extractOozieTarFileToTempDir(new File(fullOozieTarFilePath));
// Extract the sharelib tarball to a temp dir
String fullOozieShareLibTarFilePath = oozieExtractTempDir + Path.SEPARATOR +
"oozie-" + getOozieVersionFromOozieTarFileName() + Path.SEPARATOR +
"oozie-sharelib-" + getOozieVersionFromOozieTarFileName() + ".tar.gz";
String oozieShareLibExtractTempDir = extractOozieShareLibTarFileToTempDir(
new File(fullOozieShareLibTarFilePath));
// Copy the sharelib into HDFS
Path destPath = new Path(oozieHdfsShareLibDir + Path.SEPARATOR + "oozie" + Path.SEPARATOR +
SHARE_LIB_PREFIX + getTimestampDirectory());
LOG.info("OOZIE: Writing share lib contents to: {}", destPath);
hdfsFileSystem.copyFromLocalFile(false, new Path(new File(oozieShareLibExtractTempDir).toURI()), destPath);
if (purgeLocalShareLibCache) {
FileUtils.deleteDirectory(new File(shareLibCacheDir));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String getTimestampDirectory() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
Date date = new Date();
return dateFormat.format(date).toString();
}
public String getOozieTarFileUrl() {
String version = System.getProperty("hdp.release.version");
return propertyParser.getProperty(version + ".url");
}
public String getOozieTarFileName() {
String version = System.getProperty("hdp.release.version");
String url = propertyParser.getProperty(version + ".url");
return url.substring(url.lastIndexOf('/') + 1);
}
public String getOozieVersionFromOozieTarFileName() {
return getOozieTarFileName().replace("-distro.tar.gz","").replace("oozie-","");
}
public void getOozieTarFileFromRepo() throws IOException {
final String fullOozieTarFilePath = shareLibCacheDir + Path.SEPARATOR + getOozieTarFileName();
if(purgeLocalShareLibCache) {
FileUtils.deleteDirectory(new File(shareLibCacheDir));
}
if (new File(fullOozieTarFilePath).exists()) {
LOG.info("OOZIE: Found Oozie tarball in cache, skipping download: {}", fullOozieTarFilePath);
} else {
downloadOozieTarFileToLocalCacheDir();
}
}
public void downloadOozieTarFileToLocalCacheDir() throws IOException {
final String fullOozieTarFilePath = shareLibCacheDir + Path.SEPARATOR + getOozieTarFileName();
HttpUtils.downloadFileWithProgress(getOozieTarFileUrl(), fullOozieTarFilePath);
}
public String extractOozieTarFileToTempDir(File fullOozieTarFilePath) throws IOException {
File tempDir = File.createTempFile(SHARE_LIB_LOCAL_TEMP_PREFIX, "");
tempDir.delete();
tempDir.mkdir();
tempDir.deleteOnExit();
FileUtil.unTar(fullOozieTarFilePath, tempDir);
return tempDir.getAbsolutePath();
}
public String extractOozieShareLibTarFileToTempDir(File fullOozieShareLibTarFilePath) throws IOException {
File tempDir = File.createTempFile(SHARE_LIB_LOCAL_TEMP_PREFIX, "");
tempDir.delete();
tempDir.mkdir();
tempDir.deleteOnExit();
FileUtil.unTar(fullOozieShareLibTarFilePath, tempDir);
// Remove spark to try to get the CP down.
if (oozieShareLibFrameworks != null || !oozieShareLibFrameworks.isEmpty()) {
for (Framework framework : Framework.values()) {
if (!oozieShareLibFrameworks.contains(framework)) {
LOG.info("OOZIE: Excluding framework " + framework.getValue() + " from shared lib.");
File removeShareLibDir = new File(tempDir.getAbsolutePath() + "/share/lib/" + framework.getValue());
if (removeShareLibDir.isDirectory()) {
FileUtils.deleteDirectory(removeShareLibDir);
}
}
}
}
return tempDir.getAbsolutePath();
}
}