/*
* 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.ngrinder.common.model;
import org.apache.commons.io.FileUtils;
import org.ngrinder.common.constants.GrinderConstants;
import org.ngrinder.common.exception.ConfigurationException;
import org.ngrinder.common.util.EncodingUtils;
import org.ngrinder.common.util.NoOp;
import org.ngrinder.model.PerfTest;
import org.ngrinder.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;
import static org.ngrinder.common.util.ExceptionUtils.processException;
import static org.ngrinder.common.util.Preconditions.checkNotNull;
/**
* Home class which enables the easy resource access in ${NGRINDER_HOME}
* directory.
*
* @author JunHo Yoon
* @since 3.0
*/
public class Home {
// HOME_PATH
private static final String PATH_PLUGIN = "plugins";
private static final String PATH_SCRIPT = "script";
private static final String PATH_USER_REPO = "repos";
private static final String PATH_PERF_TEST = "perftest";
private static final String PATH_DOWNLOAD = "download";
private static final String PATH_GLOBAL_LOG = "logs";
private static final String PATH_LOG = "logs";
private static final String PATH_REPORT = "report";
private static final String PATH_DIST = "dist";
private static final String PATH_STAT = "stat";
private final static Logger LOGGER = LoggerFactory.getLogger(Home.class);
private final File directory;
public static final String REPORT_CSV = "output.csv";
/**
* Constructor.
*
* @param directory home directory
*/
public Home(File directory) {
this(directory, true);
}
/**
* Constructor.
*
* @param directory home directory ${NGRINDER_HOME}
* @param create create the directory if not exists
*/
public Home(File directory, boolean create) {
checkNotNull(directory, "directory should not be null");
if (create) {
if (directory.mkdir()) {
LOGGER.info("{} is created.", directory.getPath());
}
}
if (directory.exists() && !directory.canWrite()) {
throw new ConfigurationException(String.format(" ngrinder home directory %s is not writable.", directory),
null);
}
this.directory = directory;
}
public void init() {
makeSubPath(PATH_PLUGIN);
makeSubPath(PATH_PERF_TEST);
makeSubPath(PATH_DOWNLOAD);
}
/**
* Get the home directory.
*
* @return the home directory
*/
public File getDirectory() {
return directory;
}
/**
* Copy the given file from given location.
*
* @param from file location
*/
public void copyFrom(File from) {
// Copy missing files
try {
for (File file : checkNotNull(from.listFiles())) {
if (!(new File(directory, file.getName()).exists())) {
FileUtils.copyFileToDirectory(file, directory);
} else {
File orgConf = new File(directory, "org_conf");
if (orgConf.mkdirs()) {
LOGGER.info("{}", orgConf.getPath());
}
FileUtils.copyFile(file, new File(orgConf, file.getName()));
}
}
} catch (IOException e) {
throw processException("Fail to copy files from " + from.getAbsolutePath(), e);
}
}
/**
* Make a sub directory on the home directory.
*
* @param subPathName sub-path name
*/
public void makeSubPath(String subPathName) {
mkDir(new File(directory, subPathName));
}
/**
* Get the {@link Properties} from the the given configuration file.
*
* @param confFileName configuration file name
* @return loaded {@link Properties}
*/
public Properties getProperties(String confFileName) {
try {
File configFile = getSubFile(confFileName);
if (configFile.exists()) {
byte[] propByte = FileUtils.readFileToByteArray(configFile);
String propString = EncodingUtils.getAutoDecodedString(propByte, "UTF-8");
Properties prop = new Properties();
prop.load(new StringReader(propString));
return prop;
} else {
// default empty properties.
return new Properties();
}
} catch (IOException e) {
throw processException("Fail to load property file " + confFileName, e);
}
}
/**
* Get the sub {@link File} instance under the home directory.
*
* @param subPathName subpath name
* @return {@link File}
*/
public File getSubFile(String subPathName) {
return new File(directory, subPathName);
}
/**
* Get the plugin cache directory.
*
* @return plugin cache directory.
*/
public File getPluginsCacheDirectory() {
File cacheDir = getSubFile(PATH_PLUGIN + "_cache");
cacheDir.mkdirs();
return cacheDir;
}
/**
* Get the plugin directory.
*
* @return plugin directory.
*/
public File getPluginsDirectory() {
return getSubFile(PATH_PLUGIN);
}
/**
* Get the repo base directory.
*
* @return repo base directory.
*/
public File getRepoDirectoryRoot() {
return getSubFile(PATH_USER_REPO);
}
/**
* Get the user repo directory for the given user.
*
* @param user user
* @return user repo directory.
*/
public File getUserRepoDirectory(User user) {
return getUserRepoDirectory(user.getUserId());
}
/**
* Get the sub directory of the base user repo directory.
*
* @param subPath subPath
* @return base repo sub directory.
*/
public File getUserRepoDirectory(String subPath) {
return new File(getRepoDirectoryRoot(), subPath);
}
/**
* Get the base perftest directory.
*
* @return base perftest directory.
*/
public File getPerfTestDirectory() {
return getSubFile(PATH_PERF_TEST);
}
/**
* Get the sub directory for the given perftest.
*
* @param perfTest perfTest
* @param subPath subPath
* @return {@link PerfTest} sub directory.
*/
private File getPerfTestSubDirectory(PerfTest perfTest, String subPath) {
return mkDir(new File(getPerfTestDirectory(perfTest), subPath));
}
private File mkDir(File file) {
if (file.mkdirs()) {
LOGGER.info("{} is created.", file.getPath());
}
return file;
}
/**
* Get the sub directory of the given perftest's base directory.
*
* @param id perfTest id
* @param subPath subPath
* @return {@link PerfTest} sub directory.
*/
public File getPerfTestSubDirectory(String id, String subPath) {
File file = new File(getPerfTestDirectory(id), subPath);
return mkDir(file);
}
/**
* Get the perftest base directory for the given perftest id.
*
* @param id perftest id
* @return {@link PerfTest} sub directory.
*/
public File getPerfTestDirectory(String id) {
File file = new File(getPerfTestDirectory(), id);
// For backward compatibility
if (!file.exists()) {
file = getDistributedFolderName(id);
}
return mkDir(file);
}
File getDistributedFolderName(String id) {
int numericId = 0;
try {
numericId = (Integer.parseInt(id) / 1000) * 1000;
} catch (NumberFormatException e) {
NoOp.noOp();
}
String folderName = String.format("%d_%d%s%s", numericId, numericId + 999, File.separator, id);
return new File(getPerfTestDirectory(), folderName);
}
/**
* Get the root directory for given {@link PerfTest} id.
*
* @param perfTest perftest
* @return {@link PerfTest} log directory
*/
public File getPerfTestDirectory(PerfTest perfTest) {
return getPerfTestDirectory(String.valueOf(perfTest.getId()));
}
/**
* Get the log directory for given {@link PerfTest} id.
*
* @param id perftest id
* @return {@link PerfTest} log directory
*/
public File getPerfTestLogDirectory(String id) {
return getPerfTestSubDirectory(id, PATH_LOG);
}
/**
* Get the log directory for given {@link PerfTest}.
*
* @param perfTest perftest
* @return {@link PerfTest} log directory
*/
public File getPerfTestLogDirectory(PerfTest perfTest) {
return getPerfTestSubDirectory(perfTest, PATH_LOG);
}
/**
* Get the distribution directory for given {@link PerfTest}.
*
* @param perfTest perftest
* @return {@link PerfTest} distribution directory
*/
public File getPerfTestDistDirectory(PerfTest perfTest) {
return getPerfTestSubDirectory(perfTest, PATH_DIST);
}
/**
* Get the statistics directory for given {@link PerfTest}.
*
* @param perfTest perftest
* @return {@link PerfTest} statistics directory
*/
public File getPerfTestStatisticPath(PerfTest perfTest) {
return getPerfTestSubDirectory(perfTest, PATH_STAT);
}
/**
* Get the report directory for given {@link PerfTest} id.
*
* @param id perftest id
* @return {@link PerfTest} report directory
*/
public File getPerfTestReportDirectory(String id) {
return getPerfTestSubDirectory(id, PATH_REPORT);
}
/**
* Get the report directory for given {@link PerfTest}.
*
* @param perfTest perftest
* @return {@link PerfTest} report directory
*/
public File getPerfTestReportDirectory(PerfTest perfTest) {
return getPerfTestSubDirectory(perfTest, PATH_REPORT);
}
/**
* Get the csv file for given {@link PerfTest}.
*
* @param perfTest perftest
* @return {@link PerfTest} csv file
*/
public File getPerfTestCsvFile(PerfTest perfTest) {
return new File(getPerfTestReportDirectory(perfTest), REPORT_CSV);
}
/**
* Get the default grinder properties file.
*
* @return grinder properties file
*/
public File getDefaultGrinderProperties() {
return getSubFile(GrinderConstants.DEFAULT_GRINDER_PROPERTIES);
}
/**
* Get the download directory.
*
* @return download directory
*/
public File getDownloadDirectory() {
return getSubFile(PATH_DOWNLOAD);
}
/**
* Get global log file.
*
* @return log file
*/
public File getGlobalLogFile() {
return getSubFile(PATH_GLOBAL_LOG);
}
/**
* Check if this home exists.
*
* @return true if exists.
*/
public boolean exists() {
return directory.exists();
}
/**
* Get the user defined messages directory.
*
* @return the user defined messages directory
*/
public File getMessagesDirectory() {
return getSubFile("messages");
}
/**
* Get the script directory for the given user.
*
* @param user user
* @return script directory for the given user.
*/
public File getScriptDirectory(User user) {
return new File(getSubFile(PATH_SCRIPT), user.getUserId());
}
}