Author: ghenzler
Date: Fri Jan 4 11:04:17 2019
New Revision: 1850346
URL: http://svn.apache.org/viewvc?rev=1850346&view=rev
Log:
FELIX-6010 Allow multiple instances of HC servlets with configured presets for
timeout, tags, format
Modified:
felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java
felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletConfiguration.java
felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java
felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/HealthCheckServletIT.java
Modified:
felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java
URL:
http://svn.apache.org/viewvc/felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java?rev=1850346&r1=1850345&r2=1850346&view=diff
==============================================================================
---
felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java
(original)
+++
felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServlet.java
Fri Jan 4 11:04:17 2019
@@ -66,7 +66,7 @@ import org.slf4j.LoggerFactory;
* <p>
* Useful in combination with load balancers. */
@Component(configurationPolicy = ConfigurationPolicy.REQUIRE)
-@Designate(ocd = HealthCheckExecutorServletConfiguration.class)
+@Designate(ocd = HealthCheckExecutorServletConfiguration.class, factory=true)
public class HealthCheckExecutorServlet extends HttpServlet {
private static final long serialVersionUID = 8013511523994541848L;
@@ -135,6 +135,11 @@ public class HealthCheckExecutorServlet
private Map<Result.Status, Integer> defaultStatusMapping;
+ private long servletDefaultTimeout;
+ private String[] servletDefaultTags;
+ private String defaultFormat;
+ private boolean defaultCombineTagsWithOr;
+
@Reference
private HttpService httpService;
@@ -156,15 +161,29 @@ public class HealthCheckExecutorServlet
@Activate
protected final void activate(final
HealthCheckExecutorServletConfiguration configuration) {
this.servletPath = configuration.servletPath();
- this.disabled = configuration.disabled();
- this.corsAccessControlAllowOrigin =
configuration.cors_accessControlAllowOrigin();
- this.defaultStatusMapping =
getStatusMapping(configuration.httpStatusMapping());
-
LOG.info("servletPath={}", servletPath);
+
+ this.disabled = configuration.disabled();
LOG.info("disabled={}", disabled);
- LOG.info("corsAccessControlAllowOrigin={}",
corsAccessControlAllowOrigin);
+
+ this.defaultStatusMapping =
getStatusMapping(configuration.httpStatusMapping());
LOG.info("defaultStatusMapping={}", defaultStatusMapping);
+ this.servletDefaultTimeout = configuration.timeout();
+ LOG.info("servletDefaultTimeout={}", servletDefaultTimeout);
+
+ this.servletDefaultTags = configuration.tags();
+ LOG.info("servletDefaultTags={}", servletDefaultTags!=null ?
Arrays.asList(servletDefaultTags): "<none>");
+
+ this.defaultCombineTagsWithOr = configuration.combineTagsWithOr();
+ LOG.info("defaultCombineTagsWithOr={}", defaultCombineTagsWithOr);
+
+ this.defaultFormat = configuration.format();
+ LOG.info("defaultFormat={}", defaultFormat);
+
+ this.corsAccessControlAllowOrigin =
configuration.cors_accessControlAllowOrigin();
+ LOG.info("corsAccessControlAllowOrigin={}",
corsAccessControlAllowOrigin);
+
if (disabled) {
LOG.info("Health Check Servlet is disabled by configuration");
return;
@@ -228,8 +247,9 @@ public class HealthCheckExecutorServlet
}
}
if (tags.size() == 0) {
- // if not provided via path use parameter or default
- tags =
Arrays.asList(StringUtils.defaultIfEmpty(request.getParameter(PARAM_TAGS.name),
"").split(PARAM_SPLIT_REGEX));
+ // if not provided via path use parameter or configured default
+ String tagsParameter = request.getParameter(PARAM_TAGS.name);
+ tags = Arrays.asList(StringUtils.isNotBlank(tagsParameter) ?
tagsParameter.split(PARAM_SPLIT_REGEX): servletDefaultTags);
}
selector.withTags(tags.toArray(new String[0]));
@@ -245,12 +265,17 @@ public class HealthCheckExecutorServlet
final Map<Result.Status, Integer> statusMapping =
httpStatusMappingParameterVal!=null ?
getStatusMapping(httpStatusMappingParameterVal) : defaultStatusMapping;
HealthCheckExecutionOptions executionOptions = new
HealthCheckExecutionOptions();
- executionOptions.setCombineTagsWithOr(
-
Boolean.valueOf(StringUtils.defaultString(request.getParameter(PARAM_COMBINE_TAGS_WITH_OR.name),
"true")));
+
+ String paramCombineTagsWithOr =
request.getParameter(PARAM_COMBINE_TAGS_WITH_OR.name);
+ executionOptions.setCombineTagsWithOr( paramCombineTagsWithOr!=null ?
Boolean.valueOf(paramCombineTagsWithOr) : defaultCombineTagsWithOr);
+
executionOptions.setForceInstantExecution(Boolean.valueOf(request.getParameter(PARAM_FORCE_INSTANT_EXECUTION.name)));
+
String overrideGlobalTimeoutVal =
request.getParameter(PARAM_OVERRIDE_GLOBAL_TIMEOUT.name);
if (StringUtils.isNumeric(overrideGlobalTimeoutVal)) {
executionOptions.setOverrideGlobalTimeout(Integer.valueOf(overrideGlobalTimeoutVal));
+ } else if(servletDefaultTimeout > -1) {
+ executionOptions.setOverrideGlobalTimeout((int)
servletDefaultTimeout);
}
List<HealthCheckExecutionResult> executionResults =
this.healthCheckExecutor.execute(selector, executionOptions);
@@ -291,7 +316,7 @@ public class HealthCheckExecutorServlet
String format = splitFormat(pathInfo)[1];
if (StringUtils.isBlank(format)) {
// if not provided via extension use parameter or default
- format =
StringUtils.defaultIfEmpty(request.getParameter(PARAM_FORMAT.name),
FORMAT_HTML);
+ format =
StringUtils.defaultIfEmpty(request.getParameter(PARAM_FORMAT.name),
defaultFormat);
}
doGet(request, response, format);
}
Modified:
felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletConfiguration.java
URL:
http://svn.apache.org/viewvc/felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletConfiguration.java?rev=1850346&r1=1850345&r2=1850346&view=diff
==============================================================================
---
felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletConfiguration.java
(original)
+++
felix/trunk/healthcheck/core/src/main/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletConfiguration.java
Fri Jan 4 11:04:17 2019
@@ -25,16 +25,32 @@ import org.osgi.service.metatype.annotat
String SERVLET_PATH_DEFAULT = "/system/health";
- @AttributeDefinition(name = "Disabled", description = "Allows to disable
the servlet if required for security reasons")
- boolean disabled() default false;
-
@AttributeDefinition(name = "Path", description = "Servlet path (defaults
to " + SERVLET_PATH_DEFAULT
+ " in order to not be accessible via Apache/Internet)")
String servletPath() default SERVLET_PATH_DEFAULT;
+ @AttributeDefinition(name = "Http Status Mapping", description = "Maps HC
result status values to http response codes. Can be overwritten via request
parameter 'httpStatus'")
+ String httpStatusMapping() default
"OK:200,WARN:200,CRITICAL:503,TEMPORARILY_UNAVAILABLE:503,HEALTH_CHECK_ERROR:500";
+
+ @AttributeDefinition(name = "Timeout", description = "Timeout for health
check executor. If not configured (left to -1), the default from health check
executor's configuration is taken. The setting can always be overwritten by
request parameter 'timeout'")
+ long timeout() default -1;
+
+ @AttributeDefinition(name = "Default Tags", description = "Default tags if
no tags are provided in URL.")
+ String[] tags() default {};
+
+ @AttributeDefinition(name = "Combine Tags with OR", description = "If
true, will execute checks that have any of the given tags. If false, will only
execute checks that have *all* of the given tags.")
+ boolean combineTagsWithOr() default true;
+
+ @AttributeDefinition(name = "Default Format", description = "Default
format if format is not provided in URL")
+ String format() default HealthCheckExecutorServlet.FORMAT_HTML;
+
+ @AttributeDefinition(name = "Disabled", description = "Allows to disable
the servlet if required for security reasons")
+ boolean disabled() default false;
+
@AttributeDefinition(name = "CORS Access-Control-Allow-Origin",
description = "Sets the Access-Control-Allow-Origin CORS header. If blank no
header is sent.")
String cors_accessControlAllowOrigin() default "*";
- @AttributeDefinition(name = "Http Status Mapping", description = "Maps HC
result status values to http response codes. Can be overwritten via request
parameter 'httpStatus'")
- String httpStatusMapping() default
"OK:200,WARN:200,CRITICAL:503,TEMPORARILY_UNAVAILABLE:503,HEALTH_CHECK_ERROR:500";
+ @AttributeDefinition
+ String webconsole_configurationFactory_nameHint() default "{servletPath}
default format:{format} default tags:{tags} ";
+
}
Modified:
felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java
URL:
http://svn.apache.org/viewvc/felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java?rev=1850346&r1=1850345&r2=1850346&view=diff
==============================================================================
---
felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java
(original)
+++
felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/servlet/HealthCheckExecutorServletTest.java
Fri Jan 4 11:04:17 2019
@@ -101,6 +101,8 @@ public class HealthCheckExecutorServletT
doReturn(true).when(healthCheckExecutorServletConfig).disabled();
doReturn("OK:200").when(healthCheckExecutorServletConfig).httpStatusMapping();
+ doReturn(new String[0]).when(healthCheckExecutorServletConfig).tags();
+
doReturn(HealthCheckExecutorServlet.FORMAT_HTML).when(healthCheckExecutorServletConfig).format();
healthCheckExecutorServlet.activate(healthCheckExecutorServletConfig);
}
Modified:
felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/HealthCheckServletIT.java
URL:
http://svn.apache.org/viewvc/felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/HealthCheckServletIT.java?rev=1850346&r1=1850345&r2=1850346&view=diff
==============================================================================
---
felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/HealthCheckServletIT.java
(original)
+++
felix/trunk/healthcheck/core/src/test/java/org/apache/felix/hc/core/it/HealthCheckServletIT.java
Fri Jan 4 11:04:17 2019
@@ -39,10 +39,13 @@ import org.osgi.framework.InvalidSyntaxE
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.http.HttpService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/** Verify that the HealthCheckExecutorServlet becomes available after
creating the corresponding config */
@RunWith(PaxExam.class)
public class HealthCheckServletIT {
+ private final Logger log = LoggerFactory.getLogger(getClass());
@Inject
private ConfigurationAdmin configAdmin;
@@ -84,18 +87,20 @@ public class HealthCheckServletIT {
@Test
public void testServletBecomesActive() throws InvalidSyntaxException,
IOException, InterruptedException {
- final String property = "servletPath";
- final String path = "/test/" + UUID.randomUUID();
+ final String servletPathPropertyName = "servletPath";
+ final String servletPathPropertyVal = "/test/" + UUID.randomUUID();
final String packagePrefix = "org.apache.felix.hc";
assertEquals("Initially expecting no servlet from " + packagePrefix,
0, countServletServices(packagePrefix));
final int pathsBefore = httpService.getPaths().size();
// Activate servlet and wait for it to show up
- final String pid =
"org.apache.felix.hc.core.impl.servlet.HealthCheckExecutorServlet";
- final org.osgi.service.cm.Configuration cfg =
configAdmin.getConfiguration(pid, null);
+ final String factoryPid =
"org.apache.felix.hc.core.impl.servlet.HealthCheckExecutorServlet";
+ org.osgi.service.cm.Configuration cfg =
configAdmin.createFactoryConfiguration(factoryPid, null);
+ log.info("Created factory configuration for servlet with pid = {}",
cfg.getPid());
final Dictionary<String, Object> props = new Hashtable<String,
Object>();
- props.put(property, path);
+ props.put(servletPathPropertyName, servletPathPropertyVal);
cfg.update(props);
+ log.info("Updated config with properties {}", props);
final long timeoutMsec = 5000L;
final long endTime = System.currentTimeMillis() + timeoutMsec;
@@ -111,13 +116,13 @@ public class HealthCheckServletIT {
countServletServices(packagePrefix));
final List<String> paths = httpService.getPaths();
assertEquals("Expecting six new servlet registration", pathsBefore +
expectedServletCount, paths.size());
- assertEquals("Expecting the HC servlet to be registered at " + path,
path, paths.get(paths.size() - 6)); // paths list is longer,
+ assertEquals("Expecting the HC servlet to be registered at " +
servletPathPropertyVal, servletPathPropertyVal, paths.get(paths.size() - 6));
// paths list is longer,
// use last entries in list
- assertEquals("Expecting the HTML HC servlet to be registered at " +
path + ".html", path + ".html", paths.get(paths.size() - 5));
- assertEquals("Expecting the JSON HC servlet to be registered at " +
path + ".json", path + ".json", paths.get(paths.size() - 4));
- assertEquals("Expecting the JSONP HC servlet to be registered at " +
path + ".jsonp", path + ".jsonp", paths.get(paths.size() - 3));
- assertEquals("Expecting the TXT HC servlet to be registered at " +
path + ".txt", path + ".txt", paths.get(paths.size() - 2));
- assertEquals("Expecting the verbose TXT HC servlet to be registered at
" + path + ".verbose.txt", path + ".verbose.txt",
+ assertEquals("Expecting the HTML HC servlet to be registered at " +
servletPathPropertyVal + ".html", servletPathPropertyVal + ".html",
paths.get(paths.size() - 5));
+ assertEquals("Expecting the JSON HC servlet to be registered at " +
servletPathPropertyVal + ".json", servletPathPropertyVal + ".json",
paths.get(paths.size() - 4));
+ assertEquals("Expecting the JSONP HC servlet to be registered at " +
servletPathPropertyVal + ".jsonp", servletPathPropertyVal + ".jsonp",
paths.get(paths.size() - 3));
+ assertEquals("Expecting the TXT HC servlet to be registered at " +
servletPathPropertyVal + ".txt", servletPathPropertyVal + ".txt",
paths.get(paths.size() - 2));
+ assertEquals("Expecting the verbose TXT HC servlet to be registered at
" + servletPathPropertyVal + ".verbose.txt", servletPathPropertyVal +
".verbose.txt",
paths.get(paths.size() - 1));
}
}