This is an automated email from the ASF dual-hosted git repository. ghenzler pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/felix-dev.git
commit 28fc43b766216cfacda5460e0151bc780801a136 Author: georg.henzler <georg.henz...@netcentric.biz> AuthorDate: Tue Jun 30 11:21:33 2020 +0200 FELIX-6246 Remove dependency to commons lang --- healthcheck/core/pom.xml | 23 ++---- .../core/impl/JmxAdjustableStatusHealthCheck.java | 8 +- .../impl/executor/HealthCheckExecutorImpl.java | 10 +-- .../hc/core/impl/executor/HealthCheckFuture.java | 90 +++++++++++++--------- .../executor/async/AsyncHealthCheckExecutor.java | 5 +- .../AdhocResultDuringRequestProcessingFilter.java | 2 +- .../core/impl/filter/ServiceUnavailableFilter.java | 4 +- .../hc/core/impl/monitor/HealthCheckMonitor.java | 4 +- .../impl/servlet/HealthCheckExecutorServlet.java | 52 ++++++------- .../hc/core/impl/servlet/ResultHtmlSerializer.java | 41 +++++++--- .../hc/core/impl/servlet/ResultJsonSerializer.java | 2 +- .../impl/servlet/ResultTxtVerboseSerializer.java | 50 +++++++++--- .../felix/hc/core/impl/util/lang/StringUtils.java | 52 +++++++++++++ .../felix/hc/jmx/impl/HealthCheckMBeanCreator.java | 2 +- .../servlet/HealthCheckExecutorServletTest.java | 6 +- .../servlet/ResultTxtVerboseSerializerTest.java | 39 ++++++++++ .../felix/hc/core/impl/util/StringUtilsTest.java | 46 +++++++++++ .../test/java/org/apache/felix/hc/core/it/U.java | 1 - healthcheck/generalchecks/bnd.bnd | 2 +- healthcheck/generalchecks/pom.xml | 14 ++-- .../hc/generalchecks/BundlesStartedCheck.java | 2 +- .../felix/hc/generalchecks/DsComponentsCheck.java | 5 +- .../hc/generalchecks/FrameworkStartCheck.java | 2 +- .../felix/hc/generalchecks/HttpRequestsCheck.java | 32 +++++--- .../felix/hc/generalchecks/JmxAttributeCheck.java | 4 +- .../hc/generalchecks/ScriptedHealthCheck.java | 2 +- .../felix/hc/generalchecks/util/ScriptHelper.java | 2 +- .../util/SimpleConstraintChecker.java | 30 +++++--- healthcheck/webconsoleplugin/pom.xml | 13 +--- .../impl/HealthCheckWebconsolePlugin.java | 18 +++-- .../felix/hc/webconsole/impl/WebConsoleHelper.java | 16 ++-- 31 files changed, 390 insertions(+), 189 deletions(-) diff --git a/healthcheck/core/pom.xml b/healthcheck/core/pom.xml index 283cb73..08aabb3 100644 --- a/healthcheck/core/pom.xml +++ b/healthcheck/core/pom.xml @@ -157,27 +157,20 @@ </dependency> <dependency> - <groupId>org.apache.servicemix.bundles</groupId> - <artifactId>org.apache.servicemix.bundles.quartz</artifactId> - <version>2.3.0_2</version> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>3.1.0</version> <scope>provided</scope> - <!-- if not present in runtime, there is no support for async health checks --> + <!-- servlet api optional: only add configs for servlets/filters your setup includes the servlet runtime! --> <optional>true</optional> </dependency> <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - <version>3.4</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> - <version>3.1.0</version> + <groupId>org.apache.servicemix.bundles</groupId> + <artifactId>org.apache.servicemix.bundles.quartz</artifactId> + <version>2.3.0_2</version> <scope>provided</scope> - <!-- servlet api optional: only add configs for servlets/filters your setup includes the servlet runtime! --> + <!-- if not present in runtime, there is no support for async health checks --> <optional>true</optional> </dependency> diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/JmxAdjustableStatusHealthCheck.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/JmxAdjustableStatusHealthCheck.java index ed1c403..c9895e3 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/JmxAdjustableStatusHealthCheck.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/JmxAdjustableStatusHealthCheck.java @@ -34,8 +34,6 @@ import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.ReflectionException; - -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.Result.Status; @@ -136,7 +134,7 @@ public class JmxAdjustableStatusHealthCheck { public Object getAttribute(final String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { if (ATT_TAGS.equals(attribute)) { - return StringUtils.join(tags, ","); + return String.join(",", tags); } else if (ATT_STATUS.equals(attribute)) { return status.toString(); } else { @@ -212,9 +210,9 @@ public class JmxAdjustableStatusHealthCheck { status = newStatus.toString(); registerDynamicHealthCheck(newStatus, tags.toArray(new String[tags.size()])); - LOG.info("Activated JMX-adjustable Health Check with status "+newStatus+" and tags " + StringUtils.join(tags, ",")); + LOG.info("Activated JMX-adjustable Health Check with status "+newStatus+" and tags " + String.join(",", tags)); return "Added check with result "+newStatus; - + } @Override diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckExecutorImpl.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckExecutorImpl.java index 2c400e1..e0aa7f4 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckExecutorImpl.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckExecutorImpl.java @@ -38,8 +38,6 @@ import java.util.ListIterator; import java.util.Map; import java.util.Set; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.time.StopWatch; import org.apache.felix.hc.api.FormattingResultLog; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; @@ -174,7 +172,7 @@ public class HealthCheckExecutorImpl implements ExtendedHealthCheckExecutor, Ser public List<HealthCheckExecutionResult> execute(HealthCheckSelector selector, HealthCheckExecutionOptions options) { logger.debug("Starting executing checks for filter selector {} and execution options {}", selector, options); - if (ArrayUtils.isEmpty(selector.tags())) { + if (selector.tags() == null || selector.tags().length == 0) { logger.debug("Using default tags"); selector.withTags(defaultTags); } @@ -366,8 +364,8 @@ public class HealthCheckExecutorImpl implements ExtendedHealthCheckExecutor, Ser /** Wait for the futures until the timeout is reached */ private void waitForFuturesRespectingTimeout(final List<HealthCheckFuture> futuresForResultOfThisCall, HealthCheckExecutionOptions options) { - final StopWatch callExcutionTimeStopWatch = new StopWatch(); - callExcutionTimeStopWatch.start(); + + final long callExcutionStartTime = System.currentTimeMillis(); boolean allFuturesDone; long effectiveTimeout = this.timeoutInMs; @@ -392,7 +390,7 @@ public class HealthCheckExecutorImpl implements ExtendedHealthCheckExecutor, Ser for (final HealthCheckFuture healthCheckFuture : futuresForResultOfThisCall) { allFuturesDone &= healthCheckFuture.isDone(); } - } while (!allFuturesDone && callExcutionTimeStopWatch.getTime() < effectiveTimeout); + } while (!allFuturesDone && (System.currentTimeMillis() - callExcutionStartTime) < effectiveTimeout); } /** Collect the results from all futures diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckFuture.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckFuture.java index 937eec9..d86409a 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckFuture.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/HealthCheckFuture.java @@ -19,15 +19,13 @@ package org.apache.felix.hc.core.impl.executor; import static org.apache.felix.hc.api.FormattingResultLog.msHumanReadable; -import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.Date; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; -import org.apache.commons.lang3.reflect.FieldUtils; -import org.apache.commons.lang3.reflect.MethodUtils; -import org.apache.commons.lang3.time.StopWatch; import org.apache.felix.hc.api.FormattingResultLog; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; @@ -57,19 +55,18 @@ public class HealthCheckFuture extends FutureTask<ExecutionResult> { Thread.currentThread().setName("HealthCheck " + metadata.getTitle()); LOG.debug("Starting check {}", metadata); - final StopWatch stopWatch = new StopWatch(); - stopWatch.start(); + long startTime = System.currentTimeMillis(); Result resultFromHealthCheck = null; ExecutionResult executionResult = null; - Object healthCheck = bundleContext.getService(metadata.getServiceReference()); + Object healthCheckObject = bundleContext.getService(metadata.getServiceReference()); try { - if (healthCheck != null) { - if ((healthCheck instanceof HealthCheck)) { - resultFromHealthCheck = ((HealthCheck) healthCheck).execute(); - } else { - resultFromHealthCheck = executeLegacyHc(healthCheck); - } + if (healthCheckObject != null) { + HealthCheck healthCheck = healthCheckObject instanceof HealthCheck + ? (HealthCheck) healthCheckObject + : new LegacyHealthCheckWrapper(healthCheckObject); + resultFromHealthCheck = healthCheck.execute(); + } else { throw new IllegalStateException("Service cannot be retrieved - probably activate() failed or there are unsatisfied references"); } @@ -82,8 +79,7 @@ public class HealthCheckFuture extends FutureTask<ExecutionResult> { bundleContext.ungetService(metadata.getServiceReference()); // update result with information about this run - stopWatch.stop(); - long elapsedTime = stopWatch.getTime(); + long elapsedTime = (System.currentTimeMillis() - startTime); if (resultFromHealthCheck != null) { // wrap the result in an execution result executionResult = new ExecutionResult(metadata, resultFromHealthCheck, elapsedTime); @@ -115,31 +111,49 @@ public class HealthCheckFuture extends FutureTask<ExecutionResult> { return "[Future for " + this.metadata + ", createdTime=" + this.createdTime + "]"; } - @SuppressWarnings("rawtypes") - private static Result executeLegacyHc(Object healthCheck) { - - FormattingResultLog log = new FormattingResultLog(); - log.debug("Running legacy HC {}, please convert to new interface org.apache.felix.hc.api.HealthCheck!", - healthCheck.getClass().getName()); - try { - Object result = MethodUtils.invokeMethod(healthCheck, "execute"); - Object resultLog = FieldUtils.readField(result, "resultLog", true); - - List entries = (List) FieldUtils.readField(resultLog, "entries", true); - for (Object object : entries) { - String statusLegacy = String.valueOf(FieldUtils.readField(object, "status", true)); - String message = (String) FieldUtils.readField(object, "message", true); - Exception exception = (Exception) FieldUtils.readField(object, "exception", true); - if(statusLegacy.equals("DEBUG")) { - log.add(new ResultLog.Entry(message, true, exception)); - } else { - statusLegacy = statusLegacy.replace("INFO", "OK"); - log.add(new ResultLog.Entry(Result.Status.valueOf(statusLegacy), message, exception)); + private static class LegacyHealthCheckWrapper implements HealthCheck { + private final Object legacyHealthCheck; + private final FormattingResultLog log; + + public LegacyHealthCheckWrapper(Object legacyHealthCheck) { + this.legacyHealthCheck = legacyHealthCheck; + this.log = new FormattingResultLog(); + } + + @Override + @SuppressWarnings("rawtypes") + public Result execute() { + Class<?> hcClass = legacyHealthCheck.getClass(); + log.debug("Running legacy HC {}, please convert to new interface org.apache.felix.hc.api.HealthCheck!", + hcClass.getName()); + try { + Method executeMethod = hcClass.getMethod("execute"); + Object result = executeMethod.invoke(legacyHealthCheck); + Object resultLog = readPrivateField(result, "resultLog"); + + List<?> entries = (List) readPrivateField(resultLog, "entries"); + for (Object object : entries) { + String statusLegacy = String.valueOf(readPrivateField(object, "status")); + String message = (String) readPrivateField(object, "message"); + Exception exception = (Exception) readPrivateField(object, "exception"); + if(statusLegacy.equals("DEBUG")) { + log.add(new ResultLog.Entry(message, true, exception)); + } else { + statusLegacy = statusLegacy.replace("INFO", Result.Status.OK.name()); + log.add(new ResultLog.Entry(Result.Status.valueOf(statusLegacy), message, exception)); + } } + } catch (ReflectiveOperationException e) { + log.healthCheckError("Could call and convert Sling HC {} for Felix Runtime", hcClass.getName()); } - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - log.healthCheckError("Could call and convert Sling HC {} for Felix Runtime", healthCheck.getClass().getName()); + return new Result(log); + } + + private Object readPrivateField(Object target, String fieldName) throws ReflectiveOperationException { + Field field = target.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return field.get(target); } - return new Result(log); } + } diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/async/AsyncHealthCheckExecutor.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/async/AsyncHealthCheckExecutor.java index 11ff1e2..bf2f86b 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/async/AsyncHealthCheckExecutor.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/executor/async/AsyncHealthCheckExecutor.java @@ -27,7 +27,6 @@ import java.util.Set; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.execution.HealthCheckExecutionResult; @@ -38,12 +37,12 @@ import org.apache.felix.hc.core.impl.executor.HealthCheckExecutorThreadPool; import org.apache.felix.hc.core.impl.executor.HealthCheckFuture; import org.apache.felix.hc.core.impl.executor.HealthCheckFuture.Callback; import org.apache.felix.hc.core.impl.executor.HealthCheckResultCache; -import org.apache.felix.hc.core.impl.scheduling.AsyncQuartzCronJob; import org.apache.felix.hc.core.impl.scheduling.AsyncIntervalJob; import org.apache.felix.hc.core.impl.scheduling.AsyncJob; -import org.apache.felix.hc.core.impl.scheduling.QuartzCronScheduler; +import org.apache.felix.hc.core.impl.scheduling.AsyncQuartzCronJob; import org.apache.felix.hc.core.impl.scheduling.QuartzCronSchedulerProvider; import org.apache.felix.hc.core.impl.util.HealthCheckFilter; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceEvent; diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/AdhocResultDuringRequestProcessingFilter.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/AdhocResultDuringRequestProcessingFilter.java index e0a22a4..4184ff6 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/AdhocResultDuringRequestProcessingFilter.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/AdhocResultDuringRequestProcessingFilter.java @@ -32,7 +32,6 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.execution.HealthCheckExecutionOptions; @@ -42,6 +41,7 @@ import org.apache.felix.hc.api.execution.HealthCheckSelector; import org.apache.felix.hc.core.impl.executor.CombinedExecutionResult; import org.apache.felix.hc.core.impl.servlet.ResultTxtVerboseSerializer; import org.apache.felix.hc.core.impl.util.AdhocStatusHealthCheck; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.component.ComponentContext; diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/ServiceUnavailableFilter.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/ServiceUnavailableFilter.java index 977dc3d..7d7161c 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/ServiceUnavailableFilter.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/filter/ServiceUnavailableFilter.java @@ -40,7 +40,6 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.execution.HealthCheckExecutionOptions; @@ -49,6 +48,7 @@ import org.apache.felix.hc.api.execution.HealthCheckSelector; import org.apache.felix.hc.core.impl.executor.CombinedExecutionResult; import org.apache.felix.hc.core.impl.executor.ExtendedHealthCheckExecutor; import org.apache.felix.hc.core.impl.servlet.ResultTxtVerboseSerializer; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleEvent; @@ -189,7 +189,7 @@ public class ServiceUnavailableFilter implements Filter { if(StringUtils.isBlank(responseFor503)) { responseFor503 = (String) compProperties.get("htmlFor503"); // backwards-compatibility } - if(StringUtils.startsWith(responseFor503, CLASSPATH_PREFIX)) { + if(responseFor503 != null && responseFor503.startsWith(CLASSPATH_PREFIX)) { String[] bits = responseFor503.split(":"); String symbolicName = bits[1]; String pathInBundle = bits[2]; diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/monitor/HealthCheckMonitor.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/monitor/HealthCheckMonitor.java index f687d68..36ce295 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/monitor/HealthCheckMonitor.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/monitor/HealthCheckMonitor.java @@ -27,7 +27,6 @@ import java.util.Hashtable; import java.util.List; import java.util.Map; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.condition.Healthy; import org.apache.felix.hc.api.condition.SystemReady; @@ -41,6 +40,7 @@ import org.apache.felix.hc.core.impl.scheduling.AsyncIntervalJob; import org.apache.felix.hc.core.impl.scheduling.AsyncJob; import org.apache.felix.hc.core.impl.scheduling.AsyncQuartzCronJob; import org.apache.felix.hc.core.impl.scheduling.QuartzCronSchedulerProvider; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceRegistration; @@ -288,7 +288,7 @@ public class HealthCheckMonitor implements Runnable { registrationProps.put(propertyName, tagOrName); registrationProps.put("activated", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); - if (StringUtils.equals(tagOrName, TAG_SYSTEMREADY)) { + if (TAG_SYSTEMREADY.equals(tagOrName)) { LOG.debug("HealthCheckMonitor: SYSTEM READY"); healthyRegistration = bundleContext.registerService( new String[] { SystemReady.class.getName(), Healthy.class.getName() }, diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java index 73a3285..b5abc76 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java @@ -31,14 +31,13 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang3.StringEscapeUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.execution.HealthCheckExecutionOptions; import org.apache.felix.hc.api.execution.HealthCheckExecutionResult; import org.apache.felix.hc.api.execution.HealthCheckExecutor; import org.apache.felix.hc.api.execution.HealthCheckSelector; import org.apache.felix.hc.core.impl.executor.CombinedExecutionResult; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.service.component.ComponentContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @@ -226,11 +225,10 @@ public class HealthCheckExecutorServlet extends HttpServlet { this.servletPaths = null; } - protected void doGet(final HttpServletRequest request, final HttpServletResponse response, final String format) + protected void doGet(final HttpServletRequest request, final HttpServletResponse response, String pathTokensStr, String format) throws ServletException, IOException { HealthCheckSelector selector = HealthCheckSelector.empty(); - String pathInfo = request.getPathInfo(); - String pathTokensStr = StringUtils.removeStart(splitFormat(pathInfo)[0], "/"); + List<String> tags = new ArrayList<String>(); List<String> names = new ArrayList<String>(); @@ -255,7 +253,7 @@ public class HealthCheckExecutorServlet extends HttpServlet { if (names.size() == 0) { // if not provided via path use parameter or default - names = Arrays.asList(StringUtils.defaultIfEmpty(request.getParameter(PARAM_NAMES.name), "").split(PARAM_SPLIT_REGEX)); + names = Arrays.asList(StringUtils.defaultIfBlank(request.getParameter(PARAM_NAMES.name), "").split(PARAM_SPLIT_REGEX)); } selector.withNames(names.toArray(new String[0])); @@ -272,7 +270,7 @@ public class HealthCheckExecutorServlet extends HttpServlet { executionOptions.setForceInstantExecution(Boolean.valueOf(request.getParameter(PARAM_FORCE_INSTANT_EXECUTION.name))); String overrideGlobalTimeoutVal = request.getParameter(PARAM_OVERRIDE_GLOBAL_TIMEOUT.name); - if (StringUtils.isNumeric(overrideGlobalTimeoutVal)) { + if (StringUtils.isNotBlank(overrideGlobalTimeoutVal)) { executionOptions.setOverrideGlobalTimeout(Integer.valueOf(overrideGlobalTimeoutVal)); } else if(servletDefaultTimeout > -1) { executionOptions.setOverrideGlobalTimeout((int) servletDefaultTimeout); @@ -295,10 +293,10 @@ public class HealthCheckExecutorServlet extends HttpServlet { } else if (FORMAT_JSON.equals(format)) { sendJsonResponse(overallResult, executionResults, null, response, includeDebug); } else if (FORMAT_JSONP.equals(format)) { - String jsonpCallback = StringUtils.defaultIfEmpty(request.getParameter(PARAM_JSONP_CALLBACK.name), JSONP_CALLBACK_DEFAULT); + String jsonpCallback = StringUtils.defaultIfBlank(request.getParameter(PARAM_JSONP_CALLBACK.name), JSONP_CALLBACK_DEFAULT); sendJsonResponse(overallResult, executionResults, jsonpCallback, response, includeDebug); - } else if (StringUtils.endsWith(format, FORMAT_TXT)) { - sendTxtResponse(overallResult, response, StringUtils.equals(format, FORMAT_VERBOSE_TXT), executionResults, includeDebug); + } else if (format != null && format.endsWith(FORMAT_TXT)) { + sendTxtResponse(overallResult, response, FORMAT_VERBOSE_TXT.equals(format), executionResults, includeDebug); } else { response.setContentType("text/plain"); response.getWriter().println("Invalid format " + format + " - supported formats: html|json|jsonp|txt|verbose.txt"); @@ -308,19 +306,26 @@ public class HealthCheckExecutorServlet extends HttpServlet { @Override protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { String pathInfo = request.getPathInfo(); - String format = splitFormat(pathInfo)[1]; + String[] splitPathInfo = splitFormat(pathInfo); + String format = splitPathInfo[1]; if (StringUtils.isBlank(format)) { // if not provided via extension use parameter or default - format = StringUtils.defaultIfEmpty(request.getParameter(PARAM_FORMAT.name), defaultFormat); + format = StringUtils.defaultIfBlank(request.getParameter(PARAM_FORMAT.name), defaultFormat); + } + + String pathTokensStr = splitPathInfo[0]; + if(pathTokensStr!=null && pathTokensStr.startsWith("/")) { + pathTokensStr = pathTokensStr.substring(1, pathTokensStr.length()); } - doGet(request, response, format); + + doGet(request, response, pathTokensStr, format); } - private String[] splitFormat(String pathInfo) { + String[] splitFormat(String pathInfo) { for (String format : new String[] { FORMAT_HTML, FORMAT_JSON, FORMAT_JSONP, FORMAT_VERBOSE_TXT, FORMAT_TXT }) { String formatWithDot = "." + format; - if (StringUtils.endsWith(pathInfo, formatWithDot)) { - return new String[] { StringUtils.substringBeforeLast(pathInfo, formatWithDot), format }; + if (pathInfo != null && pathInfo.endsWith(formatWithDot)) { + return new String[] { pathInfo.substring(0, pathInfo.length() - formatWithDot.length()), format }; } } return new String[] { pathInfo, null }; @@ -358,7 +363,7 @@ public class HealthCheckExecutorServlet extends HttpServlet { throws IOException { response.setContentType(CONTENT_TYPE_HTML); response.setCharacterEncoding("UTF-8"); - response.getWriter().append(this.htmlSerializer.serialize(overallResult, executionResults, getHtmlHelpText(), includeDebug)); + response.getWriter().append(this.htmlSerializer.serialize(overallResult, executionResults, Arrays.asList(PARAM_LIST), includeDebug)); } private void sendNoCacheHeaders(final HttpServletResponse response) { @@ -371,17 +376,6 @@ public class HealthCheckExecutorServlet extends HttpServlet { } } - private String getHtmlHelpText() { - final StringBuilder sb = new StringBuilder(); - sb.append("<h3>Supported URL parameters</h3>\n"); - for (Param p : PARAM_LIST) { - sb.append("<b>").append(p.name).append("</b>:"); - sb.append(StringEscapeUtils.escapeHtml4(p.description)); - sb.append("<br/>"); - } - return sb.toString(); - } - Map<Result.Status, Integer> getStatusMapping(String mappingStr) { Map<Result.Status, Integer> statusMapping = new TreeMap<Result.Status, Integer>(); @@ -424,7 +418,7 @@ public class HealthCheckExecutorServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - HealthCheckExecutorServlet.this.doGet(req, resp, format); + HealthCheckExecutorServlet.this.doGet(req, resp, "", format); } } diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultHtmlSerializer.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultHtmlSerializer.java index c315c8b..8b0477c 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultHtmlSerializer.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultHtmlSerializer.java @@ -27,11 +27,11 @@ import java.util.Calendar; import java.util.Date; import java.util.List; -import org.apache.commons.lang3.StringEscapeUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.ResultLog.Entry; import org.apache.felix.hc.api.execution.HealthCheckExecutionResult; +import org.apache.felix.hc.core.impl.servlet.HealthCheckExecutorServlet.Param; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @@ -46,7 +46,7 @@ public class ResultHtmlSerializer { this.styleString = configuration.styleString(); } - public String serialize(final Result overallResult, final List<HealthCheckExecutionResult> executionResults, String escapedHelpText, + public String serialize(final Result overallResult, final List<HealthCheckExecutionResult> executionResults, List<Param> paramList, boolean includeDebug) { StringWriter stringWriter = new StringWriter(); @@ -70,13 +70,13 @@ public class ResultHtmlSerializer { List<String> tags = executionResult.getHealthCheckMetadata().getTags(); boolean hasTags = tags != null && tags.size() > 0 && StringUtils.isNotBlank(tags.get(0)); writer.print("<tr class=\"" + getClassForStatus(result.getStatus()) + "\">"); - writer.print("<td><p title=\"" + StringEscapeUtils.escapeHtml4(executionResult.getHealthCheckMetadata().getName()) + "\">" - + StringEscapeUtils.escapeHtml4(executionResult.getHealthCheckMetadata().getTitle()) + ""); + writer.print("<td><p title=\"" + escapeHtml(executionResult.getHealthCheckMetadata().getName()) + "\">" + + escapeHtml(executionResult.getHealthCheckMetadata().getTitle()) + ""); if (hasTags) { - writer.println("<br/><span style='color:gray'>" + StringEscapeUtils.escapeHtml4(StringUtils.join(tags, ", ")) + "</span>"); + writer.println("<br/><span style='color:gray'>" + escapeHtml(String.join(", ", tags)) + "</span>"); } writer.println("</p></td>"); - writer.println("<td style='font-weight:bold;'>" + StringEscapeUtils.escapeHtml4(result.getStatus().toString()) + "</td>"); + writer.println("<td style='font-weight:bold;'>" + escapeHtml(result.getStatus().toString()) + "</td>"); writer.println("<td>"); boolean isFirst = true; @@ -95,15 +95,15 @@ public class ResultHtmlSerializer { boolean showStatus = !isSingleResult && !entry.isDebug() && entry.getStatus() != Result.Status.OK; - String message = StringEscapeUtils.escapeHtml4(entry.getMessage()); + String message = escapeHtml(entry.getMessage()); if (entry.isDebug()) { message = "<span style='color:gray'/>" + message + "</span>"; } - writer.println((showStatus ? StringEscapeUtils.escapeHtml4(entry.getStatus().toString()) + " " : "") + message); + writer.println((showStatus ? escapeHtml(entry.getStatus().toString()) + " " : "") + message); Exception exception = entry.getException(); if (exception != null) { - writer.println("<span style='width:20px'/>" + StringEscapeUtils.escapeHtml4(exception.toString())); + writer.println("<span style='width:20px'/>" + escapeHtml(exception.toString())); writer.println("<!--"); exception.printStackTrace(writer); writer.println("-->"); @@ -119,7 +119,7 @@ public class ResultHtmlSerializer { writer.println("</table>"); writer.println("<div class='helpText'>"); - writer.println(escapedHelpText); + writer.println(getHtmlHelpText(paramList)); writer.println("</div>"); writer.println("</body></html>"); @@ -151,4 +151,23 @@ public class ResultHtmlSerializer { return isToday; } + + private String getHtmlHelpText(List<Param> paramList) { + final StringBuilder sb = new StringBuilder(); + sb.append("<h3>Supported URL parameters</h3>\n"); + for (Param p : paramList) { + sb.append("<b>").append(p.name).append("</b>:"); + sb.append(escapeHtml(p.description)); + sb.append("<br/>"); + } + return sb.toString(); + } + + private String escapeHtml(String text) { + return text + .replace("&", "&") + .replace("\"", """) + .replace("<", "<") + .replace(">", ">"); + } } diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultJsonSerializer.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultJsonSerializer.java index c373d66..61eefe9 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultJsonSerializer.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultJsonSerializer.java @@ -23,10 +23,10 @@ import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.ResultLog; import org.apache.felix.hc.api.execution.HealthCheckExecutionResult; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.apache.felix.utils.json.JSONWriter; import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializer.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializer.java index 9d20a4b..8192636 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializer.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializer.java @@ -23,11 +23,10 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.List; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.text.WordUtils; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.ResultLog; import org.apache.felix.hc.api.execution.HealthCheckExecutionResult; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; @@ -70,11 +69,11 @@ public class ResultTxtVerboseSerializer { StringBuilder resultStr = new StringBuilder(); resultStr.append(StringUtils.repeat("-", totalWidth) + NEWLINE); - resultStr.append(StringUtils.center("Overall Health Result: " + overallResult.getStatus().toString(), totalWidth) + NEWLINE); + resultStr.append(center("Overall Health Result: " + overallResult.getStatus().toString(), totalWidth) + NEWLINE); resultStr.append(StringUtils.repeat("-", totalWidth) + NEWLINE); - resultStr.append(StringUtils.rightPad("Name", colWidthName)); - resultStr.append(StringUtils.rightPad("Result", colWidthResult)); - resultStr.append(StringUtils.rightPad("Timing", colWidthTiming)); + resultStr.append(rightPad("Name", colWidthName)); + resultStr.append(rightPad("Result", colWidthResult)); + resultStr.append(rightPad("Timing", colWidthTiming)); resultStr.append("Logs" + NEWLINE); resultStr.append(StringUtils.repeat("-", totalWidth) + NEWLINE); @@ -92,15 +91,15 @@ public class ResultTxtVerboseSerializer { private void appendVerboseTxtForResult(StringBuilder resultStr, HealthCheckExecutionResult healthCheckResult, boolean includeDebug, DateFormat dfShort) { - String wrappedName = WordUtils.wrap(healthCheckResult.getHealthCheckMetadata().getTitle(), colWidthName); + String wrappedName = wordWrap(healthCheckResult.getHealthCheckMetadata().getTitle(), colWidthName, "\n"); - String relevantNameStringForPadding = StringUtils.contains(wrappedName, "\n") ? StringUtils.substringAfterLast(wrappedName, "\n") - : wrappedName; + int lastIndexOfNewline = wrappedName.lastIndexOf("\n"); + String relevantNameStringForPadding = lastIndexOfNewline >= 0 ? wrappedName.substring(lastIndexOfNewline+1) : wrappedName; int paddingSize = colWidthName - relevantNameStringForPadding.length(); resultStr.append(wrappedName + StringUtils.repeat(" ", paddingSize)); - resultStr.append(StringUtils.rightPad(healthCheckResult.getHealthCheckResult().getStatus().toString(), colWidthResult)); - resultStr.append(StringUtils.rightPad("[" + dfShort.format(healthCheckResult.getFinishedAt()) + resultStr.append(rightPad(healthCheckResult.getHealthCheckResult().getStatus().toString(), colWidthResult)); + resultStr.append(rightPad("[" + dfShort.format(healthCheckResult.getFinishedAt()) + "|" + msHumanReadable(healthCheckResult.getElapsedTimeInMs()) + "]", colWidthTiming)); boolean isFirst = true; @@ -115,7 +114,7 @@ public class ResultTxtVerboseSerializer { } String oneLineMessage = getStatusForTxtLog(logEntry) + logEntry.getMessage(); - String messageToPrint = WordUtils.wrap(oneLineMessage, colWidthLog, "\n" + StringUtils.repeat(" ", colWidthWithoutLog), true); + String messageToPrint = wordWrap(oneLineMessage, colWidthLog, "\n" + StringUtils.repeat(" ", colWidthWithoutLog)); resultStr.append(messageToPrint); resultStr.append(NEWLINE); @@ -136,4 +135,31 @@ public class ResultTxtVerboseSerializer { } } + // -- Some simple helpers directly here as commons lang is removed + + String wordWrap(String s, int maxWidth, String newlineDelimiter) { + return s.replaceAll("(.{1,"+maxWidth+"})(?: +|$)\\n?|(.{"+maxWidth+"})", "$1$2"+newlineDelimiter).trim(); + } + + static String rightPad(String s, int size) { + if(s.length() < size) { + return s + StringUtils.repeat(" ", size - s.length()); + } else { + return s; + } + } + + static String center(String s, int size) { + if(s.length() < size) { + int padding = size - s.length(); + int paddingLeft = padding / 2; + int paddingRight = padding / 2; + if(padding % 2 == 1) { + paddingRight++; + } + return StringUtils.repeat(" ", paddingLeft) + s + StringUtils.repeat(" ", paddingRight); + } else { + return s; + } + } } diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/util/lang/StringUtils.java b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/util/lang/StringUtils.java new file mode 100644 index 0000000..2cb0e46 --- /dev/null +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/util/lang/StringUtils.java @@ -0,0 +1,52 @@ +/* + * 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 SF 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.felix.hc.core.impl.util.lang; + +/** Simple class for commons lang replacement where Java 8 does not provide replacements. + * + * Java 11 will allow to use String.isBlank() and String.repeat(), then this class can + * be removed. + * + * HINT: This class is also used in generalchecks via Conditional-Package */ +public class StringUtils { + + public static boolean isBlank(final CharSequence cs) { + return cs == null || cs.chars().allMatch(Character::isWhitespace); + } + + public static boolean isNotBlank(final CharSequence cs) { + return !isBlank(cs); + } + + public static String defaultIfBlank(final String cs, String defaultStr) { + return isBlank(cs) ? defaultStr : cs; + } + + public static String repeat(String s, int n) { + if(s == null) { + return null; + } + final StringBuilder sb = new StringBuilder(s.length() * n); + for(int i = 0; i < n; i++) { + sb.append(s); + } + return sb.toString(); + } + + +} diff --git a/healthcheck/core/src/main/java/org/apache/felix/hc/jmx/impl/HealthCheckMBeanCreator.java b/healthcheck/core/src/main/java/org/apache/felix/hc/jmx/impl/HealthCheckMBeanCreator.java index 248971b..38c3b25 100644 --- a/healthcheck/core/src/main/java/org/apache/felix/hc/jmx/impl/HealthCheckMBeanCreator.java +++ b/healthcheck/core/src/main/java/org/apache/felix/hc/jmx/impl/HealthCheckMBeanCreator.java @@ -27,10 +27,10 @@ import java.util.Map; import javax.management.DynamicMBean; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.core.impl.executor.ExtendedHealthCheckExecutor; import org.apache.felix.hc.core.impl.util.HealthCheckFilter; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.Filter; import org.osgi.framework.InvalidSyntaxException; diff --git a/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java index 979dae9..0a320ff 100644 --- a/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java +++ b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java @@ -19,9 +19,7 @@ package org.apache.felix.hc.core.impl.servlet; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; @@ -122,7 +120,7 @@ public class HealthCheckExecutorServletTest { verifyNoInteractions(verboseTxtSerializer); verify(htmlSerializer) .serialize(resultEquals(new Result(Result.Status.CRITICAL, "Overall Status CRITICAL")), eq(executionResults), - contains("Supported URL parameters"), eq(false)); + any(List.class), eq(false)); } @Test @@ -146,7 +144,7 @@ public class HealthCheckExecutorServletTest { verifyNoInteractions(verboseTxtSerializer); verify(htmlSerializer) .serialize(resultEquals(new Result(Result.Status.CRITICAL, "Overall Status CRITICAL")), eq(executionResults), - contains("Supported URL parameters"), eq(false)); + any(List.class), eq(false)); } @Test diff --git a/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializerTest.java b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializerTest.java new file mode 100644 index 0000000..9b27418 --- /dev/null +++ b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/ResultTxtVerboseSerializerTest.java @@ -0,0 +1,39 @@ +/* + * 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 SF 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.felix.hc.core.impl.servlet; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class ResultTxtVerboseSerializerTest { + + ResultTxtVerboseSerializer resultTxtVerboseSerializer = new ResultTxtVerboseSerializer(); + @Test + public void testWordWrap() { + String exampleText = "word1 word2 word3 word4 word5 word6 word7 word8 word9 word10"; + + assertEquals("word1 word2 word3\nword4 word5 word6\nword7 word8 word9\nword10", resultTxtVerboseSerializer.wordWrap(exampleText, 20, "\n")); + assertEquals("word1 word2 word3 word4 word5 word6\nword7 word8 word9 word10", resultTxtVerboseSerializer.wordWrap(exampleText, 40, "\n")); + + String longText = "Disk Usage /very/long/path/to/some/location/on/disk/somewhere/.: 88.6% of 465.6GB used / 53.1GB free"; + assertEquals("Disk Usage\n/very/long/path/to/some/locati\non/on/disk/somewhere/.: 88.6%\nof 465.6GB used / 53.1GB free", resultTxtVerboseSerializer.wordWrap(longText, 30, "\n")); + + } + +} diff --git a/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/util/StringUtilsTest.java b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/util/StringUtilsTest.java new file mode 100644 index 0000000..2cc88a8 --- /dev/null +++ b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/util/StringUtilsTest.java @@ -0,0 +1,46 @@ +/* + * 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 SF 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.felix.hc.core.impl.util; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.apache.felix.hc.core.impl.util.lang.StringUtils; +import org.junit.Test; + +public class StringUtilsTest { + + @Test + public void testIsNotBlank() { + assertTrue(StringUtils.isNotBlank("test")); + assertTrue(StringUtils.isNotBlank("$")); + assertTrue(StringUtils.isNotBlank("123")); + assertFalse(StringUtils.isNotBlank(" ")); + assertFalse(StringUtils.isNotBlank("\t")); + } + + @Test + public void testIsBlank() { + assertFalse(StringUtils.isBlank("test")); + assertFalse(StringUtils.isBlank("$")); + assertFalse(StringUtils.isBlank("123")); + assertTrue(StringUtils.isBlank(" ")); + assertTrue(StringUtils.isBlank("\t")); + } + +} diff --git a/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/U.java b/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/U.java index d9efb83..c42b6c1 100644 --- a/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/U.java +++ b/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/U.java @@ -82,7 +82,6 @@ public class U { mavenBundle("org.apache.felix", "org.apache.felix.eventadmin", "1.4.10"), mavenBundle("org.apache.felix", "org.apache.felix.healthcheck.api").versionAsInProject(), - mavenBundle().groupId("org.apache.commons").artifactId("commons-lang3").versionAsInProject(), mavenBundle("org.apache.felix", "org.apache.felix.http.servlet-api", "1.1.2"), mavenBundle("org.apache.felix", "org.apache.felix.http.jetty", "4.0.2"), diff --git a/healthcheck/generalchecks/bnd.bnd b/healthcheck/generalchecks/bnd.bnd index e37e4b6..e42dd06 100644 --- a/healthcheck/generalchecks/bnd.bnd +++ b/healthcheck/generalchecks/bnd.bnd @@ -8,7 +8,7 @@ Bundle-License: Apache License, Version 2.0 Bundle-Vendor: The Apache Software Foundation -Conditional-Package: org.apache.commons.cli.*,org.apache.felix.utils.* +Conditional-Package: org.apache.commons.cli.*,org.apache.felix.utils.*,org.apache.felix.hc.core.impl.util.lang.* Export-Package: org.apache.felix.hc.generalchecks.util diff --git a/healthcheck/generalchecks/pom.xml b/healthcheck/generalchecks/pom.xml index e7873f8..00c873e 100644 --- a/healthcheck/generalchecks/pom.xml +++ b/healthcheck/generalchecks/pom.xml @@ -167,13 +167,6 @@ <scope>provided</scope> </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - <version>3.4</version> - <scope>provided</scope> - </dependency> - <!-- START provided via ConditionalPackage --> <dependency> <groupId>commons-cli</groupId> @@ -187,6 +180,13 @@ <version>1.11.0</version> <scope>provided</scope> </dependency> + <!-- only to be able to use org.apache.felix.hc.core.impl.util.StringUtils for commons lang replacement --> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.healthcheck.core</artifactId> + <version>2.0.7-SNAPSHOT</version> + <scope>provided</scope> + </dependency> <!-- END provided via ConditionalPackage --> <!-- START test scope dependencies --> diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/BundlesStartedCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/BundlesStartedCheck.java index 1065852..60d6788 100644 --- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/BundlesStartedCheck.java +++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/BundlesStartedCheck.java @@ -19,11 +19,11 @@ package org.apache.felix.hc.generalchecks; import java.util.regex.Pattern; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.annotation.HealthCheckService; import org.apache.felix.hc.api.FormattingResultLog; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/DsComponentsCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/DsComponentsCheck.java index 3785b33..9fcbbd2 100644 --- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/DsComponentsCheck.java +++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/DsComponentsCheck.java @@ -24,19 +24,18 @@ import java.util.Collection; import java.util.LinkedList; import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.annotation.HealthCheckService; import org.apache.felix.hc.api.FormattingResultLog; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.ResultLog.Entry; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.apache.felix.hc.generalchecks.scrutil.DsRootCauseAnalyzer; import org.osgi.framework.BundleContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.ConfigurationPolicy; import org.osgi.service.component.annotations.Reference; -import org.osgi.service.component.annotations.ReferenceCardinality; import org.osgi.service.component.annotations.ReferencePolicyOption; import org.osgi.service.component.runtime.ServiceComponentRuntime; import org.osgi.service.component.runtime.dto.ComponentConfigurationDTO; @@ -128,7 +127,7 @@ public class DsComponentsCheck implements HealthCheck { foundActiveOrSatisfiedConfig = true; } } - log.debug(dsComp.name + " (" + StringUtils.join(idStateTuples, ",") + ")"); + log.debug(dsComp.name + " (" + String.join(",", idStateTuples) + ")"); if (componentConfigurationDTOs.isEmpty() || foundActiveOrSatisfiedConfig) { countEnabled++; diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/FrameworkStartCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/FrameworkStartCheck.java index 4618fd7..6f21eeb 100644 --- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/FrameworkStartCheck.java +++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/FrameworkStartCheck.java @@ -18,10 +18,10 @@ */ package org.apache.felix.hc.generalchecks; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.annotation.HealthCheckService; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/HttpRequestsCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/HttpRequestsCheck.java index 2dc682e..9729f56 100644 --- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/HttpRequestsCheck.java +++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/HttpRequestsCheck.java @@ -33,6 +33,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Base64; import java.util.HashMap; import java.util.List; @@ -48,12 +49,12 @@ import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.annotation.HealthCheckService; import org.apache.felix.hc.api.FormattingResultLog; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.ResultLog; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.apache.felix.hc.generalchecks.util.SimpleConstraintChecker; import org.apache.felix.utils.json.JSONParser; import org.osgi.framework.BundleContext; @@ -234,15 +235,15 @@ public class HttpRequestsCheck implements HealthCheck { String[] responseAssertionArr = responseAssertions.split(" +&& +"); for(String clause: responseAssertionArr) { - if(StringUtils.isNumeric(clause)) { + if(isNumeric(clause)) { responseChecks.add(new ResponseCodeCheck(Integer.parseInt(clause))); - } else if(StringUtils.startsWithIgnoreCase(clause, ResponseTimeCheck.TIME)) { + } else if(clause.toUpperCase().startsWith(ResponseTimeCheck.TIME)) { responseChecks.add(new ResponseTimeCheck(clause.substring(ResponseTimeCheck.TIME.length()))); - } else if(StringUtils.startsWithIgnoreCase(clause, ResponseEntityRegExCheck.MATCHES)) { + } else if(clause.toUpperCase().startsWith(ResponseEntityRegExCheck.MATCHES)) { responseChecks.add(new ResponseEntityRegExCheck(Pattern.compile(clause.substring(ResponseEntityRegExCheck.MATCHES.length())))); - } else if(StringUtils.startsWithIgnoreCase(clause, ResponseHeaderCheck.HEADER)) { + } else if(clause.toUpperCase().startsWith(ResponseHeaderCheck.HEADER)) { responseChecks.add(new ResponseHeaderCheck(clause.substring(ResponseHeaderCheck.HEADER.length()))); - } else if(StringUtils.startsWithIgnoreCase(clause, JsonPropertyCheck.JSON)) { + } else if(clause.toUpperCase().startsWith(JsonPropertyCheck.JSON)) { responseChecks.add(new JsonPropertyCheck(clause.substring(JsonPropertyCheck.JSON.length()))); } else { throw new IllegalArgumentException("Invalid response content assertion clause: '"+clause+"'"); @@ -250,6 +251,15 @@ public class HttpRequestsCheck implements HealthCheck { } } + private boolean isNumeric(String text) { + try { + Integer.parseInt(text); + return true; + } catch(NumberFormatException e) { + return false; + } + } + private void parseCurlLikeRequestInfo(String requestInfo) throws ParseException, URISyntaxException { CommandLineParser parser = new DefaultParser(); @@ -356,7 +366,7 @@ public class HttpRequestsCheck implements HealthCheck { Result.Status status = hasFailed ? statusForFailedContraint : Result.Status.OK; String timing = showTiming ? " " + msHumanReadable(response.requestDurationInMs) : ""; // result of response assertion(s) - log.add(new ResultLog.Entry(status, urlWithUser+timing+": "+ StringUtils.join(resultBits,", "))); + log.add(new ResultLog.Entry(status, urlWithUser+timing+": "+ String.join(", ", resultBits))); } return log; @@ -601,13 +611,14 @@ public class HttpRequestsCheck implements HealthCheck { Object currentObject = null; for (int i=0; i < jsonPropertyPathBits.length; i++) { String jsonPropertyPathBit = jsonPropertyPathBits[i]; + String propPathForEx = StringUtils.defaultIfBlank(String.join("", Arrays.copyOfRange(jsonPropertyPathBits, 0, i)), "<root>"); if(jsonPropertyPathBit.startsWith("[")) { int arrayIndex = Integer.parseInt(jsonPropertyPathBit.substring(1,jsonPropertyPathBit.length()-1)); if(currentObject==null) { currentObject = jsonParser.getParsedList(); } if(!(currentObject instanceof List)) { - throw new IllegalArgumentException("Path '"+StringUtils.defaultIfEmpty(StringUtils.join(jsonPropertyPathBits, "", 0, i), "<root>")+"' is not a json list"); + throw new IllegalArgumentException("Path '"+propPathForEx+"' is not a json list"); } currentObject = ((List<?>) currentObject).get(arrayIndex); } else { @@ -616,12 +627,13 @@ public class HttpRequestsCheck implements HealthCheck { currentObject = jsonParser.getParsed(); } if(!(currentObject instanceof Map)) { - throw new IllegalArgumentException("Path '"+StringUtils.defaultIfEmpty(StringUtils.join(jsonPropertyPathBits, "", 0, i), "<root>")+"' is not a json object"); + throw new IllegalArgumentException("Path '"+propPathForEx+"' is not a json object"); } currentObject = ((Map<?,?>) currentObject).get(propertyName); } if(currentObject==null && /* not last */ i+1 < jsonPropertyPathBits.length) { - throw new IllegalArgumentException("Path "+StringUtils.join(jsonPropertyPathBits, "", 0, i+1)+" is null, cannot evaluate left-over part '"+StringUtils.join(jsonPropertyPathBits, "", i+1, jsonPropertyPathBits.length)+"'"); + String unevaluated = String.join("", Arrays.copyOfRange(jsonPropertyPathBits, i+1, jsonPropertyPathBits.length)); + throw new IllegalArgumentException("Path "+propPathForEx+" is null, cannot evaluate left-over part '"+unevaluated+"'"); } } return currentObject; diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/JmxAttributeCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/JmxAttributeCheck.java index 9fdf0bb..ba545bc 100644 --- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/JmxAttributeCheck.java +++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/JmxAttributeCheck.java @@ -25,11 +25,11 @@ import java.util.Map; import javax.management.MBeanServer; import javax.management.ObjectName; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.FormattingResultLog; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.ResultLog; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.apache.felix.hc.generalchecks.util.SimpleConstraintChecker; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @@ -176,7 +176,7 @@ public class JmxAttributeCheck implements HealthCheck { this.mbeanName = StringUtils.defaultIfBlank(mBeanName, defaultMBeanName); this.attributeName = (String) rawConfig.get(propNameAttribute); this.attributeValueConstraint = (String) rawConfig.get(PROP_ATTRIBUTE + attributeCounter + SUFFIX_VALUE_CONSTRAINT); - if(StringUtils.isAnyBlank(mbeanName, attributeName, attributeValueConstraint)) { + if(StringUtils.isBlank(mbeanName) || StringUtils.isBlank(attributeName) || StringUtils.isBlank(attributeValueConstraint)) { throw new IllegalArgumentException("Invalid JmxAttributeCheck config for property "+mbeanName+" -> "+propNameAttribute+": "+toString()); } } diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java index bb83f1e..49a7bb6 100644 --- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java +++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/ScriptedHealthCheck.java @@ -19,10 +19,10 @@ package org.apache.felix.hc.generalchecks; import javax.script.ScriptEngine; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.FormattingResultLog; import org.apache.felix.hc.api.HealthCheck; import org.apache.felix.hc.api.Result; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.apache.felix.hc.generalchecks.util.ScriptEnginesTracker; import org.apache.felix.hc.generalchecks.util.ScriptHelper; import org.osgi.framework.BundleContext; diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java index c6b8e7d..fc93558 100644 --- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java +++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/ScriptHelper.java @@ -39,10 +39,10 @@ import javax.script.ScriptException; import javax.script.SimpleBindings; import javax.script.SimpleScriptContext; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.FormattingResultLog; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.ResultLog; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; diff --git a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/SimpleConstraintChecker.java b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/SimpleConstraintChecker.java index 96eaa30..c531a89 100644 --- a/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/SimpleConstraintChecker.java +++ b/healthcheck/generalchecks/src/main/java/org/apache/felix/hc/generalchecks/util/SimpleConstraintChecker.java @@ -17,9 +17,10 @@ */ package org.apache.felix.hc.generalchecks.util; +import java.util.Arrays; import java.util.Calendar; -import org.apache.commons.lang3.StringUtils; +import org.apache.felix.hc.core.impl.util.lang.StringUtils; /** Simple check of values against expressions like < N, > N, between two values etc. See the SimpleConstraintCheckerTest for * examples. */ @@ -73,9 +74,9 @@ public class SimpleConstraintChecker { matches = value < Long.valueOf(parts[1]); } else if (parts[0].equals(EQUALS) && parts.length == 2) { - if(StringUtils.isNumeric(stringValue)) { - long value = Long.valueOf(stringValue).longValue(); - matches = value == Long.valueOf(parts[1]).longValue(); + Long longValue; + if((longValue = getLongObject(stringValue)) != null) { + matches = longValue.longValue() == Long.valueOf(parts[1]).longValue(); } else { matches = stringValue.equals(parts[1]); } @@ -86,16 +87,16 @@ public class SimpleConstraintChecker { matches = value > lowerBound && value < upperBound; } else if (parts.length > 1 && CONTAINS.equalsIgnoreCase(parts[0])) { - String pattern = StringUtils.join(parts, " ", 1, parts.length); + String pattern = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length)); matches = stringValue.contains(pattern); } else if (parts.length > 1 && STARTS_WITH.equalsIgnoreCase(parts[0])) { - String pattern = StringUtils.join(parts, " ", 1, parts.length); + String pattern = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length)); matches = stringValue.startsWith(pattern); } else if (parts.length > 1 && ENDS_WITH.equalsIgnoreCase(parts[0])) { - String pattern = StringUtils.join(parts, " ", 1, parts.length); + String pattern = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length)); matches = stringValue.endsWith(pattern); } else if (parts.length > 1 && MATCHES.equalsIgnoreCase(parts[0])) { - String pattern = StringUtils.join(parts, " ", 1, parts.length); + String pattern = String.join(" ", Arrays.copyOfRange(parts, 1, parts.length)); matches = stringValue.matches(pattern); } else if (parts.length > 1 && OLDER_THAN.equalsIgnoreCase(parts[0]) && parts.length == 3) { int unit = stringToUnit(parts[2]); @@ -109,7 +110,7 @@ public class SimpleConstraintChecker { matches = timestamp < compareTimestamp; } else { - matches = StringUtils.join(parts, "").equals(stringValue); + matches = String.join("", parts).equals(stringValue); } boolean result = matches ^ inverseResult; @@ -144,4 +145,15 @@ public class SimpleConstraintChecker { } return unit; } + + private static Long getLongObject(String strNum) { + if (strNum == null) { + return null; + } + try { + return Long.valueOf(strNum); + } catch (NumberFormatException nfe) { + return null; + } + } } \ No newline at end of file diff --git a/healthcheck/webconsoleplugin/pom.xml b/healthcheck/webconsoleplugin/pom.xml index a2dff58..cb152bf 100644 --- a/healthcheck/webconsoleplugin/pom.xml +++ b/healthcheck/webconsoleplugin/pom.xml @@ -36,7 +36,10 @@ <description> Plugin for the felix web console </description> - + + <properties> + <felix.java.version>8</felix.java.version> + </properties> <scm> <connection>scm:git:https://github.com/apache/felix-dev.git</connection> <developerConnection>scm:git:https://github.com/apache/felix-dev.git</developerConnection> @@ -103,14 +106,6 @@ <version>1.7.6</version> <scope>provided</scope> </dependency> - - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - <version>3.4</version> - <scope>provided</scope> - </dependency> - <!-- START test scope dependencies --> <dependency> diff --git a/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/HealthCheckWebconsolePlugin.java b/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/HealthCheckWebconsolePlugin.java index a858a29..46ff61e 100644 --- a/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/HealthCheckWebconsolePlugin.java +++ b/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/HealthCheckWebconsolePlugin.java @@ -17,7 +17,6 @@ */ package org.apache.felix.hc.webconsole.impl; -import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4; import static org.apache.felix.hc.api.FormattingResultLog.msHumanReadable; import java.io.IOException; @@ -33,7 +32,6 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang3.StringUtils; import org.apache.felix.hc.api.Result; import org.apache.felix.hc.api.ResultLog; import org.apache.felix.hc.api.execution.HealthCheckExecutionOptions; @@ -126,7 +124,7 @@ public class HealthCheckWebconsolePlugin extends HttpServlet { // override not set in UI } - HealthCheckSelector selector = StringUtils.isNotBlank(tags) ? HealthCheckSelector.tags(tags.split(",")) : HealthCheckSelector.empty(); + HealthCheckSelector selector = !isBlank(tags) ? HealthCheckSelector.tags(tags.split(",")) : HealthCheckSelector.empty(); Collection<HealthCheckExecutionResult> results = healthCheckExecutor.execute(selector, options); pw.println("<table class='content healthcheck' cellpadding='0' cellspacing='0' width='100%'>"); @@ -151,6 +149,10 @@ public class HealthCheckWebconsolePlugin extends HttpServlet { } } + + private static boolean isBlank(final CharSequence cs) { + return cs == null || cs.chars().allMatch(Character::isWhitespace); + } void renderResult(final PrintWriter pw, final HealthCheckExecutionResult exResult, final boolean debug) throws IOException { final Result result = exResult.getHealthCheckResult(); @@ -166,7 +168,7 @@ public class HealthCheckWebconsolePlugin extends HttpServlet { c.tr(); c.tdContent(); - c.writer().print(escapeHtml4(status.toString())); + c.writer().print(c.escapeHtml(status.toString())); c.writer().print("<br/>Result: <span class='resultOk"); c.writer().print(result.isOk()); c.writer().print("'>"); @@ -186,10 +188,10 @@ public class HealthCheckWebconsolePlugin extends HttpServlet { c.writer().print("'>"); c.writer().print(e.getStatus().toString()); c.writer().print(' '); - c.writer().print(escapeHtml4(e.getMessage())); + c.writer().print(c.escapeHtml(e.getMessage())); if (e.getException() != null) { c.writer().print(" "); - c.writer().print(escapeHtml4(e.getException().toString())); + c.writer().print(c.escapeHtml(e.getException().toString())); } c.writer().println("</div>"); } @@ -215,7 +217,7 @@ public class HealthCheckWebconsolePlugin extends HttpServlet { c.tdContent(); c.writer().print("<input type='text' name='" + PARAM_TAGS + "' value='"); if ( tags != null ) { - c.writer().print(escapeHtml4(tags)); + c.writer().print(c.escapeHtml(tags)); } c.writer().println("' class='input' size='80'>"); c.closeTd(); @@ -270,7 +272,7 @@ public class HealthCheckWebconsolePlugin extends HttpServlet { c.tdContent(); c.writer().print("<input type='text' name='" + PARAM_OVERRIDE_GLOBAL_TIMEOUT + "' value='"); if (overrideGlobalTimeoutStr != null) { - c.writer().print(escapeHtml4(overrideGlobalTimeoutStr)); + c.writer().print(c.escapeHtml(overrideGlobalTimeoutStr)); } c.writer().println("' class='input' size='80'>"); c.closeTd(); diff --git a/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/WebConsoleHelper.java b/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/WebConsoleHelper.java index 6ffeeeb..f3257bc 100644 --- a/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/WebConsoleHelper.java +++ b/healthcheck/webconsoleplugin/src/main/java/org/apache/felix/hc/webconsole/impl/WebConsoleHelper.java @@ -19,8 +19,6 @@ package org.apache.felix.hc.webconsole.impl; import java.io.PrintWriter; -import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4; - /** Webconsole plugin helper for writing html. */ class WebConsoleHelper { @@ -48,7 +46,7 @@ class WebConsoleHelper { void tdLabel(final String label) { pw.print("<td class='content'>"); - pw.print(escapeHtml4(label)); + pw.print(escapeHtml(label)); pw.println("</td>"); } @@ -59,16 +57,24 @@ class WebConsoleHelper { void titleHtml(String title, String description) { tr(); pw.print("<th colspan='3' class='content container'>"); - pw.print(escapeHtml4(title)); + pw.print(escapeHtml(title)); pw.println("</th>"); closeTr(); if (description != null) { tr(); pw.print("<td colspan='3' class='content'>"); - pw.print(escapeHtml4(description)); + pw.print(escapeHtml(description)); pw.println("</th>"); closeTr(); } } + + String escapeHtml(String text) { + return text + .replace("&", "&") + .replace("\"", """) + .replace("<", "<") + .replace(">", ">"); + } }