Skip to content

Commit

Permalink
Clean up util classes (#994)
Browse files Browse the repository at this point in the history
* Move StringUtils to ngrinder-core

* Change to lazy search localhost address

* Clean up EncodingUtils

* Add profile for testing

* Temporarily disable failed tests
  • Loading branch information
imbyungjun authored Jan 8, 2024
1 parent d7cc4cf commit 9959953
Show file tree
Hide file tree
Showing 15 changed files with 194 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
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.common.util.PropertyUtils;
import org.ngrinder.model.PerfTest;
import org.ngrinder.model.User;
import org.slf4j.Logger;
Expand All @@ -26,7 +26,6 @@

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.Properties;

import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -55,8 +54,8 @@ public class Home {
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;
private static final String REPORT_CSV = "output.csv";
private final File directory;

/**
* Constructor.
Expand All @@ -81,8 +80,7 @@ public Home(File directory, boolean create) {
}
}
if (directory.exists() && !directory.canWrite()) {
throw new ConfigurationException(String.format(" ngrinder home directory %s is not writable.", directory),
null);
throw new ConfigurationException(String.format(" ngrinder home directory %s is not writable.", directory), null);
}
this.directory = directory;
}
Expand Down Expand Up @@ -140,22 +138,8 @@ public void makeSubPath(String subPathName) {
* @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);
}
File configFile = getSubFile(confFileName);
return PropertyUtils.loadProperties(configFile);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,32 @@

import com.ibm.icu.text.CharsetDetector;
import com.ibm.icu.text.CharsetMatch;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.Properties;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.ngrinder.common.util.ExceptionUtils.processException;

/**
* Automatic encoding detection utility.
*
* @since 3.0
*/
public abstract class EncodingUtils {
public abstract class PropertyUtils {

private static final int MINIMAL_CONFIDENCE_LEVEL = 70;

/**
* Decode the byte array with auto encoding detection feature.
*
* @param data
* byte array
* @param defaultEncoding
* the default encoding if no encoding is sure.
* @param data byte array
* @param defaultEncoding the default encoding if no encoding is sure.
* @return decoded string
* @throws IOException
* occurs when the decoding is failed.
* @throws IOException occurs when the decoding is failed.
*/
public static String getAutoDecodedString(byte[] data, String defaultEncoding) throws IOException {
return new String(data, detectEncoding(data, defaultEncoding));
Expand All @@ -52,10 +49,8 @@ public static String getAutoDecodedString(byte[] data, String defaultEncoding) t
/**
* Detect encoding of given data.
*
* @param data
* byte array
* @param defaultEncoding
* the default encoding if no encoding is sure.
* @param data byte array
* @param defaultEncoding the default encoding if no encoding is sure.
* @return encoding name detected encoding name
*/
public static String detectEncoding(byte[] data, String defaultEncoding) {
Expand All @@ -67,40 +62,20 @@ public static String detectEncoding(byte[] data, String defaultEncoding) {
return isReliable ? estimatedEncoding : defaultEncoding;
}

/**
* Encode the given path with UTF-8.
*
* "/" is not encoded.
* @param path path
* @return encoded path
*/
public static String encodePathWithUTF8(String path) {
public static Properties loadProperties(File file) {
try {
StringBuilder result = new StringBuilder();
for (char each : path.toCharArray()) {
if (each == '/') {
result.append("/");
} else {
result.append(URLEncoder.encode(String.valueOf(each), "UTF-8"));
}
if (file.exists()) {
byte[] propByte = FileUtils.readFileToByteArray(file);
String propString = PropertyUtils.getAutoDecodedString(propByte, "UTF-8");
Properties prop = new Properties();
prop.load(new StringReader(propString));
return prop;
} else {
// default empty properties.
return new Properties();
}
return result.toString();
} catch (UnsupportedEncodingException e) {
throw processException(e);
}
}

/**
* Decode the given path with UTF-8.
*
* @param path path
* @return decoded path
*/
public static String decodePathWithUTF8(String path) {
try {
return URLDecoder.decode(path, UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw processException(e);
} catch (IOException e) {
throw processException("Fail to load property file " + file.getAbsolutePath(), e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*
* 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
Expand Down Expand Up @@ -35,6 +35,7 @@
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
Expand All @@ -53,7 +54,7 @@

import static java.nio.charset.StandardCharsets.UTF_8;
import static net.grinder.util.NoOp.noOp;
import static org.apache.commons.io.FileUtils.*;
import static org.apache.commons.io.FileUtils.readFileToString;
import static org.apache.commons.lang.StringUtils.defaultIfEmpty;
import static org.apache.commons.lang.StringUtils.isEmpty;
import static org.ngrinder.common.constant.CacheConstants.REGION_ATTR_KEY;
Expand All @@ -71,7 +72,7 @@
*
* @since 3.0
*/

@Profile("production")
@Component
public class Config extends AbstractConfig implements ControllerConstants, ClusterConstants {
public static final String NONE_REGION = "NONE";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.ngrinder.common.util.EncodingUtils;
import org.ngrinder.common.util.PropertyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.AbstractMessageSource;
Expand Down Expand Up @@ -81,19 +80,16 @@ private Map<LocaleAndCode, MessageFormat> getLangMessageMap() {
if (messagesDirectory.exists()) {
for (String each : Locale.getISOLanguages()) {
File file = new File(messagesDirectory, "messages_" + each + ".properties");
if (file.exists()) {
try {
byte[] propByte = FileUtils.readFileToByteArray(file);
String propString = EncodingUtils.getAutoDecodedString(propByte, "UTF-8");
Properties prop = new Properties();
prop.load(new StringReader(propString));
for (Map.Entry<Object, Object> eachEntry : prop.entrySet()) {
map.put(new LocaleAndCode(each, (String) eachEntry.getKey()), new MessageFormat(
(String) eachEntry.getValue()));
}
} catch (Exception e) {
LOGGER.error("Error while loading {}", file.getAbsolutePath(), e);
try {
Properties prop = PropertyUtils.loadProperties(file);
for (Map.Entry<Object, Object> eachEntry : prop.entrySet()) {
map.put(
new LocaleAndCode(each, (String) eachEntry.getKey()),
new MessageFormat((String) eachEntry.getValue())
);
}
} catch (Exception e) {
LOGGER.error("Error while loading {}", file.getAbsolutePath(), e);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
import java.util.Set;
import java.util.concurrent.Callable;

import static org.apache.commons.lang.StringUtils.defaultIfBlank;
import static org.ngrinder.common.constant.CacheConstants.REGION_ATTR_KEY;
import static org.ngrinder.common.constant.CacheConstants.SUBREGION_ATTR_KEY;
import static org.ngrinder.common.util.RegionUtils.convertSubregionsStringToSet;
import static org.ngrinder.common.util.StringUtils.defaultIfBlank;

/**
* Task for getting region info from clustered controller.
Expand All @@ -28,7 +28,7 @@ public class RegionInfoTask implements Callable<RegionInfo>, Serializable {
private transient Config config;

public RegionInfo call() {
final String regionIP = defaultIfBlank(config.getCurrentIP(), NetworkUtils.getLocalHostAddress());
final String regionIP = defaultIfBlank(config.getCurrentIP(), NetworkUtils::getLocalHostAddress);
Map<String, String> regionWithSubregion = config.getRegionWithSubregion();
Set<String> subregion = convertSubregionsStringToSet(regionWithSubregion.get(SUBREGION_ATTR_KEY));
return new RegionInfo(regionWithSubregion.get(REGION_ATTR_KEY), subregion, regionIP, config.getControllerPort());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.ngrinder.perftest.model.NullSingleConsole;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
Expand All @@ -36,10 +37,10 @@
import java.util.concurrent.TimeUnit;

import static net.grinder.util.NetworkUtils.getAvailablePorts;
import static org.apache.commons.lang.StringUtils.defaultIfEmpty;
import static org.ngrinder.common.constant.ControllerConstants.*;
import static org.ngrinder.common.util.ExceptionUtils.processException;
import static org.ngrinder.common.util.NoOp.noOp;
import static org.ngrinder.common.util.StringUtils.defaultIfBlank;

/**
* Console manager is responsible for console instance management.
Expand All @@ -51,6 +52,7 @@
*
* @since 3.0
*/
@Profile("production")
@Component
@RequiredArgsConstructor
public class ConsoleManager {
Expand All @@ -72,7 +74,7 @@ public class ConsoleManager {
public void init() {
int consoleSize = getConsoleSize();
consoleQueue = new ArrayBlockingQueue<>(consoleSize);
final String currentIP = defaultIfEmpty(config.getCurrentIP(), NetworkUtils.getLocalHostAddress());
final String currentIP = defaultIfBlank(config.getCurrentIP(), NetworkUtils::getLocalHostAddress);
for (int port : getAvailablePorts(currentIP, consoleSize, getConsolePortBase(), MAX_PORT_NUMBER)) {
final ConsoleEntry consoleEntry = new ConsoleEntry(currentIP, port);
try {
Expand Down Expand Up @@ -150,7 +152,7 @@ public SingleConsole getAvailableConsole(ConsoleProperties baseConsoleProperties
consoleCommunicationSetting.setInactiveClientTimeOut(config.getInactiveClientTimeOut());
}
SingleConsole singleConsole = new SingleConsole(config.getCurrentIP(), consoleEntry.getPort(),
consoleCommunicationSetting, baseConsoleProperties);
consoleCommunicationSetting, baseConsoleProperties);
getConsoleInUse().add(singleConsole);
singleConsole.setCsvSeparator(config.getCsvSeparator());
return singleConsole;
Expand Down Expand Up @@ -180,7 +182,7 @@ public void returnBackConsole(String testIdentifier, SingleConsole console) {
console.sendStopMessageToAgents();
} catch (Exception e) {
LOG.error("Exception occurred during console return back for test {}.",
testIdentifier, e);
testIdentifier, e);
// But the port is getting back.
} finally {
// This is very careful implementation..
Expand All @@ -189,15 +191,15 @@ public void returnBackConsole(String testIdentifier, SingleConsole console) {
console.waitUntilAllAgentDisconnected();
} catch (Exception e) {
LOG.error("Exception occurred during console return back for test {}.",
testIdentifier, e);
testIdentifier, e);
// If it's not disconnected still, stop them by force.
agentManager.stopAgent(console.getConsolePort());
}
try {
console.shutdown();
} catch (Exception e) {
LOG.error("Exception occurred during console return back for test {}.",
testIdentifier, e);
testIdentifier, e);
}
int consolePort;
String consoleIP;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import static org.ngrinder.common.constant.CacheConstants.*;
import static org.ngrinder.common.util.ExceptionUtils.processException;
import static org.ngrinder.common.util.RegionUtils.convertSubregionsStringToSet;
import static org.ngrinder.common.util.StringUtils.defaultIfBlank;

/**
* Region service class. This class responsible to keep the status of available regions.
Expand All @@ -66,7 +67,7 @@ public Map<String, RegionInfo> get() {
regions.put(regionInfo.getRegionName(), regionInfo);
}
} else {
final String regionIP = StringUtils.defaultIfBlank(config.getCurrentIP(), NetworkUtils.getLocalHostAddress());
final String regionIP = defaultIfBlank(config.getCurrentIP(), NetworkUtils::getLocalHostAddress);
regions.put(config.getRegion(), new RegionInfo(config.getRegion(), emptySet(), regionIP, config.getControllerPort()));
}
return regions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.apache.commons.lang.StringUtils;
import org.ngrinder.common.exception.NGrinderRuntimeException;
import org.ngrinder.common.model.Home;
import org.ngrinder.common.util.EncodingUtils;
import org.ngrinder.common.util.PropertyUtils;
import org.ngrinder.infra.config.Config;
import org.ngrinder.model.User;
import org.ngrinder.script.model.FileCategory;
Expand Down Expand Up @@ -239,8 +239,8 @@ public FileEntry findOne(User user, String path, SVNRevision revision) {
}
script.setFileType(FileType.getFileTypeByExtension(FilenameUtils.getExtension(script.getFileName())));
if (script.getFileType().isEditable()) {
String autoDetectedEncoding = EncodingUtils.detectEncoding(byteArray, "UTF-8");
script.setContent((new String(byteArray, autoDetectedEncoding)).replaceAll("&quot;","\""));
String autoDetectedEncoding = PropertyUtils.detectEncoding(byteArray, "UTF-8");
script.setContent((new String(byteArray, autoDetectedEncoding)).replaceAll("&quot;", "\""));
script.setEncoding(autoDetectedEncoding);
}
script.setContentBytes(byteArray);
Expand Down
Loading

0 comments on commit 9959953

Please sign in to comment.