You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by gh...@apache.org on 2019/08/22 17:14:10 UTC
[sling-org-apache-sling-hc-core] 01/01: SLING-8653 Noop version of
org.apache.sling.hc.core
This is an automated email from the ASF dual-hosted git repository.
ghenzler pushed a commit to branch noop-version-for-felix-migration
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-hc-core.git
commit 9edb4b35f941ba9e0db57e016f1c9b368f245673
Author: georg.henzler <ge...@netcentric.biz>
AuthorDate: Thu Aug 22 18:52:24 2019 +0200
SLING-8653 Noop version of org.apache.sling.hc.core
---
bnd.bnd | 4 -
pom.xml | 179 +-------
.../sling/hc/core/impl/CompositeHealthCheck.java | 185 --------
.../impl/CompositeHealthCheckConfiguration.java | 61 ---
.../apache/sling/hc/core/impl/CompositeResult.java | 46 --
.../core/impl/JmxAdjustableStatusForTesting.java | 245 ----------
.../hc/core/impl/JmxAttributeHealthCheck.java | 83 ----
.../impl/JmxAttributeHealthCheckConfiguration.java | 67 ---
.../hc/core/impl/JmxScriptBindingsProvider.java | 90 ----
.../org/apache/sling/hc/core/impl/NoopHcCore.java | 41 ++
.../sling/hc/core/impl/ScriptableHealthCheck.java | 124 -----
.../impl/ScriptableHealthCheckConfiguration.java | 61 ---
.../impl/executor/AsyncHealthCheckExecutor.java | 251 -----------
.../hc/core/impl/executor/ExecutionResult.java | 126 ------
.../impl/executor/ExtendedHealthCheckExecutor.java | 31 --
.../impl/executor/HealthCheckExecutorImpl.java | 500 ---------------------
.../HealthCheckExecutorImplConfiguration.java | 53 ---
.../hc/core/impl/executor/HealthCheckFuture.java | 110 -----
.../core/impl/executor/HealthCheckResultCache.java | 237 ----------
.../impl/servlet/HealthCheckExecutorServlet.java | 404 -----------------
.../HealthCheckExecutorServletConfiguration.java | 49 --
.../hc/core/impl/servlet/ResultHtmlSerializer.java | 157 -------
.../servlet/ResultHtmlSerializerConfiguration.java | 46 --
.../hc/core/impl/servlet/ResultJsonSerializer.java | 119 -----
.../hc/core/impl/servlet/ResultTxtSerializer.java | 32 --
.../impl/servlet/ResultTxtVerboseSerializer.java | 137 ------
.../ResultTxtVerboseSerializerConfiguration.java | 53 ---
.../apache/sling/hc/jmx/impl/HealthCheckMBean.java | 257 -----------
.../sling/hc/jmx/impl/HealthCheckMBeanCreator.java | 193 --------
.../hc/core/impl/CompositeHealthCheckTest.java | 290 ------------
.../hc/core/impl/JmxAttributeHealthCheckTest.java | 52 ---
.../core/impl/JmxScriptBindingsProviderTest.java | 38 --
.../hc/core/impl/ScriptableHealthCheckTest.java | 101 -----
.../impl/executor/HealthCheckExecutorImplTest.java | 182 --------
.../impl/executor/HealthCheckResultCacheTest.java | 197 --------
.../servlet/HealthCheckExecutorServletTest.java | 299 ------------
.../sling/hc/core/it/AsyncHealthCheckIT.java | 178 --------
.../hc/core/it/ExtendedHealthCheckExecutorIT.java | 113 -----
.../hc/core/it/HealthCheckExecutorSelectionIT.java | 147 ------
.../sling/hc/core/it/HealthCheckFilterIT.java | 271 -----------
.../sling/hc/core/it/HealthCheckServletIT.java | 123 -----
.../core/it/JmxAdjustableStatusForTestingIT.java | 156 -------
.../apache/sling/hc/core/it/MockHttpService.java | 62 ---
src/test/java/org/apache/sling/hc/core/it/U.java | 127 ------
.../sling/hc/jmx/impl/HealthCheckMBeanTest.java | 185 --------
45 files changed, 46 insertions(+), 6416 deletions(-)
diff --git a/bnd.bnd b/bnd.bnd
index f5933e9..e19e747 100644
--- a/bnd.bnd
+++ b/bnd.bnd
@@ -7,7 +7,3 @@ Bundle-DocURL: https://sling.apache.org
Bundle-License: Apache License, Version 2.0
Bundle-Vendor: The Apache Software Foundation
-
--removeheaders:\
- Include-Resource,\
- Private-Package
diff --git a/pom.xml b/pom.xml
index b618f33..eaa5bdc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,20 +29,14 @@
</parent>
<artifactId>org.apache.sling.hc.core</artifactId>
- <version>1.2.11-SNAPSHOT</version>
+ <version>2.0.0-SNAPSHOT</version>
<name>Apache Sling Health Check Core</name>
<inceptionYear>2013</inceptionYear>
- <description>
- The Sling Health Check Core
- </description>
+ <description>CAUTION: Noop Package - ensure Felix Health Check bundles are installed!</description>
<properties>
- <pax-exam.version>4.11.0</pax-exam.version>
- <pax-link.version>2.4.3</pax-link.version>
- <org.ops4j.pax.logging.DefaultServiceLog.level>INFO</org.ops4j.pax.logging.DefaultServiceLog.level>
- <felix.shell>false</felix.shell>
<project.bundle.file>${project.build.directory}/${project.build.finalName}.jar</project.bundle.file>
</properties>
@@ -59,49 +53,6 @@
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-maven-plugin</artifactId>
</plugin>
- <plugin>
- <groupId>biz.aQute.bnd</groupId>
- <artifactId>bnd-baseline-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.jacoco</groupId>
- <artifactId>jacoco-maven-plugin</artifactId>
- <executions>
- <execution>
- <id>prepare-agent-integration</id>
- <goals>
- <goal>prepare-agent-integration</goal>
- </goals>
- <configuration>
- <propertyName>coverage.command</propertyName>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.servicemix.tooling</groupId>
- <artifactId>depends-maven-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-failsafe-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>integration-test</goal>
- <goal>verify</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <systemProperties>
- <org.ops4j.pax.logging.DefaultServiceLog.level>${org.ops4j.pax.logging.DefaultServiceLog.level}</org.ops4j.pax.logging.DefaultServiceLog.level>
- <felix.shell>${felix.shell}</felix.shell>
- <coverage.command>${coverage.command}</coverage.command>
- <project.bundle.file>${project.bundle.file}</project.bundle.file>
- </systemProperties>
- </configuration>
- </plugin>
</plugins>
</build>
@@ -117,9 +68,9 @@
<scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.hc.api</artifactId>
- <version>1.0.3-SNAPSHOT</version>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.healthcheck.api</artifactId>
+ <version>2.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
@@ -127,126 +78,6 @@
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <version>1.9.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>rhino</groupId>
- <artifactId>js</artifactId>
- <version>1.6R6</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-container-forked</artifactId>
- <version>${pax-exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit4</artifactId>
- <version>${pax-exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-link-mvn</artifactId>
- <version>${pax-exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.url</groupId>
- <artifactId>pax-url-aether</artifactId>
- <version>${pax-link.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.url</groupId>
- <artifactId>pax-url-wrap</artifactId>
- <version>${pax-link.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-atinject_1.0_spec</artifactId>
- <version>1.0</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.framework</artifactId>
- <version>5.6.10</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.osgi</artifactId>
- <version>2.2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.scripting.api</artifactId>
- <version>2.1.0</version>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.threads</artifactId>
- <version>3.1.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.geronimo.specs</groupId>
- <artifactId>geronimo-json_1.0_spec</artifactId>
- <version>1.0-alpha-1</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.johnzon</artifactId>
- <version>1.0.0</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.scheduler</artifactId>
- <version>2.3.2</version>
- <scope>provided</scope>
- </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>
- <scope>provided</scope>
- </dependency>
-
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.5</version>
- <scope>test</scope>
- </dependency>
</dependencies>
</project>
diff --git a/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheck.java b/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheck.java
deleted file mode 100644
index 95ce1f4..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheck.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.Result.Status;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionOptions;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.apache.sling.hc.util.HealthCheckFilter;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentConstants;
-import org.osgi.service.component.ComponentContext;
-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.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.metatype.annotations.Designate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** {@link HealthCheck} that executes a number of other HealthChecks,
- * selected by their tags, and merges their Results.
- */
-
-@Component(
- service = HealthCheck.class,
- configurationPolicy = ConfigurationPolicy.REQUIRE
-)
-@Designate(
- ocd = CompositeHealthCheckConfiguration.class,
- factory = true
-)
-public class CompositeHealthCheck implements HealthCheck {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- static final String PROP_FILTER_TAGS = "filter.tags";
-
- private String [] filterTags;
-
- private boolean combineTagsWithOr;
-
- @Reference
- private HealthCheckExecutor healthCheckExecutor;
-
- private BundleContext bundleContext;
- private HealthCheckFilter healthCheckFilter;
-
- private volatile ComponentContext componentContext;
-
- @Activate
- protected void activate(final CompositeHealthCheckConfiguration configuration, final ComponentContext ctx) {
- bundleContext = ctx.getBundleContext();
- componentContext = ctx;
- healthCheckFilter = new HealthCheckFilter(bundleContext);
-
- filterTags = configuration.filter_tags();
- combineTagsWithOr = configuration.filter_combineTagsWithOr();
- log.debug("Activated, will select HealthCheck having tags {} {}", Arrays.asList(filterTags), combineTagsWithOr ? "using OR" : "using AND");
- }
-
- @Deactivate
- protected void deactivate() {
- bundleContext = null;
- healthCheckFilter = null;
- componentContext = null;
- }
-
- @Override
- public Result execute() {
- final ComponentContext localCtx = this.componentContext;
- final ServiceReference referenceToThis = localCtx == null ? null : localCtx.getServiceReference();
- Result result = referenceToThis == null ? null : checkForRecursion(referenceToThis, new HashSet<String>());
- if (result != null) {
- // return recursion error
- return result;
- }
-
- FormattingResultLog resultLog = new FormattingResultLog();
- HealthCheckExecutionOptions options = new HealthCheckExecutionOptions();
- options.setCombineTagsWithOr(combineTagsWithOr);
- List<HealthCheckExecutionResult> executionResults = healthCheckExecutor.execute(HealthCheckSelector.tags(filterTags), options);
- resultLog.debug("Executing {} HealthChecks selected by tags {}", executionResults.size(), Arrays.asList(filterTags));
- result = new CompositeResult(resultLog, executionResults);
-
- return result;
- }
-
-
- Result checkForRecursion(ServiceReference hcReference, Set<String> alreadyBannedTags) {
-
- HealthCheckMetadata thisCheckMetadata = new HealthCheckMetadata(hcReference);
-
- Set<String> bannedTagsForThisCompositeCheck = new HashSet<String>();
- bannedTagsForThisCompositeCheck.addAll(alreadyBannedTags);
- bannedTagsForThisCompositeCheck.addAll(thisCheckMetadata.getTags());
-
- String[] tagsForIncludedChecksArr = PropertiesUtil.toStringArray(hcReference.getProperty(PROP_FILTER_TAGS), new String[0]);
- Set<String> tagsForIncludedChecks = new HashSet<String>(Arrays.asList(tagsForIncludedChecksArr));
-
-
- log.debug("HC {} has banned tags {}", thisCheckMetadata.getName(), bannedTagsForThisCompositeCheck);
- log.debug("tagsForIncludedChecks {}", tagsForIncludedChecks);
-
- // is this HC ok?
- Set<String> intersection = new HashSet<String>();
- intersection.addAll(bannedTagsForThisCompositeCheck);
- intersection.retainAll(tagsForIncludedChecks);
-
- if (!intersection.isEmpty()) {
- return new Result(Status.HEALTH_CHECK_ERROR,
- "INVALID CONFIGURATION: Cycle detected in composite health check hierarchy. Health check '" + thisCheckMetadata.getName()
- + "' (" + hcReference.getProperty(Constants.SERVICE_ID) + ") must not have tag(s) " + intersection
- + " as a composite check in the hierarchy is itself already tagged alike (tags assigned to composite checks: "
- + bannedTagsForThisCompositeCheck + ")");
- }
-
- // check each sub composite check
- ServiceReference[] hcRefsOfCompositeCheck = healthCheckFilter.getHealthCheckServiceReferences(HealthCheckSelector.tags(tagsForIncludedChecksArr), combineTagsWithOr);
- for (ServiceReference hcRefOfCompositeCheck : hcRefsOfCompositeCheck) {
- if (CompositeHealthCheck.class.getName().equals(hcRefOfCompositeCheck.getProperty(ComponentConstants.COMPONENT_NAME))) {
- log.debug("Checking sub composite HC {}, {}", hcRefOfCompositeCheck, hcRefOfCompositeCheck.getProperty(ComponentConstants.COMPONENT_NAME));
- Result result = checkForRecursion(hcRefOfCompositeCheck, bannedTagsForThisCompositeCheck);
- if (result != null) {
- // found recursion
- return result;
- }
- }
-
- }
-
- // no recursion detected
- return null;
-
- }
-
- void setHealthCheckFilter(HealthCheckFilter healthCheckFilter) {
- this.healthCheckFilter = healthCheckFilter;
- }
-
- void setFilterTags(String[] filterTags) {
- this.filterTags = filterTags;
- }
-
- void setCombineTagsWithOr(boolean combineTagsWithOr) {
- this.combineTagsWithOr = combineTagsWithOr;
- }
-
- void setHealthCheckExecutor(HealthCheckExecutor healthCheckExecutor) {
- this.healthCheckExecutor = healthCheckExecutor;
- }
-
- void setComponentContext(ComponentContext ctx) {
- this.componentContext = ctx;
- }
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheckConfiguration.java b/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheckConfiguration.java
deleted file mode 100644
index 6a8a02a..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheckConfiguration.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-@ObjectClassDefinition(
- name = "Apache Sling Composite Health Check",
- description = "Executes a set of health checks, selected by tags."
-)
-@interface CompositeHealthCheckConfiguration {
-
- @AttributeDefinition(
- name = "Name",
- description = "Name of this health check."
- )
- String hc_name() default "";
-
- @AttributeDefinition(
- name = "Tags",
- description = "List of tags for this health check, used to select subsets of health checks for execution e.g. by a composite health check."
- )
- String[] hc_tags() default {};
-
- @AttributeDefinition(
- name = "MBean Name",
- description = "Name of the MBean to create for this health check. If empty, no MBean is registered."
- )
- String hc_mbean_name() default "";
-
- //
-
- @AttributeDefinition(
- name = "Filter Tags",
- description = "Tags used to select which health checks the composite health check executes."
- )
- String[] filter_tags() default {};
-
- @AttributeDefinition(
- name = "Combine Tags With Or",
- description = "Tags used to select which health checks the composite health check executes."
- )
- boolean filter_combineTagsWithOr() default false;
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/CompositeResult.java b/src/main/java/org/apache/sling/hc/core/impl/CompositeResult.java
deleted file mode 100644
index e42396f..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/CompositeResult.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import static org.apache.sling.hc.util.FormattingResultLog.msHumanReadable;
-
-import java.util.List;
-
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.ResultLog;
-import org.apache.sling.hc.api.ResultLog.Entry;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-
-public class CompositeResult extends Result {
-
- public CompositeResult(ResultLog log, List<HealthCheckExecutionResult> executionResults) {
- super(log);
-
- for (HealthCheckExecutionResult executionResult : executionResults) {
- HealthCheckMetadata healthCheckMetadata = executionResult.getHealthCheckMetadata();
- Result healthCheckResult = executionResult.getHealthCheckResult();
- for (Entry entry : healthCheckResult) {
- resultLog.add(new ResultLog.Entry(entry.getStatus(), healthCheckMetadata.getName() + ": " + entry.getMessage(), entry.getException()));
- }
- resultLog.add(new ResultLog.Entry(Result.Status.DEBUG, healthCheckMetadata.getName() + " finished after "
- + msHumanReadable(executionResult.getElapsedTimeInMs()) + (executionResult.hasTimedOut() ? " (timed out)" : "")));
- }
- }
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/JmxAdjustableStatusForTesting.java b/src/main/java/org/apache/sling/hc/core/impl/JmxAdjustableStatusForTesting.java
deleted file mode 100644
index b9b3f9a..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/JmxAdjustableStatusForTesting.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.InvalidAttributeValueException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanException;
-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.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.Result.Status;
-import org.apache.sling.hc.api.ResultLog.Entry;
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Allows to dynamically add a health check that returns WARN or CRITICAL for certain tags for testing purposes. Uses an MBean to add/remove the DynamicTestingHealthCheck dynamically. */
-@Component
-public class JmxAdjustableStatusForTesting {
- private static final Logger LOG = LoggerFactory.getLogger(JmxAdjustableStatusForTesting.class);
-
- private static final String OBJECT_NAME = "org.apache.sling.healthcheck:type=AdjustableHealthCheckForTesting";
-
- private BundleContext bundleContext;
-
- private ServiceRegistration mbeanRegistration = null;
- private ServiceRegistration healthCheckRegistration = null;
-
- @Activate
- protected final void activate(final ComponentContext context) {
- this.bundleContext = context.getBundleContext();
- registerMbean();
- }
-
- @Deactivate
- protected final void deactivate(final ComponentContext context) {
- unregisterMbean();
- unregisterDynamicTestingHealthCheck();
- }
-
- private void registerMbean() {
- final Dictionary<String, String> mbeanProps = new Hashtable<String, String>();
- mbeanProps.put("jmx.objectname", OBJECT_NAME);
- AdjustableHealthCheckStatusMBean adjustableHealthCheckStatusMBean = new AdjustableHealthCheckStatusMBean();
- this.mbeanRegistration = bundleContext.registerService(DynamicMBean.class.getName(), adjustableHealthCheckStatusMBean, mbeanProps);
- LOG.debug("Registered mbean {} as {}", adjustableHealthCheckStatusMBean, OBJECT_NAME);
- }
-
- private void unregisterMbean() {
- if (this.mbeanRegistration != null) {
- this.mbeanRegistration.unregister();
- this.mbeanRegistration = null;
- LOG.debug("Unregistered mbean AdjustableHealthCheckStatusMBean");
- }
- }
-
- /* synchronized as potentially multiple users can run JMX operations */
- private synchronized void registerDynamicTestingHealthCheck(Result.Status status, String[] tags) {
- unregisterDynamicTestingHealthCheck();
- HealthCheck healthCheck = new DynamicTestingHealthCheck(status);
- Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(HealthCheck.NAME, "JMX-adjustable Testing Check");
- props.put(HealthCheck.TAGS, tags);
-
- healthCheckRegistration = bundleContext.registerService(HealthCheck.class.getName(), healthCheck, props);
-
- }
-
- /* synchronized as potentially multiple users can run JMX operations */
- private synchronized void unregisterDynamicTestingHealthCheck() {
- if (this.healthCheckRegistration != null) {
- this.healthCheckRegistration.unregister();
- this.healthCheckRegistration = null;
- LOG.debug("Unregistered DynamicTestingHealthCheck");
- }
- }
-
- class DynamicTestingHealthCheck implements HealthCheck {
-
- private final Result.Status status;
-
- DynamicTestingHealthCheck(Result.Status status) {
- this.status = status;
- }
-
- @Override
- public Result execute() {
- FormattingResultLog resultLog = new FormattingResultLog();
- resultLog.add(new Entry(status, "Set by JMX bean " + OBJECT_NAME + " (someone from IT operations is configuring this instance)"));
- return new Result(resultLog);
- }
-
- }
-
- private class AdjustableHealthCheckStatusMBean implements DynamicMBean {
-
- private static final String OP_RESET = "reset";
- private static final String OP_ADD_WARN_RESULT_FOR_TAGS = "addWarnResultForTags";
- private static final String OP_ADD_CRITICAL_RESULT_FOR_TAGS = "addCriticalResultForTags";
-
- private static final String ATT_TAGS = "tags";
- private static final String ATT_STATUS = "status";
-
- private static final String STATUS_INACTIVE = "INACTIVE";
-
- /** The mbean info. */
- private final MBeanInfo mbeanInfo;
-
- private List<String> tags = new ArrayList<String>();
- private String status = STATUS_INACTIVE;
-
- public AdjustableHealthCheckStatusMBean() {
- this.mbeanInfo = this.createMBeanInfo();
- }
-
- @Override
- public Object getAttribute(final String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
-
- if (ATT_TAGS.equals(attribute)) {
- return StringUtils.join(tags, ",");
- } else if (ATT_STATUS.equals(attribute)) {
- return status.toString();
- } else {
- throw new AttributeNotFoundException("Attribute " + attribute + " not found.");
- }
- }
-
- @Override
- public AttributeList getAttributes(final String[] attributes) {
- final AttributeList result = new AttributeList();
- for (String att : attributes) {
- try {
- result.add(new Attribute(att, getAttribute(att)));
- } catch (Exception e) {
- throw new IllegalArgumentException(e.getMessage(), e);
- }
- }
- return result;
- }
-
- private MBeanInfo createMBeanInfo() {
- final List<MBeanAttributeInfo> attrs = new ArrayList<MBeanAttributeInfo>();
-
- attrs.add(new MBeanAttributeInfo(ATT_TAGS, String.class.getName(), "Tags", true, false, false));
- attrs.add(new MBeanAttributeInfo(ATT_STATUS, String.class.getName(), "Status", true, false, false));
-
- MBeanParameterInfo[] params = new MBeanParameterInfo[] { new MBeanParameterInfo(ATT_TAGS, "java.lang.String", "Comma separated list of tags") };
-
- final List<MBeanOperationInfo> ops = new ArrayList<MBeanOperationInfo>();
- ops.add(new MBeanOperationInfo(OP_RESET, "Resets this testing mechanism and removes the failing HC",
- new MBeanParameterInfo[0], "java.lang.String", MBeanOperationInfo.ACTION));
- ops.add(new MBeanOperationInfo(OP_ADD_CRITICAL_RESULT_FOR_TAGS, "Adds a critical result for the given tags",
- params, "java.lang.String", MBeanOperationInfo.ACTION));
- ops.add(new MBeanOperationInfo(OP_ADD_WARN_RESULT_FOR_TAGS, "Adds a warn result for the given tags",
- params, "java.lang.String", MBeanOperationInfo.ACTION));
-
- return new MBeanInfo(this.getClass().getName(),
- "Adjustable Health Check", attrs.toArray(new MBeanAttributeInfo[attrs.size()]), null, ops.toArray(new MBeanOperationInfo[ops.size()]), null);
- }
-
- @Override
- public MBeanInfo getMBeanInfo() {
- return this.mbeanInfo;
- }
-
- @Override
- public Object invoke(final String actionName, final Object[] params, final String[] signature) throws MBeanException, ReflectionException {
- if (OP_RESET.equals(actionName)) {
- tags = Arrays.asList("");
- status = STATUS_INACTIVE;
- unregisterDynamicTestingHealthCheck();
- LOG.info("JMX-adjustable Health Check for testing was reset");
- return "Reset successful";
- } else if (OP_ADD_CRITICAL_RESULT_FOR_TAGS.equals(actionName)) {
- String[] newTags = params[0].toString().split("[,; ]+");
- tags = Arrays.asList(newTags);
- Status critical = Result.Status.CRITICAL;
- status = critical.toString();
- registerDynamicTestingHealthCheck(critical, newTags);
- LOG.info("Activated JMX-adjustable Health Check with status CRITICAL and tags " + StringUtils.join(tags, ","));
- return "Added check with result CRITICAL";
- } else if (OP_ADD_WARN_RESULT_FOR_TAGS.equals(actionName)) {
- String[] newTags = params[0].toString().split("[,; ]+");
- tags = Arrays.asList(newTags);
- Status warn = Result.Status.WARN;
- status = warn.toString();
- registerDynamicTestingHealthCheck(warn, newTags);
- LOG.info("Activated JMX-adjustable Health Check with status WARN and tags " + StringUtils.join(tags, ","));
- return "Added check with result WARN";
- } else {
- throw new MBeanException(new UnsupportedOperationException(getClass().getSimpleName() + " does not support operation " + actionName));
- }
- }
-
- @Override
- public void setAttribute(final Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException,
- ReflectionException {
- throw new MBeanException(new UnsupportedOperationException(getClass().getSimpleName() + " does not support setting attributes."));
- }
-
- @Override
- public AttributeList setAttributes(final AttributeList attributes) {
- return new AttributeList();
- }
- }
-
-
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/JmxAttributeHealthCheck.java b/src/main/java/org/apache/sling/hc/core/impl/JmxAttributeHealthCheck.java
deleted file mode 100644
index 29805f9..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/JmxAttributeHealthCheck.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import java.lang.management.ManagementFactory;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.apache.sling.hc.util.SimpleConstraintChecker;
-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.metatype.annotations.Designate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** {@link HealthCheck} that checks a single JMX attribute */
-@Component(
- service = HealthCheck.class,
- configurationPolicy = ConfigurationPolicy.REQUIRE
-)
-@Designate(
- ocd = JmxAttributeHealthCheckConfiguration.class,
- factory = true
-)
-public class JmxAttributeHealthCheck implements HealthCheck {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- private String mbeanName;
- private String attributeName;
- private String constraint;
-
- @Activate
- protected void activate(final JmxAttributeHealthCheckConfiguration configuration) {
- mbeanName = configuration.mbean_name();
- attributeName = configuration.attribute_name();
- constraint = configuration.attribute_value_constraint();
-
- log.debug("Activated with HealthCheck name={}, objectName={}, attribute={}, constraint={}",
- new Object[] { configuration.hc_name(), mbeanName, attributeName, constraint });
- }
-
- @Override
- public Result execute() {
- final FormattingResultLog resultLog = new FormattingResultLog();
- resultLog.debug("Checking {} / {} with constraint {}", mbeanName, attributeName, constraint);
- try {
- final MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();
- final ObjectName objectName = new ObjectName(mbeanName);
- if(jmxServer.queryNames(objectName, null).size() == 0) {
- resultLog.warn("MBean not found: {}", objectName);
- } else {
- final Object value = jmxServer.getAttribute(objectName, attributeName);
- resultLog.debug("{} {} returns {}", mbeanName, attributeName, value);
- new SimpleConstraintChecker().check(value, constraint, resultLog);
- }
- } catch(final Exception e) {
- log.warn("JMX attribute {}/{} check failed: {}", new Object []{ mbeanName, attributeName, e});
- resultLog.healthCheckError("JMX attribute check failed: {}", e);
- }
- return new Result(resultLog);
- }
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/JmxAttributeHealthCheckConfiguration.java b/src/main/java/org/apache/sling/hc/core/impl/JmxAttributeHealthCheckConfiguration.java
deleted file mode 100644
index 0b5ff55..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/JmxAttributeHealthCheckConfiguration.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-@ObjectClassDefinition(
- name = "Apache Sling JMX Attribute Health Check",
- description = "Checks the value of a single JMX attribute."
-)
-@interface JmxAttributeHealthCheckConfiguration {
-
- @AttributeDefinition(
- name = "Name",
- description = "Name of this health check."
- )
- String hc_name() default "";
-
- @AttributeDefinition(
- name = "Tags",
- description = "List of tags for this health check, used to select subsets of health checks for execution e.g. by a composite health check."
- )
- String[] hc_tags() default {};
-
- @AttributeDefinition(
- name = "MBean Name",
- description = "Name of the MBean to create for this health check. If empty, no MBean is registered."
- )
- String hc_mbean_name() default "";
-
- //
-
- @AttributeDefinition(
- name = "Check MBean Name",
- description = "The name of the MBean to check by this health check."
- )
- String mbean_name() default "";
-
- @AttributeDefinition(
- name = "Check Attribute Name",
- description = "The name of the MBean attribute to check by this health check."
- )
- String attribute_name() default "";
-
- @AttributeDefinition(
- name = "Check Attribute Constraint",
- description = "Constraint on the MBean attribute value."
- )
- String attribute_value_constraint() default "";
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/JmxScriptBindingsProvider.java b/src/main/java/org/apache/sling/hc/core/impl/JmxScriptBindingsProvider.java
deleted file mode 100644
index bfdbd94..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/JmxScriptBindingsProvider.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import java.lang.management.ManagementFactory;
-
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-import javax.script.Bindings;
-
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.apache.sling.scripting.api.BindingsValuesProvider;
-import org.osgi.service.component.annotations.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** The JmxBinding is meant to be bound as "jmx" global variables
- * in scripted rules, to allow for writing scripted expressions
- * like jmx.attribute("java.lang:type=ClassLoading", "LoadedClassCount") > 100
- */
-@Component(
- service = BindingsValuesProvider.class,
- property = {
- "context=healthcheck"
- }
-)
-public class JmxScriptBindingsProvider implements BindingsValuesProvider {
- private MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();
- private final Logger log = LoggerFactory.getLogger(getClass());
- public static final String JMX_BINDING_NAME = "jmx";
-
- public static class AttributeBinding {
- private final MBeanServer jmxServer;
- private final FormattingResultLog resultLog;
-
- AttributeBinding(MBeanServer s, FormattingResultLog r) {
- jmxServer = s;
- resultLog = r;
- }
-
- public Object attribute(String objectNameString, String attributeName)
- throws MalformedObjectNameException, AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException {
- final ObjectName name = new ObjectName(objectNameString);
- if(jmxServer.queryNames(name, null).size() == 0) {
- final String msg = "JMX object name not found: [" + objectNameString + "]";
- resultLog.warn(msg);
- throw new IllegalStateException(msg);
- }
- resultLog.debug("Got JMX Object [{}]", name);
- final Object value = jmxServer.getAttribute(name, attributeName);
- resultLog.debug("JMX Object [{}] Attribute [{}] = [{}]", name, attributeName, value);
- return value;
- }
- }
-
- @Override
- public void addBindings(Bindings b) {
- final String logBindingName = FormattingResultLog.class.getName();
- final Object resultLog = b.get(logBindingName);
- if (resultLog == null) {
- log.debug("No {} found in Bindings, cannot activate {} binding", logBindingName, JMX_BINDING_NAME);
- return;
- }
- try {
- b.put("jmx", new AttributeBinding(jmxServer, (FormattingResultLog)resultLog));
- } catch(Exception e) {
- log.error("Exception while activating " + JMX_BINDING_NAME, e);
- }
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/hc/core/impl/NoopHcCore.java b/src/main/java/org/apache/sling/hc/core/impl/NoopHcCore.java
new file mode 100644
index 0000000..230e341
--- /dev/null
+++ b/src/main/java/org/apache/sling/hc/core/impl/NoopHcCore.java
@@ -0,0 +1,41 @@
+/*
+ * 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 ASF 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.sling.hc.core.impl;
+
+import org.apache.felix.hc.api.execution.HealthCheckExecutor;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(immediate = true)
+public class NoopHcCore {
+ private static final Logger LOG = LoggerFactory.getLogger(NoopHcCore.class);
+
+ @Reference
+ protected HealthCheckExecutor executor;
+
+ @Activate
+ protected void activate() {
+ LOG.debug("Sling Health Check Web Console is obsolete and replaced by Felix Health Check Webconsole "
+ + "(found Felix HC executor: " + executor + ")");
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/ScriptableHealthCheck.java b/src/main/java/org/apache/sling/hc/core/impl/ScriptableHealthCheck.java
deleted file mode 100644
index 287910e..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/ScriptableHealthCheck.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.script.Bindings;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.apache.sling.scripting.api.BindingsValuesProvider;
-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.ReferencePolicy;
-import org.osgi.service.metatype.annotations.Designate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** {@link HealthCheck} that checks a scriptable expression */
-@Component(
- service = HealthCheck.class,
- configurationPolicy = ConfigurationPolicy.REQUIRE
-)
-@Designate(
- ocd = ScriptableHealthCheckConfiguration.class,
- factory = true
-)
-public class ScriptableHealthCheck implements HealthCheck {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
- private String expression;
- private String languageExtension;
-
- @Reference
- private ScriptEngineManager scriptEngineManager;
-
- @Reference(
- cardinality = ReferenceCardinality.MULTIPLE,
- policy = ReferencePolicy.DYNAMIC,
- service = BindingsValuesProvider.class,
- target = "(context=healthcheck)"
- )
- private final Set<BindingsValuesProvider> bindingsValuesProviders = new HashSet<BindingsValuesProvider>();
-
- @Activate
- protected void activate(final ScriptableHealthCheckConfiguration configuration) {
- expression = configuration.expression();
- languageExtension = configuration.language_extension();
-
- log.debug("Activated scriptable health check name={}, languageExtension={}, expression={}",
- new Object[] {configuration.hc_name(),
- languageExtension, expression});
- }
-
- @Override
- public Result execute() {
- final FormattingResultLog resultLog = new FormattingResultLog();
- resultLog.debug("Checking expression [{}], language extension=[{}]", expression, languageExtension);
- try {
- final ScriptEngine engine = scriptEngineManager.getEngineByExtension(languageExtension);
- if (engine == null) {
- resultLog.healthCheckError("No ScriptEngine available for extension {}", languageExtension);
- } else {
- // Set Bindings, with our ResultLog as a binding first, so that other bindings can use it
- final Bindings b = engine.createBindings();
- b.put(FormattingResultLog.class.getName(), resultLog);
- synchronized (bindingsValuesProviders) {
- for(BindingsValuesProvider bvp : bindingsValuesProviders) {
- log.debug("Adding Bindings provided by {}", bvp);
- bvp.addBindings(b);
- }
- }
- log.debug("All Bindings added: {}", b.keySet());
-
- final Object value = engine.eval(expression, b);
- if(value!=null && "true".equals(value.toString().toLowerCase())) {
- resultLog.debug("Expression [{}] evaluates to true as expected", expression);
- } else {
- resultLog.warn("Expression [{}] does not evaluate to true as expected, value=[{}]", expression, value);
- }
- }
- } catch (final Exception e) {
- resultLog.healthCheckError(
- "Exception while evaluating expression [{}] with language extension [{}]: {}",
- expression, languageExtension, e);
- }
- return new Result(resultLog);
- }
-
- public void bindBindingsValuesProvider(BindingsValuesProvider bvp) {
- synchronized (bindingsValuesProviders) {
- bindingsValuesProviders.add(bvp);
- }
- log.debug("{} registered: {}", bvp, bindingsValuesProviders);
- }
-
- public void unbindBindingsValuesProvider(BindingsValuesProvider bvp) {
- synchronized (bindingsValuesProviders) {
- bindingsValuesProviders.remove(bvp);
- }
- log.debug("{} unregistered: {}", bvp, bindingsValuesProviders);
- }
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/ScriptableHealthCheckConfiguration.java b/src/main/java/org/apache/sling/hc/core/impl/ScriptableHealthCheckConfiguration.java
deleted file mode 100644
index 9e1ba15..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/ScriptableHealthCheckConfiguration.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-@ObjectClassDefinition(
- name = "Apache Sling Scriptable Health Check",
- description = "Uses scripted expressions to verify multiple JMX attributes or other values."
-)
-@interface ScriptableHealthCheckConfiguration {
-
- @AttributeDefinition(
- name = "Name",
- description = "Name of this health check."
- )
- String hc_name() default "";
-
- @AttributeDefinition(
- name = "Tags",
- description = "List of tags for this health check, used to select subsets of health checks for execution e.g. by a composite health check."
- )
- String[] hc_tags() default {};
-
- @AttributeDefinition(
- name = "MBean Name",
- description = "Name of the MBean to create for this health check. If empty, no MBean is registered."
- )
- String hc_mbean_name() default "";
-
- //
-
- @AttributeDefinition(
- name = "Expression",
- description = "The value of this expression must be \"true\" for this check to be successful."
- )
- String expression() default "";
-
- @AttributeDefinition(
- name = "Language Extension",
- description = "File extension of the language to use to evaluate the expression, for example \"ecma\" or \"groovy\", assuming the corresponding script engine is available. By default \"ecma\" is used."
- )
- String language_extension() default "ecma";
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/executor/AsyncHealthCheckExecutor.java b/src/main/java/org/apache/sling/hc/core/impl/executor/AsyncHealthCheckExecutor.java
deleted file mode 100644
index a8daaba..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/executor/AsyncHealthCheckExecutor.java
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * 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.sling.hc.core.impl.executor;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.sling.commons.scheduler.Scheduler;
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.apache.sling.hc.core.impl.executor.HealthCheckFuture.Callback;
-import org.apache.sling.hc.util.HealthCheckFilter;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Runs health checks that are configured with a cron expression for asynchronous
- * execution. Used by HealthCheckExecutor.
- *
- */
-@Component(
- service = AsyncHealthCheckExecutor.class,
- immediate = true
-)
-public class AsyncHealthCheckExecutor implements ServiceListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(AsyncHealthCheckExecutor.class);
-
- @Reference
- private Scheduler scheduler;
-
- private Map<HealthCheckMetadata, ExecutionResult> asyncResultsByDescriptor = new ConcurrentHashMap<HealthCheckMetadata, ExecutionResult>();
-
- private Map<HealthCheckMetadata, HealthCheckAsyncJob> registeredJobs = new HashMap<HealthCheckMetadata, HealthCheckAsyncJob>();
-
- private BundleContext bundleContext;
-
-
-
- @Activate
- protected final void activate(final ComponentContext componentContext) {
- this.bundleContext = componentContext.getBundleContext();
- this.bundleContext.addServiceListener(this);
-
- int count = 0;
- HealthCheckFilter healthCheckFilter = new HealthCheckFilter(bundleContext);
- final ServiceReference[] healthCheckReferences = healthCheckFilter.getHealthCheckServiceReferences(HealthCheckSelector.empty());
- for (ServiceReference serviceReference : healthCheckReferences) {
- HealthCheckMetadata healthCheckMetadata = new HealthCheckMetadata(serviceReference);
- if (isAsync(healthCheckMetadata)) {
- if (scheduleHealthCheck(healthCheckMetadata)) {
- count++;
- }
- }
- }
- LOG.debug("Scheduled {} jobs for asynchronous health checks", count);
- }
-
- @Deactivate
- protected final void deactivate(final ComponentContext componentContext) {
- this.bundleContext.removeServiceListener(this);
- this.bundleContext = null;
-
- LOG.debug("Unscheduling {} jobs for asynchronous health checks", registeredJobs.size());
- for (HealthCheckMetadata healthCheckDescriptor : new LinkedList<HealthCheckMetadata>(registeredJobs.keySet())) {
- unscheduleHealthCheck(healthCheckDescriptor);
- }
-
- }
-
- @Override
- public void serviceChanged(ServiceEvent event) {
- if(bundleContext == null) {
- // already deactivated?
- return;
- }
- ServiceReference serviceReference = event.getServiceReference();
- final boolean isHealthCheck = serviceReference.isAssignableTo(bundleContext.getBundle(), HealthCheck.class.getName());
-
- if (isHealthCheck) {
- HealthCheckMetadata healthCheckMetadata = new HealthCheckMetadata(serviceReference);
- int eventType = event.getType();
- LOG.debug("Received service event of type {} for health check {}", eventType, healthCheckMetadata);
- if (eventType == ServiceEvent.REGISTERED) {
- scheduleHealthCheck(healthCheckMetadata);
- } else if (eventType == ServiceEvent.UNREGISTERING) {
- unscheduleHealthCheck(healthCheckMetadata);
- } else if (eventType == ServiceEvent.MODIFIED) {
- unscheduleHealthCheck(healthCheckMetadata);
- scheduleHealthCheck(healthCheckMetadata);
- }
-
- }
- }
-
- private boolean scheduleHealthCheck(HealthCheckMetadata descriptor) {
-
- if(!isAsync(descriptor)) {
- return false;
- }
-
- try {
- HealthCheckAsyncJob healthCheckAsyncJob = new HealthCheckAsyncJob(descriptor);
- LOG.debug("Scheduling job {} with cron expression {}", healthCheckAsyncJob, descriptor.getAsyncCronExpression());
- final boolean concurrent = false;
- this.scheduler.addJob(healthCheckAsyncJob.getJobId(), healthCheckAsyncJob, null, descriptor.getAsyncCronExpression(), concurrent);
- registeredJobs.put(descriptor, healthCheckAsyncJob);
- return true;
- } catch (Exception e) {
- LOG.warn("Could not schedule job for " + descriptor + ". Exception: " + e, e);
- return false;
- }
-
- }
-
- private boolean unscheduleHealthCheck(HealthCheckMetadata descriptor) {
-
- // here no check for isAsync must be used to ensure previously
- // scheduled async checks are correctly unscheduled if they have
- // changed from async to sync.
-
- HealthCheckAsyncJob job = registeredJobs.remove(descriptor);
- try {
- if (job != null) {
- LOG.debug("Unscheduling job {} with cron expression '{}'", job, descriptor.getAsyncCronExpression());
- this.scheduler.removeJob(job.getJobId());
- return true;
- }
- } catch (Exception e) {
- LOG.warn("Could not unschedule job " + job + ". Exception: " + e, e);
- }
- return false;
-
- }
-
- /** Called by the main Executor to get results from async HCs */
- void collectAsyncResults(List<HealthCheckMetadata> healthCheckDescriptors, Collection<HealthCheckExecutionResult> results, HealthCheckResultCache cache) {
- Iterator<HealthCheckMetadata> checksIt = healthCheckDescriptors.iterator();
-
- Set<ExecutionResult> asyncResults = new TreeSet<ExecutionResult>();
- while (checksIt.hasNext()) {
- HealthCheckMetadata healthCheckMetadata = checksIt.next();
- if (isAsync(healthCheckMetadata)) {
- ExecutionResult result = asyncResultsByDescriptor.get(healthCheckMetadata);
- if (result == null) {
-
- result = new ExecutionResult(healthCheckMetadata, new Result(Result.Status.INFO, "Async Health Check with cron expression '"
- + healthCheckMetadata.getAsyncCronExpression() + "' has not yet been executed."), 0L);
-
- asyncResults.add(result);
- }
- asyncResults.add(result);
- // remove from HC collection to not execute the check in HealthCheckExecutorImpl
- checksIt.remove();
- }
- }
-
- LOG.debug("Caching {} results from async results", asyncResults.size());
- for(ExecutionResult result : asyncResults) {
- cache.updateWith(result);
- }
-
- LOG.debug("Adding {} results from async results", asyncResults.size());
- results.addAll(asyncResults);
-
- }
-
- void updateWith(HealthCheckExecutionResult result) {
- if (isAsync(result.getHealthCheckMetadata())) {
- asyncResultsByDescriptor.put(result.getHealthCheckMetadata(), (ExecutionResult) result);
- LOG.debug("Updated result for async hc {} with {}", result.getHealthCheckMetadata(), result);
- }
- }
-
- private boolean isAsync(HealthCheckMetadata healthCheckMetadata) {
- return StringUtils.isNotBlank(healthCheckMetadata.getAsyncCronExpression());
- }
-
- private class HealthCheckAsyncJob implements Runnable {
-
- private final HealthCheckMetadata healthCheckDescriptor;
-
- public HealthCheckAsyncJob(HealthCheckMetadata healthCheckDescriptor) {
- super();
- this.healthCheckDescriptor = healthCheckDescriptor;
- }
-
- public String getJobId() {
- String jobId = "job-hc-" + healthCheckDescriptor.getServiceId();
- return jobId;
- }
-
- @Override
- public void run() {
-
- LOG.debug("Running job {}", this);
- HealthCheckFuture healthCheckFuture = new HealthCheckFuture(healthCheckDescriptor, bundleContext, new Callback() {
-
- @Override
- public void finished(HealthCheckExecutionResult result) {
- updateWith(result);
- }});
-
- // run future in same thread (as we are already async via scheduler)
- healthCheckFuture.run();
-
- }
-
- @Override
- public String toString() {
- return "[Async job for " + this.healthCheckDescriptor + "]";
- }
-
- }
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/executor/ExecutionResult.java b/src/main/java/org/apache/sling/hc/core/impl/executor/ExecutionResult.java
deleted file mode 100644
index bab65a4..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/executor/ExecutionResult.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.sling.hc.core.impl.executor;
-
-import java.text.Collator;
-import java.util.Date;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-
-/**
- * The result of executing a {@link HealthCheck}.
- */
-public class ExecutionResult implements Comparable<ExecutionResult>, HealthCheckExecutionResult {
-
- private final Result resultFromHC;
-
- private final HealthCheckMetadata metaData;
-
- private final Date finishedAt;
-
- private final long elapsedTimeInMs;
-
- private final boolean timedOut;
-
- /**
- * Full constructor
- */
- public ExecutionResult(final HealthCheckMetadata metadata,
- final Result simpleResult,
- final long elapsedTimeInMs,
- final boolean timedout) {
- this.metaData = metadata;
- this.resultFromHC = simpleResult;
- this.finishedAt = new Date();
- this.timedOut = timedout;
- this.elapsedTimeInMs = elapsedTimeInMs;
- }
-
- /**
- * Shortcut constructor for a result
- */
- public ExecutionResult(final HealthCheckMetadata metadata,
- final Result simpleResult,
- final long elapsedTimeInMs) {
- this(metadata, simpleResult, elapsedTimeInMs, false);
- }
-
- /**
- * Shortcut constructor to create error/timed out result.
- */
- public ExecutionResult(final HealthCheckMetadata metadata,
- final Result.Status status,
- final String errorMessage,
- final long elapsedTime, boolean timedOut) {
- this(metadata, new Result(status, errorMessage), elapsedTime, timedOut);
- }
-
-
- @Override
- public Result getHealthCheckResult() {
- return this.resultFromHC;
- }
-
- @Override
- public String toString() {
- return "ExecutionResult [status=" + this.resultFromHC.getStatus() +
- ", finishedAt=" + finishedAt +
- ", elapsedTimeInMs=" + elapsedTimeInMs +
- ", timedOut=" + timedOut +
- "]";
- }
-
- @Override
- public long getElapsedTimeInMs() {
- return elapsedTimeInMs;
- }
-
- @Override
- public HealthCheckMetadata getHealthCheckMetadata() {
- return this.metaData;
- }
-
- @Override
- public Date getFinishedAt() {
- return finishedAt;
- }
-
- @Override
- public boolean hasTimedOut() {
- return this.timedOut;
- }
-
- /**
- * Natural order of results (failed results are sorted before ok results).
- */
- @Override
- public int compareTo(ExecutionResult otherResult) {
- int retVal = otherResult.getHealthCheckResult().getStatus().compareTo(this.getHealthCheckResult().getStatus());
- if (retVal == 0) {
- retVal = Collator.getInstance().compare(this.getHealthCheckMetadata().getTitle(), otherResult.getHealthCheckMetadata().getTitle());
- }
- return retVal;
- }
-
- long getServiceId() {
- return this.metaData.getServiceId();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/hc/core/impl/executor/ExtendedHealthCheckExecutor.java b/src/main/java/org/apache/sling/hc/core/impl/executor/ExtendedHealthCheckExecutor.java
deleted file mode 100644
index 1b741c1..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/executor/ExtendedHealthCheckExecutor.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.sling.hc.core.impl.executor;
-
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.osgi.framework.ServiceReference;
-
-/**
- * Internal service used by the JMX stuff
- *
- */
-public interface ExtendedHealthCheckExecutor extends HealthCheckExecutor {
-
- HealthCheckExecutionResult execute(ServiceReference ref);
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImpl.java b/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImpl.java
deleted file mode 100644
index b494d2a..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImpl.java
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * 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.sling.hc.core.impl.executor;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.commons.lang3.time.StopWatch;
-import org.apache.sling.commons.threads.ModifiableThreadPoolConfig;
-import org.apache.sling.commons.threads.ThreadPool;
-import org.apache.sling.commons.threads.ThreadPoolManager;
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.ResultLog;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionOptions;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.apache.sling.hc.util.HealthCheckFilter;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Modified;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.metatype.annotations.Designate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.apache.sling.hc.core.impl.executor.HealthCheckExecutorImplConfiguration.LONGRUNNING_FUTURE_THRESHOLD_CRITICAL_DEFAULT_MS;
-import static org.apache.sling.hc.core.impl.executor.HealthCheckExecutorImplConfiguration.RESULT_CACHE_TTL_DEFAULT_MS;
-import static org.apache.sling.hc.core.impl.executor.HealthCheckExecutorImplConfiguration.TIMEOUT_DEFAULT_MS;
-import static org.apache.sling.hc.util.FormattingResultLog.msHumanReadable;
-
-/**
- * Runs health checks for a given list of tags in parallel.
- *
- */
-@Component(
- service = {HealthCheckExecutor.class, ExtendedHealthCheckExecutor.class},
- immediate = true // immediate = true to keep the cache!
-)
-@Designate(
- ocd = HealthCheckExecutorImplConfiguration.class
-)
-public class HealthCheckExecutorImpl implements ExtendedHealthCheckExecutor, ServiceListener {
-
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- private long timeoutInMs;
-
- private long longRunningFutureThresholdForRedMs;
-
- private long resultCacheTtlInMs;
-
- private HealthCheckResultCache healthCheckResultCache = new HealthCheckResultCache();
-
- private final Map<HealthCheckMetadata, HealthCheckFuture> stillRunningFutures = new HashMap<HealthCheckMetadata, HealthCheckFuture>();
-
- @Reference
- private AsyncHealthCheckExecutor asyncHealthCheckExecutor;
-
- @Reference
- private ThreadPoolManager threadPoolManager;
-
- private ThreadPool hcThreadPool;
-
- private BundleContext bundleContext;
-
- @Activate
- protected final void activate(final HealthCheckExecutorImplConfiguration configuration, final BundleContext bundleContext) {
- this.bundleContext = bundleContext;
-
- final ModifiableThreadPoolConfig hcThreadPoolConfig = new ModifiableThreadPoolConfig();
- hcThreadPoolConfig.setMaxPoolSize(25);
- hcThreadPool = threadPoolManager.create(hcThreadPoolConfig, "Health Check Thread Pool");
-
- configure(configuration);
-
- try {
- this.bundleContext.addServiceListener(this, "("
- + Constants.OBJECTCLASS + "=" + HealthCheck.class.getName() + ")");
- } catch (final InvalidSyntaxException ise) {
- // this should really never happen as the expression above is constant
- throw new RuntimeException("Unexpected exception occured.", ise);
- }
- }
-
- @Modified
- protected final void modified(final HealthCheckExecutorImplConfiguration configuration) {
- configure(configuration);
- }
-
- @Deactivate
- protected final void deactivate() {
- threadPoolManager.release(hcThreadPool);
- this.bundleContext.removeServiceListener(this);
- this.bundleContext = null;
- this.healthCheckResultCache.clear();
- }
-
- protected final void configure(final HealthCheckExecutorImplConfiguration configuration) {
- this.timeoutInMs = configuration.timeoutInMs();
- if (this.timeoutInMs <= 0L) {
- this.timeoutInMs = TIMEOUT_DEFAULT_MS;
- }
-
- this.longRunningFutureThresholdForRedMs = configuration.longRunningFutureThresholdForCriticalMs();
- if (this.longRunningFutureThresholdForRedMs <= 0L) {
- this.longRunningFutureThresholdForRedMs = LONGRUNNING_FUTURE_THRESHOLD_CRITICAL_DEFAULT_MS;
- }
-
- this.resultCacheTtlInMs = configuration.resultCacheTtlInMs();
- if (this.resultCacheTtlInMs <= 0L) {
- this.resultCacheTtlInMs = RESULT_CACHE_TTL_DEFAULT_MS;
- }
- }
-
- @Override
- public void serviceChanged(final ServiceEvent event) {
- if ( event.getType() == ServiceEvent.UNREGISTERING ) {
- final Long serviceId = (Long)event.getServiceReference().getProperty(Constants.SERVICE_ID);
- this.healthCheckResultCache.removeCachedResult(serviceId);
- }
- }
-
- @Override
- public List<HealthCheckExecutionResult> execute(HealthCheckSelector selector) {
- return execute(selector, new HealthCheckExecutionOptions());
- }
-
- @Override
- public List<HealthCheckExecutionResult> execute(HealthCheckSelector selector, HealthCheckExecutionOptions options) {
- logger.debug("Starting executing checks for filter selector {} and execution options {}", selector, options);
-
- final HealthCheckFilter filter = new HealthCheckFilter(this.bundleContext);
- try {
- final ServiceReference[] healthCheckReferences = filter.getHealthCheckServiceReferences(selector, options.isCombineTagsWithOr());
-
- return this.execute(healthCheckReferences, options);
- } finally {
- filter.dispose();
- }
- }
-
- /**
- * @see org.apache.sling.hc.api.execution.HealthCheckExecutor#execute(String[])
- */
- @SuppressWarnings("deprecation")
- @Override
- public List<HealthCheckExecutionResult> execute(final String... tags) {
- return execute(/*default options*/new HealthCheckExecutionOptions(), tags);
- }
-
- /**
- * @see org.apache.sling.hc.api.execution.HealthCheckExecutor#execute(HealthCheckExecutionOptions, String...)
- */
- @SuppressWarnings("deprecation")
- @Override
- public List<HealthCheckExecutionResult> execute(HealthCheckExecutionOptions options, final String... tags) {
- return execute(HealthCheckSelector.tags(tags), options);
- }
-
- /**
- * @see org.apache.sling.hc.core.impl.executor.ExtendedHealthCheckExecutor#execute(org.osgi.framework.ServiceReference)
- */
- @Override
- public HealthCheckExecutionResult execute(final ServiceReference ref) {
- final HealthCheckMetadata metadata = this.getHealthCheckMetadata(ref);
- return createResultsForDescriptor(metadata);
- }
-
- /**
- * Execute a set of health checks
- */
- private List<HealthCheckExecutionResult> execute(final ServiceReference[] healthCheckReferences, HealthCheckExecutionOptions options) {
- final StopWatch stopWatch = new StopWatch();
- stopWatch.start();
-
- final List<HealthCheckExecutionResult> results = new ArrayList<HealthCheckExecutionResult>();
- final List<HealthCheckMetadata> healthCheckDescriptors = getHealthCheckMetadata(healthCheckReferences);
-
-
- createResultsForDescriptors(healthCheckDescriptors, results, options);
-
- stopWatch.stop();
- if ( logger.isDebugEnabled() ) {
- logger.debug("Time consumed for all checks: {}", msHumanReadable(stopWatch.getTime()));
- }
- // sort result
- Collections.sort(results, new Comparator<HealthCheckExecutionResult>() {
-
- @Override
- public int compare(final HealthCheckExecutionResult arg0,
- final HealthCheckExecutionResult arg1) {
- return ((ExecutionResult)arg0).compareTo((ExecutionResult)arg1);
- }
-
- });
- return results;
- }
-
- private void createResultsForDescriptors(final List<HealthCheckMetadata> healthCheckDescriptors,
- final List<HealthCheckExecutionResult> results, HealthCheckExecutionOptions options) {
- // -- All methods below check if they can transform a healthCheckDescriptor into a result
- // -- if yes the descriptor is removed from the list and the result added
-
- // get async results
- if (!options.isForceInstantExecution()) {
- asyncHealthCheckExecutor.collectAsyncResults(healthCheckDescriptors, results, healthCheckResultCache);
- }
-
- // reuse cached results where possible
- if (!options.isForceInstantExecution()) {
- healthCheckResultCache.useValidCacheResults(healthCheckDescriptors, results, resultCacheTtlInMs);
- }
-
- // everything else is executed in parallel via futures
- List<HealthCheckFuture> futures = createOrReuseFutures(healthCheckDescriptors);
-
- // wait for futures at most until timeout (but will return earlier if all futures are finished)
- waitForFuturesRespectingTimeout(futures, options);
- collectResultsFromFutures(futures, results);
-
- // respect sticky results if configured via HealthCheck.WARNINGS_STICK_FOR_MINUTES
- appendStickyResultLogIfConfigured(results);
-
- }
-
- private void appendStickyResultLogIfConfigured(List<HealthCheckExecutionResult> results) {
- ListIterator<HealthCheckExecutionResult> resultsIt = results.listIterator();
- while (resultsIt.hasNext()) {
- HealthCheckExecutionResult result = resultsIt.next();
- Long warningsStickForMinutes = result.getHealthCheckMetadata().getWarningsStickForMinutes();
- if (warningsStickForMinutes != null && warningsStickForMinutes > 0) {
- result = healthCheckResultCache.createExecutionResultWithStickyResults(result);
- resultsIt.set(result);
- }
- }
- }
-
- private HealthCheckExecutionResult createResultsForDescriptor(final HealthCheckMetadata metadata) {
- // create result for a single descriptor
-
- // reuse cached results where possible
- HealthCheckExecutionResult result;
-
- result = healthCheckResultCache.getValidCacheResult(metadata, resultCacheTtlInMs);
-
- if ( result == null ) {
- final HealthCheckFuture future;
- synchronized ( this.stillRunningFutures ) {
- future = createOrReuseFuture(metadata);
- }
-
- // wait for futures at most until timeout (but will return earlier if all futures are finished)
- waitForFuturesRespectingTimeout(Collections.singletonList(future), null);
- result = collectResultFromFuture(future);
- }
-
- return result;
- }
-
- /**
- * Create the health check meta data
- */
- private List<HealthCheckMetadata> getHealthCheckMetadata(final ServiceReference... healthCheckReferences) {
- final List<HealthCheckMetadata> descriptors = new LinkedList<HealthCheckMetadata>();
- for (final ServiceReference serviceReference : healthCheckReferences) {
- final HealthCheckMetadata descriptor = getHealthCheckMetadata(serviceReference);
-
- descriptors.add(descriptor);
- }
-
- return descriptors;
- }
-
- /**
- * Create the health check meta data
- */
- private HealthCheckMetadata getHealthCheckMetadata(final ServiceReference healthCheckReference) {
- final HealthCheckMetadata descriptor = new HealthCheckMetadata(healthCheckReference);
- return descriptor;
- }
-
- /**
- * Create or reuse future for the list of health checks
- */
- private List<HealthCheckFuture> createOrReuseFutures(final List<HealthCheckMetadata> healthCheckDescriptors) {
- final List<HealthCheckFuture> futuresForResultOfThisCall = new LinkedList<HealthCheckFuture>();
-
- synchronized ( this.stillRunningFutures ) {
- for (final HealthCheckMetadata md : healthCheckDescriptors) {
-
- futuresForResultOfThisCall.add(createOrReuseFuture(md));
-
- }
- }
- return futuresForResultOfThisCall;
- }
-
- /**
- * Create or reuse future for the health check
- * This method must be synchronized by the caller(!) on stillRunningFutures
- */
- private HealthCheckFuture createOrReuseFuture(final HealthCheckMetadata metadata) {
- HealthCheckFuture future = this.stillRunningFutures.get(metadata);
- if (future != null ) {
- logger.debug("Found a future that is still running for {}", metadata);
- } else {
- logger.debug("Creating future for {}", metadata);
- future = new HealthCheckFuture(metadata, bundleContext, new HealthCheckFuture.Callback() {
-
- @Override
- public void finished(final HealthCheckExecutionResult result) {
- healthCheckResultCache.updateWith(result);
- asyncHealthCheckExecutor.updateWith(result);
- synchronized ( stillRunningFutures ) {
- stillRunningFutures.remove(metadata);
- }
- }
- });
- this.stillRunningFutures.put(metadata, future);
-
- final HealthCheckFuture newFuture = future;
- this.hcThreadPool.execute(new Runnable() {
- @Override
- public void run() {
- newFuture.run();
- synchronized ( stillRunningFutures ) {
- // notify executor threads that newFuture is finished. Wrapping it in another runnable
- // ensures that newFuture.isDone() will return true (if e.g. done in callback above, there are
- // still a few lines of code until the future is really done and hence then the executor thread
- // is sometime notified a bit too early, still receives the result isDone()=false and then waits
- // for another 50ms, even though the future was about to be done one ms later)
- stillRunningFutures.notifyAll();
- }
- }
- });
- }
-
- return future;
- }
-
- /**
- * 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();
- boolean allFuturesDone;
-
- long effectiveTimeout = this.timeoutInMs;
- if (options != null && options.getOverrideGlobalTimeout() > 0) {
- effectiveTimeout = options.getOverrideGlobalTimeout();
- }
-
- if(futuresForResultOfThisCall.isEmpty()) {
- return; // nothing to wait for (usually because of cached results)
- }
-
- do {
- try {
- synchronized (stillRunningFutures) {
- stillRunningFutures.wait(50); // wait for notifications of callbacks of HealthCheckFutures
- }
- } catch (final InterruptedException ie) {
- logger.warn("Unexpected InterruptedException while waiting for healthCheckContributors", ie);
- }
-
- allFuturesDone = true;
- for (final HealthCheckFuture healthCheckFuture : futuresForResultOfThisCall) {
- allFuturesDone &= healthCheckFuture.isDone();
- }
- } while (!allFuturesDone && callExcutionTimeStopWatch.getTime() < effectiveTimeout);
- }
-
- /**
- * Collect the results from all futures
- * @param futuresForResultOfThisCall The list of futures
- * @param results The result collection
- */
- void collectResultsFromFutures(final List<HealthCheckFuture> futuresForResultOfThisCall, final Collection<HealthCheckExecutionResult> results) {
-
- final Set<HealthCheckExecutionResult> resultsFromFutures = new HashSet<HealthCheckExecutionResult>();
-
- final Iterator<HealthCheckFuture> futuresIt = futuresForResultOfThisCall.iterator();
- while (futuresIt.hasNext()) {
- final HealthCheckFuture future = futuresIt.next();
- final HealthCheckExecutionResult result = this.collectResultFromFuture(future);
-
- resultsFromFutures.add(result);
- futuresIt.remove();
- }
-
- logger.debug("Adding {} results from futures", resultsFromFutures.size());
- results.addAll(resultsFromFutures);
- }
-
- /**
- * Collect the result from a single future
- * @param future The future
- * @return The execution result or a result for a reached timeout
- */
- HealthCheckExecutionResult collectResultFromFuture(final HealthCheckFuture future) {
-
- HealthCheckExecutionResult result;
- HealthCheckMetadata hcMetadata = future.getHealthCheckMetadata();
- if (future.isDone()) {
- logger.debug("Health Check is done: {}", hcMetadata);
-
- try {
- result = future.get();
- } catch (final Exception e) {
- logger.warn("Unexpected Exception during future.get(): " + e, e);
- long futureElapsedTimeMs = new Date().getTime() - future.getCreatedTime().getTime();
- result = new ExecutionResult(hcMetadata, Result.Status.HEALTH_CHECK_ERROR,
- "Unexpected Exception during future.get(): " + e, futureElapsedTimeMs, false);
- }
-
- } else {
- logger.debug("Health Check timed out: {}", hcMetadata);
- // Futures must not be cancelled as interrupting a health check might leave the system in invalid state
- // (worst case could be a corrupted repository index if using write operations)
-
- // normally we turn the check into WARN (normal timeout), but if the threshold time for CRITICAL is reached for a certain
- // future we turn the result CRITICAL
- long futureElapsedTimeMs = new Date().getTime() - future.getCreatedTime().getTime();
- FormattingResultLog resultLog = new FormattingResultLog();
- if (futureElapsedTimeMs < this.longRunningFutureThresholdForRedMs) {
- resultLog.warn("Timeout: Check still running after " + msHumanReadable(futureElapsedTimeMs));
- } else {
- resultLog.critical("Timeout: Check still running after " + msHumanReadable(futureElapsedTimeMs)
- + " (exceeding the configured threshold for CRITICAL: "
- + msHumanReadable(this.longRunningFutureThresholdForRedMs) + ")");
- }
-
- // add logs from previous, cached result if exists (using a 1 year TTL)
- HealthCheckExecutionResult lastCachedResult = healthCheckResultCache.getValidCacheResult(hcMetadata, 1000 * 60 * 60 * 24 * 365);
- if (lastCachedResult != null) {
- DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
- resultLog.info("*** Result log of last execution finished at {} after {} ***",
- df.format(lastCachedResult.getFinishedAt()), FormattingResultLog.msHumanReadable(lastCachedResult.getElapsedTimeInMs()));
- for (ResultLog.Entry entry : lastCachedResult.getHealthCheckResult()) {
- resultLog.add(entry);
- }
- }
-
- result = new ExecutionResult(hcMetadata, new Result(resultLog), futureElapsedTimeMs, true);
-
- }
-
- return result;
- }
-
-
- public void setTimeoutInMs(final long timeoutInMs) {
- this.timeoutInMs = timeoutInMs;
- }
-
- public void setLongRunningFutureThresholdForRedMs(
- final long longRunningFutureThresholdForRedMs) {
- this.longRunningFutureThresholdForRedMs = longRunningFutureThresholdForRedMs;
- }
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImplConfiguration.java b/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImplConfiguration.java
deleted file mode 100644
index dbf79d2..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImplConfiguration.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.sling.hc.core.impl.executor;
-
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-@ObjectClassDefinition(
- name = "Apache Sling Health Check Executor",
- description = "Runs health checks for a given list of tags in parallel."
-)
-@interface HealthCheckExecutorImplConfiguration {
-
- long TIMEOUT_DEFAULT_MS = 2000L;
-
- long LONGRUNNING_FUTURE_THRESHOLD_CRITICAL_DEFAULT_MS = 1000L * 60 * 5;
-
- long RESULT_CACHE_TTL_DEFAULT_MS = 1000L * 2;
-
- @AttributeDefinition(
- name = "Timeout",
- description = "Timeout in ms until a check is marked as timed out"
- )
- long timeoutInMs() default TIMEOUT_DEFAULT_MS;
-
- @AttributeDefinition(
- name = "Timeout threshold for CRITICAL",
- description = "Threshold in ms until a check is marked as 'exceedingly' timed out and will marked CRITICAL instead of WARN only"
- )
- long longRunningFutureThresholdForCriticalMs() default LONGRUNNING_FUTURE_THRESHOLD_CRITICAL_DEFAULT_MS;
-
- @AttributeDefinition(
- name = "Results Cache TTL in Ms",
- description = "Result Cache time to live - results will be cached for the given time"
- )
- long resultCacheTtlInMs() default RESULT_CACHE_TTL_DEFAULT_MS;
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckFuture.java b/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckFuture.java
deleted file mode 100644
index dcf8816..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckFuture.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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.sling.hc.core.impl.executor;
-
-import static org.apache.sling.hc.util.FormattingResultLog.msHumanReadable;
-
-import java.util.Date;
-import java.util.concurrent.Callable;
-import java.util.concurrent.FutureTask;
-
-import org.apache.commons.lang3.time.StopWatch;
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Future to be able to schedule a health check for parallel execution.
- *
- */
-class HealthCheckFuture extends FutureTask<ExecutionResult> {
-
- public interface Callback {
- public void finished(final HealthCheckExecutionResult result);
- }
-
- private final static Logger LOG = LoggerFactory.getLogger(HealthCheckFuture.class);
-
- private final HealthCheckMetadata metadata;
- private final Date createdTime;
-
- HealthCheckFuture(final HealthCheckMetadata metadata, final BundleContext bundleContext, final Callback callback) {
- super(new Callable<ExecutionResult>() {
- @Override
- public ExecutionResult call() throws Exception {
- Thread.currentThread().setName("HealthCheck " + metadata.getTitle());
- LOG.debug("Starting check {}", metadata);
-
- final StopWatch stopWatch = new StopWatch();
- stopWatch.start();
- Result resultFromHealthCheck = null;
- ExecutionResult executionResult = null;
-
- final HealthCheck healthCheck = (HealthCheck) bundleContext.getService(metadata.getServiceReference());
-
- try {
- if (healthCheck != null) {
- resultFromHealthCheck = healthCheck.execute();
- } else {
- throw new IllegalStateException("Service for " + metadata + " is gone");
- }
-
- } catch (final Exception e) {
- resultFromHealthCheck = new Result(Result.Status.CRITICAL, "Exception during execution of '" + metadata.getName() + "': " + e, e);
- } finally {
- // unget service ref
- bundleContext.ungetService(metadata.getServiceReference());
-
- // update result with information about this run
- stopWatch.stop();
- long elapsedTime = stopWatch.getTime();
- if (resultFromHealthCheck != null) {
- // wrap the result in an execution result
- executionResult = new ExecutionResult(metadata, resultFromHealthCheck, elapsedTime);
- }
- LOG.debug("Time consumed for {}: {}", metadata, msHumanReadable(elapsedTime));
- }
-
- callback.finished(executionResult);
- Thread.currentThread().setName("HealthCheck idle");
- return executionResult;
- }
- });
- this.createdTime = new Date();
- this.metadata = metadata;
-
- }
-
- Date getCreatedTime() {
- return this.createdTime;
- }
-
- public HealthCheckMetadata getHealthCheckMetadata() {
- return metadata;
- }
-
- @Override
- public String toString() {
- return "[Future for " + this.metadata + ", createdTime=" + this.createdTime + "]";
- }
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckResultCache.java b/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckResultCache.java
deleted file mode 100644
index 7efedb6..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckResultCache.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * 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.sling.hc.core.impl.executor;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.Result.Status;
-import org.apache.sling.hc.api.ResultLog;
-import org.apache.sling.hc.api.ResultLog.Entry;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Caches health check results.
- */
-public class HealthCheckResultCache {
-
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
-
- private static final List<Status> NOT_OK_STATUS_VALUES = Arrays.asList(Status.WARN, Status.CRITICAL, Status.HEALTH_CHECK_ERROR);
-
- /**
- * The map holding the cached results.
- */
- private final Map<Long, HealthCheckExecutionResult> cache = new ConcurrentHashMap<Long, HealthCheckExecutionResult>();
-
- @SuppressWarnings("serial")
- private final Map<Result.Status, Map<Long, HealthCheckExecutionResult>> cacheOfNotOkResults = new ConcurrentHashMap<Result.Status, Map<Long, HealthCheckExecutionResult>>() {
- {
- for (Status status : NOT_OK_STATUS_VALUES) {
- put(status, new ConcurrentHashMap<Long, HealthCheckExecutionResult>());
- }
- }
- };
-
- /**
- * Update the cache with the result
- */
- public void updateWith(HealthCheckExecutionResult result) {
- final ExecutionResult executionResult = (ExecutionResult) result;
- cache.put(executionResult.getServiceId(), result);
-
- Status status = executionResult.getHealthCheckResult().getStatus();
- if (status.ordinal() >= Result.Status.WARN.ordinal()) {
- logger.debug("Caching {} result for HC {}", status, executionResult.getServiceId());
- cacheOfNotOkResults.get(status).put(executionResult.getServiceId(), result);
- }
- }
-
- /**
- * Get the valid cache results
- */
- public void useValidCacheResults(final List<HealthCheckMetadata> metadatas,
- final Collection<HealthCheckExecutionResult> results,
- final long resultCacheTtlInMs) {
- final Set<HealthCheckExecutionResult> cachedResults = new TreeSet<HealthCheckExecutionResult>();
- final Iterator<HealthCheckMetadata> checksIt = metadatas.iterator();
- while (checksIt.hasNext()) {
- final HealthCheckMetadata md = checksIt.next();
- final HealthCheckExecutionResult result = getValidCacheResult(md, resultCacheTtlInMs);
- if (result != null) {
- cachedResults.add(result);
- checksIt.remove();
- }
- }
- logger.debug("Adding {} results from cache", cachedResults.size());
- results.addAll(cachedResults);
- }
-
- /**
- * Return the cached result if it's still valid.
- */
- public HealthCheckExecutionResult getValidCacheResult(final HealthCheckMetadata metadata,
- final long resultCacheTtlInMs) {
- return get(metadata, resultCacheTtlInMs);
- }
-
- private HealthCheckExecutionResult get(final HealthCheckMetadata metadata, final long globalResultCacheTtlInMs) {
- final Long key = metadata.getServiceId();
- final HealthCheckExecutionResult cachedResult = cache.get(key);
- if (cachedResult != null) {
- Date finishedAt = cachedResult.getFinishedAt();
- if (finishedAt == null) {
- // never cache without proper meta data -> remove it
- cache.remove(key);
- return null;
- }
-
- long effectiveTtl = getEffectiveTtl(metadata, globalResultCacheTtlInMs);
- long validUntilLong = finishedAt.getTime() + effectiveTtl;
- if(validUntilLong < 0) { // if Long.MAX_VALUE is configured, this can become negative
- validUntilLong = Long.MAX_VALUE;
- }
- Date validUntil = new Date(validUntilLong);
- Date now = new Date();
- if (validUntil.after(now)) {
- logger.debug("Cache hit: validUntil={} cachedResult={}", validUntil, cachedResult);
- return cachedResult;
- } else {
- logger.debug("Outdated result: validUntil={} cachedResult={}", validUntil, cachedResult);
- // not removing result for key as out-dated results are shown for timed out checks if available
- }
- }
-
- // null => no cache hit
- return null;
- }
-
- /**
- * Obtains the effective TTL for a given Metadata descriptor.
- *
- * @param metadata Metadata descriptor of health check
- * @param globalTtl TTL from service configuration of health check executor (used as default)
- * @return effective TTL
- */
- private long getEffectiveTtl(HealthCheckMetadata metadata, long globalTtl) {
- final long ttl;
- Long hcTtl = metadata.getResultCacheTtlInMs();
- if (hcTtl != null && hcTtl > 0) {
- ttl = hcTtl;
- } else {
- ttl = globalTtl;
- }
- return ttl;
- }
-
- /**
- * Creates a new execution result
- * @param origResult
- * @return
- */
- public HealthCheckExecutionResult createExecutionResultWithStickyResults(HealthCheckExecutionResult origResult) {
- HealthCheckExecutionResult result = origResult;
-
- HealthCheckMetadata healthCheckMetadata = origResult.getHealthCheckMetadata();
- Long warningsStickForMinutes = healthCheckMetadata.getWarningsStickForMinutes();
- if (warningsStickForMinutes != null) {
- logger.debug("Taking into account sticky results (up to {} min old) for health check ", warningsStickForMinutes, healthCheckMetadata.getName());
- List<HealthCheckExecutionResult> nonOkResultsFromPast = new ArrayList<HealthCheckExecutionResult>();
- long cutOffTime = System.currentTimeMillis() - (warningsStickForMinutes * 60 * 1000);
- for (Status status : NOT_OK_STATUS_VALUES) {
- long hcServiceId = ((ExecutionResult) origResult).getServiceId();
- HealthCheckExecutionResult nonOkResultFromPast = cacheOfNotOkResults.get(status).get(hcServiceId);
- if (nonOkResultFromPast == null) {
- logger.debug("no sticky result in cache for HC {}", hcServiceId);
- continue;
- }
- if(nonOkResultFromPast == origResult) {
- logger.debug("result already in cache: {} for HC {}, not adding sticky result", origResult, hcServiceId);
- continue;
- }
- long pastHcTime = nonOkResultFromPast.getFinishedAt().getTime();
- logger.debug("Time of old {} result: {}", status, pastHcTime);
- logger.debug("Cut off time: {}", cutOffTime);
- if (pastHcTime > cutOffTime) {
- logger.debug("Found sticky result: {}", nonOkResultFromPast);
- nonOkResultsFromPast.add(nonOkResultFromPast);
- }
- }
-
- if (!nonOkResultsFromPast.isEmpty()) {
- ResultLog resultLog = new ResultLog();
- resultLog.add(new Entry(Result.Status.INFO, "*** Current Result ***"));
- for (ResultLog.Entry entry : origResult.getHealthCheckResult()) {
- resultLog.add(entry);
- }
- DateFormat df = new SimpleDateFormat("HH:mm:ss.SSS");
- for (HealthCheckExecutionResult nonOkResultFromPast : nonOkResultsFromPast) {
- Status status = nonOkResultFromPast.getHealthCheckResult().getStatus();
- resultLog.add(
- new Entry(Result.Status.WARN, "*** Sticky Result " + status + " from " + df.format(nonOkResultFromPast.getFinishedAt()) + " ***"));
- for (ResultLog.Entry entry : nonOkResultFromPast.getHealthCheckResult()) {
- resultLog.add(entry);
- }
- }
- result = new ExecutionResult(healthCheckMetadata, new Result(resultLog), origResult.getElapsedTimeInMs());
- }
- }
-
- return result;
- }
-
- /**
- * Clear the whole cache
- */
- public void clear() {
- this.cache.clear();
- for (Status status : NOT_OK_STATUS_VALUES) {
- cacheOfNotOkResults.get(status).clear();
- }
- }
-
- /**
- * Remove entry from cache
- */
- public void removeCachedResult(final Long serviceId) {
- this.cache.remove(serviceId);
- for (Status status : NOT_OK_STATUS_VALUES) {
- cacheOfNotOkResults.get(status).remove(serviceId);
- }
- }
-
- @Override
- public String toString() {
- return "[HealthCheckResultCache size=" + cache.size() + "]";
- }
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/servlet/HealthCheckExecutorServlet.java b/src/main/java/org/apache/sling/hc/core/impl/servlet/HealthCheckExecutorServlet.java
deleted file mode 100644
index 422702c..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/servlet/HealthCheckExecutorServlet.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * 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.sling.hc.core.impl.servlet;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-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.sling.commons.osgi.PropertiesUtil;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.Result.Status;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionOptions;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.osgi.service.component.ComponentContext;
-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.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.http.HttpService;
-import org.osgi.service.metatype.annotations.Designate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Servlet that triggers the health check executor to return results via http.
- *
- * Parameters:
- * <ul>
- * <li>tags: The health check tags to take into account
- * <li>format: html|json|jsonp
- * <li>includeDebug: If true, debug messages from result log are included.
- * <li>callback: For jsonp, the JS callback function name (defaults to "processHealthCheckResults")
- * <li>httpStatus: health check status to http status mapping in format httpStatus=WARN:418,CRITICAL:503,HEALTH_CHECK_ERROR:500.
- * </ul>
- *
- * For omitted health check status values the next best code will be used (e.g. for httpStatus=CRITICAL:503 a result WARN will
- * return 200, CRITICAL 503 and HEALTH_CHECK_ERROR also 503). By default all requests answer with an http status of 200.
- * <p>
- * Useful in combination with load balancers.
- * <p>
- * NOTE: This servlet registers directly (low-level) at the HttpService and is not processed by sling (better performance, fewer dependencies, no authentication required, 503 can be sent without the progress tracker information). */
-@Component(
- configurationPolicy = ConfigurationPolicy.REQUIRE
-)
-@Designate(
- ocd = HealthCheckExecutorServletConfiguration.class
-)
-public class HealthCheckExecutorServlet extends HttpServlet {
- private static final long serialVersionUID = 8013511523994541848L;
-
- private static final Logger LOG = LoggerFactory.getLogger(HealthCheckExecutorServlet.class);
- public static final String PARAM_SPLIT_REGEX = "[,;]+";
-
- static class Param {
- final String name;
- final String description;
- Param(String n, String d) {
- name = n;
- description = d;
- }
- }
-
- static final Param PARAM_TAGS = new Param("tags",
- "Comma-separated list of health checks tags to select - can also be specified via path, e.g. /system/health/tag1,tag2.json. Exclusions can be done by prepending '-' to the tag name");
- static final Param PARAM_FORMAT = new Param("format", "Output format, html|json|jsonp|txt - an extension in the URL overrides this");
- static final Param PARAM_HTTP_STATUS = new Param("httpStatus", "Specify HTTP result code, for example"
- + " CRITICAL:503 (status 503 if result >= CRITICAL)"
- + " or CRITICAL:503,HEALTH_CHECK_ERROR:500,OK:418 for more specific HTTP status");
-
- static final Param PARAM_COMBINE_TAGS_WITH_OR = new Param("combineTagsWithOr", "Combine tags with OR, active by default. Set to false to combine with AND");
- static final Param PARAM_FORCE_INSTANT_EXECUTION = new Param("forceInstantExecution",
- "If true, forces instant execution by executing async health checks directly, circumventing the cache (2sec by default) of the HealthCheckExecutor");
- static final Param PARAM_OVERRIDE_GLOBAL_TIMEOUT = new Param("timeout",
- "(msec) a timeout status is returned for any health check still running after this period. Overrides the default HealthCheckExecutor timeout");
-
- static final Param PARAM_INCLUDE_DEBUG = new Param("hcDebug", "Include the DEBUG output of the Health Checks");
-
- static final Param PARAM_NAMES = new Param("names", "Comma-separated list of health check names to select. Exclusions can be done by prepending '-' to the health check name");
-
- static final String JSONP_CALLBACK_DEFAULT = "processHealthCheckResults";
- static final Param PARAM_JSONP_CALLBACK = new Param("callback", "name of the JSONP callback function to use, defaults to " + JSONP_CALLBACK_DEFAULT);
-
- static final Param [] PARAM_LIST = { PARAM_TAGS, PARAM_NAMES, PARAM_FORMAT, PARAM_HTTP_STATUS, PARAM_COMBINE_TAGS_WITH_OR,
- PARAM_FORCE_INSTANT_EXECUTION, PARAM_OVERRIDE_GLOBAL_TIMEOUT, PARAM_INCLUDE_DEBUG, PARAM_JSONP_CALLBACK};
-
- static final String FORMAT_HTML = "html";
- static final String FORMAT_JSON = "json";
- static final String FORMAT_JSONP = "jsonp";
- static final String FORMAT_TXT = "txt";
- static final String FORMAT_VERBOSE_TXT = "verbose.txt";
-
- private static final String CONTENT_TYPE_HTML = "text/html";
- private static final String CONTENT_TYPE_TXT = "text/plain";
- private static final String CONTENT_TYPE_JSON = "application/json";
- private static final String CONTENT_TYPE_JSONP = "application/javascript";
- private static final String STATUS_HEADER_NAME = "X-Health";
-
- private static final String CACHE_CONTROL_KEY = "Cache-control";
- private static final String CACHE_CONTROL_VALUE = "no-cache";
-
- private String[] servletPaths;
-
- private boolean disabled;
-
- private String servletPath;
-
- private String corsAccessControlAllowOrigin;
-
- private static final String CORS_ORIGIN_HEADER_NAME = "Access-Control-Allow-Origin";
-
-
- @Reference
- private HttpService httpService;
-
- @Reference
- HealthCheckExecutor healthCheckExecutor;
-
- @Reference
- ResultHtmlSerializer htmlSerializer;
-
- @Reference
- ResultJsonSerializer jsonSerializer;
-
- @Reference
- ResultTxtSerializer txtSerializer;
-
- @Reference
- ResultTxtVerboseSerializer verboseTxtSerializer;
-
- @Activate
- protected final void activate(final HealthCheckExecutorServletConfiguration configuration) {
- this.servletPath = configuration.servletPath();
- this.disabled = configuration.disabled();
- this.corsAccessControlAllowOrigin = configuration.cors_accessControlAllowOrigin();
-
- Map<String, HttpServlet> servletsToRegister = new LinkedHashMap<String, HttpServlet>();
- servletsToRegister.put(this.servletPath, this);
- servletsToRegister.put(this.servletPath + "." + FORMAT_HTML, new ProxyServlet(FORMAT_HTML));
- servletsToRegister.put(this.servletPath + "." + FORMAT_JSON, new ProxyServlet(FORMAT_JSON));
- servletsToRegister.put(this.servletPath + "." + FORMAT_JSONP, new ProxyServlet(FORMAT_JSONP));
- servletsToRegister.put(this.servletPath + "." + FORMAT_TXT, new ProxyServlet(FORMAT_TXT));
- servletsToRegister.put(this.servletPath + "." + FORMAT_VERBOSE_TXT, new ProxyServlet(FORMAT_VERBOSE_TXT));
-
- if (disabled) {
- LOG.info("Health Check Servlet is disabled by configuration");
- return;
- }
-
- for (final Map.Entry<String, HttpServlet> servlet : servletsToRegister.entrySet()) {
- try {
- LOG.debug("Registering {} to path {}", getClass().getSimpleName(), servlet.getKey());
- this.httpService.registerServlet(servlet.getKey(), servlet.getValue(), null, null);
- } catch (Exception e) {
- LOG.error("Could not register health check servlet: " + e, e);
- }
- }
- this.servletPaths = servletsToRegister.keySet().toArray(new String[0]);
-
- }
-
- @Deactivate
- public void deactivate(final ComponentContext componentContext) {
- if (disabled || this.servletPaths == null) {
- return;
- }
-
- for (final String servletPath : this.servletPaths) {
- try {
- LOG.debug("Unregistering path {}", servletPath);
- this.httpService.unregister(servletPath);
- } catch (Exception e) {
- LOG.error("Could not unregister health check servlet: " + e, e);
- }
- }
- this.servletPaths = null;
- }
-
- protected void doGet(final HttpServletRequest request, final HttpServletResponse response, final 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>();
-
- if (StringUtils.isNotBlank(pathTokensStr)) {
- String[] pathTokens = pathTokensStr.split(PARAM_SPLIT_REGEX);
- for (String pathToken : pathTokens) {
- if (pathToken.indexOf(' ') >= 0) {
- // token contains space. assume it is a name
- names.add(pathToken);
- } else {
- tags.add(pathToken);
- }
- }
- }
- 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));
- }
- selector.withTags(tags.toArray(new String[0]));
-
- 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));
- }
- selector.withNames(names.toArray(new String[0]));
-
- final Boolean includeDebug = Boolean.valueOf(request.getParameter(PARAM_INCLUDE_DEBUG.name));
- final Map<Result.Status, Integer> statusMapping = request.getParameter(PARAM_HTTP_STATUS.name) != null ? getStatusMapping(request
- .getParameter(PARAM_HTTP_STATUS.name)) : null;
-
- HealthCheckExecutionOptions executionOptions = new HealthCheckExecutionOptions();
- executionOptions.setCombineTagsWithOr(Boolean.valueOf(StringUtils.defaultString(request.getParameter(PARAM_COMBINE_TAGS_WITH_OR.name), "true")));
- 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));
- }
-
- List<HealthCheckExecutionResult> executionResults = this.healthCheckExecutor.execute(selector, executionOptions);
-
- Result.Status mostSevereStatus = Result.Status.DEBUG;
- for (HealthCheckExecutionResult executionResult : executionResults) {
- Status status = executionResult.getHealthCheckResult().getStatus();
- if (status.ordinal() > mostSevereStatus.ordinal()) {
- mostSevereStatus = status;
- }
- }
- Result overallResult = new Result(mostSevereStatus, "Overall status " + mostSevereStatus);
-
- sendNoCacheHeaders(response);
- sendCorsHeaders(response);
-
- if (statusMapping != null) {
- Integer httpStatus = statusMapping.get(overallResult.getStatus());
- response.setStatus(httpStatus);
- }
-
- if (FORMAT_HTML.equals(format)) {
- sendHtmlResponse(overallResult, executionResults, request, response, includeDebug);
- } 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);
- 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 {
- response.setContentType("text/plain");
- response.getWriter().println("Invalid format " + format + " - supported formats: html|json|jsonp|txt|verbose.txt");
- }
- }
-
- @Override
- protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
- String pathInfo = request.getPathInfo();
- 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);
- }
- doGet(request, response, format);
- }
-
- private 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 };
- }
- }
- return new String[] { pathInfo, null };
- }
-
- private void sendTxtResponse(final Result overallResult, final HttpServletResponse response, boolean verbose,
- List<HealthCheckExecutionResult> executionResults, boolean includeDebug) throws IOException {
- response.setContentType(CONTENT_TYPE_TXT);
- response.setCharacterEncoding("UTF-8");
- if (verbose) {
- response.getWriter().write(verboseTxtSerializer.serialize(overallResult, executionResults, includeDebug));
- } else {
- response.getWriter().write(txtSerializer.serialize(overallResult));
- }
- }
-
- private void sendJsonResponse(final Result overallResult, final List<HealthCheckExecutionResult> executionResults, final String jsonpCallback,
- final HttpServletResponse response, boolean includeDebug)
- throws IOException {
- if (StringUtils.isNotBlank(jsonpCallback)) {
- response.setContentType(CONTENT_TYPE_JSONP);
- } else {
- response.setContentType(CONTENT_TYPE_JSON);
- }
- response.setCharacterEncoding("UTF-8");
-
- String resultJson = this.jsonSerializer.serialize(overallResult, executionResults, jsonpCallback, includeDebug);
- PrintWriter writer = response.getWriter();
- writer.append(resultJson);
- }
-
- private void sendHtmlResponse(final Result overallResult, final List<HealthCheckExecutionResult> executionResults,
- final HttpServletRequest request, final HttpServletResponse response, boolean includeDebug)
- throws IOException {
- response.setContentType(CONTENT_TYPE_HTML);
- response.setCharacterEncoding("UTF-8");
- response.setHeader(STATUS_HEADER_NAME, overallResult.toString());
- response.getWriter().append(this.htmlSerializer.serialize(overallResult, executionResults, getHtmlHelpText(), includeDebug));
- }
-
- private void sendNoCacheHeaders(final HttpServletResponse response) {
- response.setHeader(CACHE_CONTROL_KEY, CACHE_CONTROL_VALUE);
- }
-
- private void sendCorsHeaders(final HttpServletResponse response) {
- if (StringUtils.isNotBlank(corsAccessControlAllowOrigin)) {
- response.setHeader(CORS_ORIGIN_HEADER_NAME, corsAccessControlAllowOrigin);
- }
- }
-
- 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) throws ServletException {
- Map<Result.Status, Integer> statusMapping = new HashMap<Result.Status, Integer>();
- try {
- String[] bits = mappingStr.split("[,]");
- for (String bit : bits) {
- String[] tuple = bit.split("[:]");
- statusMapping.put(Result.Status.valueOf(tuple[0]), Integer.parseInt(tuple[1]));
- }
- } catch (Exception e) {
- throw new ServletException("Invalid parameter httpStatus=" + mappingStr + " " + e, e);
- }
-
- if (!statusMapping.containsKey(Result.Status.OK)) {
- statusMapping.put(Result.Status.OK, 200);
- }
- if (!statusMapping.containsKey(Result.Status.WARN)) {
- statusMapping.put(Result.Status.WARN, statusMapping.get(Result.Status.OK));
- }
- if (!statusMapping.containsKey(Result.Status.CRITICAL)) {
- statusMapping.put(Result.Status.CRITICAL, statusMapping.get(Result.Status.WARN));
- }
- if (!statusMapping.containsKey(Result.Status.HEALTH_CHECK_ERROR)) {
- statusMapping.put(Result.Status.HEALTH_CHECK_ERROR, statusMapping.get(Result.Status.CRITICAL));
- }
- return statusMapping;
- }
-
- private class ProxyServlet extends HttpServlet {
-
- private final String format;
-
- private ProxyServlet(final String format) {
- this.format = format;
- }
-
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- HealthCheckExecutorServlet.this.doGet(req, resp, format);
- }
- }
-
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/servlet/HealthCheckExecutorServletConfiguration.java b/src/main/java/org/apache/sling/hc/core/impl/servlet/HealthCheckExecutorServletConfiguration.java
deleted file mode 100644
index 2bbf456..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/servlet/HealthCheckExecutorServletConfiguration.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.sling.hc.core.impl.servlet;
-
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-@ObjectClassDefinition(
- name = "Apache Sling Health Check Executor Servlet",
- description = "Serializes health check results into html or json format"
-)
-@interface HealthCheckExecutorServletConfiguration {
-
- 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 = "CORS Access-Control-Allow-Origin",
- description = "Sets the Access-Control-Allow-Origin CORS header. If blank no header is sent."
- )
- String cors_accessControlAllowOrigin() default "*";
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultHtmlSerializer.java b/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultHtmlSerializer.java
deleted file mode 100644
index d3c560b..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultHtmlSerializer.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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.sling.hc.core.impl.servlet;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Dictionary;
-import java.util.List;
-
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.ResultLog.Entry;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-
-/** Serializes health check results into html format. */
-@Component(
- service = ResultHtmlSerializer.class
-)
-public class ResultHtmlSerializer {
-
- private String styleString;
-
- @Activate
- protected final void activate(final ResultHtmlSerializerConfiguration configuration) {
- this.styleString = configuration.styleString();
- }
-
- public String serialize(final Result overallResult, final List<HealthCheckExecutionResult> executionResults, String escapedHelpText, boolean includeDebug) {
-
- StringWriter stringWriter = new StringWriter();
- PrintWriter writer = new PrintWriter(stringWriter);
-
- writer.println("<html><head><title>System Health</title>" +
- "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /><style>" + styleString +
- "</style></head><body><h1>System Health</h1>");
-
- writer.println("<p><span class=\"" + getClassForStatus(overallResult.getStatus()) + "\"><strong>Overall Result: "
- + overallResult.getStatus() + "</strong></span></p>");
-
- final DateFormat dfShort = new SimpleDateFormat("HH:mm:ss.SSS");
- final DateFormat dfLong = new SimpleDateFormat("yyyy-MM-dd HH:mm");
-
- writer.println("<table id=\"healthCheckResults\" cellspacing=\"0\">");
- writer.println(
- "<thead><tr><th>Health Check <span style='color:gray'>(tags)</span></th><th>Status</th><th>Log</th><th>Finished At</th><th>Time</th></tr></thead>");
- for (HealthCheckExecutionResult executionResult : executionResults) {
- Result result = executionResult.getHealthCheckResult();
- 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()) + "");
- if (hasTags) {
- writer.println("<br/><span style='color:gray'>" + StringEscapeUtils.escapeHtml4(StringUtils.join(tags, ", ")) + "</span>");
- }
- writer.println("</p></td>");
- writer.println("<td style='font-weight:bold;'>" + StringEscapeUtils.escapeHtml4(result.getStatus().toString()) + "</td>");
- writer.println("<td>");
- boolean isFirst = true;
-
- boolean isSingleResult = isSingleResult(result);
-
- for (Entry entry : result) {
- if(!includeDebug && entry.getStatus()==Result.Status.DEBUG) {
- continue;
- }
-
- if (isFirst) {
- isFirst = false;
- } else {
- writer.println("<br/>\n");
- }
-
- boolean showStatus = !isSingleResult && entry.getStatus()!=Result.Status.DEBUG && entry.getStatus() !=Result.Status.INFO;
-
- String message = StringEscapeUtils.escapeHtml4(entry.getMessage());
- if(entry.getStatus()==Result.Status.DEBUG) {
- message = "<span style='color:gray'/>"+message + "</span>";
- }
- writer.println((showStatus ? StringEscapeUtils.escapeHtml4(entry.getStatus().toString()) + " " : "") + message);
-
- Exception exception = entry.getException();
- if (exception != null) {
- writer.println("<span style='width:20px'/>" + StringEscapeUtils.escapeHtml4(exception.toString()));
- writer.println("<!--");
- exception.printStackTrace(writer);
- writer.println("-->");
- }
- }
- writer.println("</td>");
- Date finishedAt = executionResult.getFinishedAt();
- writer.println("<td>" + (isToday(finishedAt) ? dfShort.format(finishedAt) : dfLong.format(finishedAt)) + "</td>");
- writer.println("<td>" + FormattingResultLog.msHumanReadable(executionResult.getElapsedTimeInMs()) + "</td>");
-
- writer.println("</tr>");
- }
- writer.println("</table>");
-
- writer.println("<div class='helpText'>");
- writer.println(escapedHelpText);
- writer.println("</div>");
- writer.println("</body></html>");
-
- return stringWriter.toString();
-
- }
-
- private String getClassForStatus(final Result.Status status) {
- return "status" + status.name();
- }
-
- private boolean isSingleResult(final Result result) {
- int count = 0;
- for (Entry entry : result) {
- count++;
- if (count > 1) {
- return false;
- }
- }
- return true;
- }
-
- private boolean isToday(Date date) {
- Calendar cal1 = Calendar.getInstance();
- Calendar cal2 = Calendar.getInstance();
- cal2.setTime(date);
- boolean isToday = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
- cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
- return isToday;
-
- }
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultHtmlSerializerConfiguration.java b/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultHtmlSerializerConfiguration.java
deleted file mode 100644
index 017dfc3..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultHtmlSerializerConfiguration.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.sling.hc.core.impl.servlet;
-
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-@ObjectClassDefinition(
- name = "Apache Sling Health Check Result HTML Serializer",
- description = "Serializer for health check results in HTML format"
-)
-@interface ResultHtmlSerializerConfiguration {
-
- String CSS_STYLE_DEFAULT = "body { font-size:12px; font-family:arial,verdana,sans-serif;background-color:#FFFDF1; }\n"
- + "h1 { font-size:20px;}\n"
- + "table { font-size:12px; border:#ccc 1px solid; border-radius:3px; }\n"
- + "table th { padding:5px; text-align: left; background: #ededed; }\n"
- + "table td { padding:5px; border-top: 1px solid #ffffff; border-bottom:1px solid #e0e0e0; border-left: 1px solid #e0e0e0; }\n"
- + ".statusOK { background-color:#CCFFCC;}\n"
- + ".statusWARN { background-color:#FFE569;}\n"
- + ".statusCRITICAL { background-color:#F0975A;}\n"
- + ".statusHEALTH_CHECK_ERROR { background-color:#F16D4E;}\n"
- + ".helpText { color:grey; font-size:80%; }\n";
-
- @AttributeDefinition(
- name = "CSS Style",
- description = "CSS Style - can be configured to change the look and feel of the html result page."
- )
- String styleString() default CSS_STYLE_DEFAULT;
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultJsonSerializer.java b/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultJsonSerializer.java
deleted file mode 100644
index 1616ce7..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultJsonSerializer.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.sling.hc.core.impl.servlet;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.List;
-
-import javax.json.Json;
-import javax.json.JsonArrayBuilder;
-import javax.json.JsonException;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.ResultLog;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.osgi.service.component.annotations.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Serializes health check results into json format. */
-@Component(
- service = ResultJsonSerializer.class
-)
-public class ResultJsonSerializer {
-
- private static final Logger LOG = LoggerFactory.getLogger(ResultJsonSerializer.class);
-
- static final String OVERALL_RESULT_KEY = "OverallResult";
-
- public String serialize(final Result overallResult, final List<HealthCheckExecutionResult> executionResults, final String jsonpCallback,
- boolean includeDebug) {
-
- LOG.debug("Sending json response... ");
-
- JsonObjectBuilder result = Json.createObjectBuilder();
- try {
-
- result.add("overallResult", overallResult.getStatus().toString());
- JsonArrayBuilder resultsJsonArr = Json.createArrayBuilder();
-
- for (HealthCheckExecutionResult healthCheckResult : executionResults) {
- resultsJsonArr.add(getJsonForSimpleResult(healthCheckResult, includeDebug));
- }
-
- result.add("results", resultsJsonArr);
- } catch (JsonException e) {
- LOG.info("Could not serialize health check result: " + e, e);
- }
-
- StringWriter writer = new StringWriter();
- Json.createGenerator(writer).write(result.build()).close();
-
- String resultStr = writer.toString();
-
- if (StringUtils.isNotBlank(jsonpCallback)) {
- resultStr = jsonpCallback + "(" + resultStr + ");";
- }
-
- return resultStr;
-
- }
-
- private JsonObject getJsonForSimpleResult(final HealthCheckExecutionResult healthCheckResult, boolean includeDebug) {
-
- JsonObjectBuilder result = Json.createObjectBuilder();
-
- result.add("name", healthCheckResult.getHealthCheckMetadata().getName());
- result.add("status", healthCheckResult.getHealthCheckResult().getStatus().toString());
- result.add("timeInMs", healthCheckResult.getElapsedTimeInMs());
- result.add("finishedAt", healthCheckResult.getFinishedAt().toString());
- JsonArrayBuilder tagsArray = Json.createArrayBuilder();
- for (final String tag : healthCheckResult.getHealthCheckMetadata().getTags()) {
- tagsArray.add(tag);
- }
- result.add("tags", tagsArray);
-
- JsonArrayBuilder messagesArr = Json.createArrayBuilder();
-
- for (ResultLog.Entry entry : healthCheckResult.getHealthCheckResult()) {
- if (!includeDebug && entry.getStatus() == Result.Status.DEBUG) {
- continue;
- }
- JsonObjectBuilder jsonEntry = Json.createObjectBuilder();
- jsonEntry.add("status", entry.getStatus().toString());
- jsonEntry.add("message", entry.getMessage());
- Exception exception = entry.getException();
- if (exception != null) {
- StringWriter stringWriter = new StringWriter();
- exception.printStackTrace(new PrintWriter(stringWriter));
- jsonEntry.add("exception", stringWriter.toString());
- }
- messagesArr.add(jsonEntry);
- }
-
- result.add("messages", messagesArr);
-
-
- return result.build();
- }
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultTxtSerializer.java b/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultTxtSerializer.java
deleted file mode 100644
index 9c4d673..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultTxtSerializer.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.sling.hc.core.impl.servlet;
-
-import org.apache.sling.hc.api.Result;
-import org.osgi.service.component.annotations.Component;
-
-/** Serializes health check results into a simple text message (ideal to be used by a load balancer that would discard
- * further information). */
-@Component(
- service = ResultTxtSerializer.class
-)
-public class ResultTxtSerializer {
- public String serialize(final Result overallResult) {
- return overallResult.getStatus().toString();
- }
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultTxtVerboseSerializer.java b/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultTxtVerboseSerializer.java
deleted file mode 100644
index a8e46ef..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultTxtVerboseSerializer.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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.sling.hc.core.impl.servlet;
-
-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.sling.hc.api.Result;
-import org.apache.sling.hc.api.ResultLog;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Serializes health check results into a verbose text message. */
-@Component(
- service = ResultTxtVerboseSerializer.class
-)
-public class ResultTxtVerboseSerializer {
-
- private static final Logger LOG = LoggerFactory.getLogger(ResultTxtVerboseSerializer.class);
-
- private static final String NEWLINE = "\n"; // not using system prop 'line.separator' as not the local but the calling system is relevant.
-
- private int totalWidth;
-
- private int colWidthName;
-
- private int colWidthResult;
-
- private int colWidthTiming;
-
- private int colWidthWithoutLog;
- private int colWidthLog;
-
- @Activate
- protected final void activate(final ResultTxtVerboseSerializerConfiguration configuration) {
- this.totalWidth = configuration.totalWidth();
- this.colWidthName = configuration.colWidthName();
- this.colWidthResult = configuration.colWidthResult();
- this.colWidthTiming = configuration.colWidthTiming();
- colWidthWithoutLog = colWidthName + colWidthResult + colWidthTiming;
- colWidthLog = totalWidth - colWidthWithoutLog;
- }
-
- public String serialize(final Result overallResult, final List<HealthCheckExecutionResult> executionResults, boolean includeDebug) {
-
- LOG.debug("Sending verbose txt response... ");
-
- StringBuilder resultStr = new StringBuilder();
-
- resultStr.append(StringUtils.repeat("-", totalWidth) + NEWLINE);
- resultStr.append(StringUtils.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("Logs" + NEWLINE);
- resultStr.append(StringUtils.repeat("-", totalWidth) + NEWLINE);
-
- final DateFormat dfShort = new SimpleDateFormat("HH:mm:ss.SSS");
-
- for (HealthCheckExecutionResult healthCheckResult : executionResults) {
- appendVerboseTxtForResult(resultStr, healthCheckResult, includeDebug, dfShort);
- }
- resultStr.append(StringUtils.repeat("-", totalWidth) + NEWLINE);
-
- return resultStr.toString();
-
- }
-
- private void appendVerboseTxtForResult(StringBuilder resultStr, HealthCheckExecutionResult healthCheckResult, boolean includeDebug, DateFormat dfShort) {
-
- String wrappedName = WordUtils.wrap(healthCheckResult.getHealthCheckMetadata().getName(), colWidthName);
-
- String relevantNameStringForPadding = StringUtils.contains(wrappedName, "\n") ? StringUtils.substringAfterLast(wrappedName, "\n") : 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())
- + "|" + FormattingResultLog.msHumanReadable(healthCheckResult.getElapsedTimeInMs()) + "]", colWidthTiming));
-
- boolean isFirst = true;
- for (ResultLog.Entry logEntry : healthCheckResult.getHealthCheckResult()) {
- if (!includeDebug && logEntry.getStatus() == Result.Status.DEBUG) {
- continue;
- }
- if(isFirst) {
- isFirst = false;
- } else {
- resultStr.append(StringUtils.repeat(" ", colWidthWithoutLog));
- }
-
- String oneLineMessage = getStatusForTxtLog(logEntry) + logEntry.getMessage();
- String messageToPrint = WordUtils.wrap(oneLineMessage, colWidthLog, "\n" + StringUtils.repeat(" ", colWidthWithoutLog), true);
-
- resultStr.append(messageToPrint);
- resultStr.append(NEWLINE);
- }
-
- if (isFirst) {
- // no log entry exists, ensure newline
- resultStr.append(NEWLINE);
- }
-
- }
-
- private String getStatusForTxtLog(ResultLog.Entry logEntry) {
- if (logEntry.getStatus() == Result.Status.OK || logEntry.getStatus() == Result.Status.INFO) {
- return "";
- } else {
- return logEntry.getStatus().toString() + " ";
- }
- }
-
-}
diff --git a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultTxtVerboseSerializerConfiguration.java b/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultTxtVerboseSerializerConfiguration.java
deleted file mode 100644
index 78b8ace..0000000
--- a/src/main/java/org/apache/sling/hc/core/impl/servlet/ResultTxtVerboseSerializerConfiguration.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.sling.hc.core.impl.servlet;
-
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-@ObjectClassDefinition(
- name = "Apache Sling Health Check Verbose Text Serializer",
- description = "Serializes health check results to a verbose text format"
-)
-@interface ResultTxtVerboseSerializerConfiguration {
-
- @AttributeDefinition(
- name = "Total Width",
- description = "Total width of all columns in verbose txt rendering (in characters)"
- )
- int totalWidth() default 140;
-
- @AttributeDefinition(
- name = "Name Column Width",
- description = "Column width of health check name (in characters)"
- )
- int colWidthName() default 30;
-
- @AttributeDefinition(
- name = "Result Column Width",
- description = "Column width of health check result (in characters)"
- )
- int colWidthResult() default 9;
-
- @AttributeDefinition(
- name = "Timing Column Width",
- description = "Column width of health check timing (in characters)"
- )
- int colWidthTiming() default 22;
-
-}
diff --git a/src/main/java/org/apache/sling/hc/jmx/impl/HealthCheckMBean.java b/src/main/java/org/apache/sling/hc/jmx/impl/HealthCheckMBean.java
deleted file mode 100644
index 54c262b..0000000
--- a/src/main/java/org/apache/sling/hc/jmx/impl/HealthCheckMBean.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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.sling.hc.jmx.impl;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
-import javax.management.InvalidAttributeValueException;
-import javax.management.MBeanAttributeInfo;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.ReflectionException;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.ResultLog;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.core.impl.executor.ExtendedHealthCheckExecutor;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-/** A {@link DynamicMBean} used to execute a {@link HealthCheck} service */
-public class HealthCheckMBean implements DynamicMBean {
-
- private static final String HC_OK_ATTRIBUTE_NAME = "ok";
- private static final String HC_STATUS_ATTRIBUTE_NAME = "status";
- private static final String HC_LOG_ATTRIBUTE_NAME = "log";
- private static final String HC_TIMED_OUT_ATTRIBUTE_NAME = "timedOut";
- private static final String HC_ELAPSED_TIMED_ATTRIBUTE_NAME = "elapsedTime";
- private static final String HC_FINISHED_AT_ATTRIBUTE_NAME = "finishedAt";
- private static CompositeType LOG_ROW_TYPE;
- private static TabularType LOG_TABLE_TYPE;
-
- private static final String INDEX_COLUMN = "index";
- private static final String LEVEL_COLUMN = "level";
- private static final String MESSAGE_COLUMN = "message";
-
- /** The health check service to call. */
- private final ServiceReference healthCheckRef;
-
- /** The executor service. */
- private final ExtendedHealthCheckExecutor executor;
-
- /** The mbean info. */
- private final MBeanInfo mbeanInfo;
-
- /** The default attributes. */
- private final Map<String, Object> defaultAttributes;
-
- static {
- try {
- // Define the log row and table types
- LOG_ROW_TYPE = new CompositeType(
- "LogLine",
- "A line in the result log",
- new String [] { INDEX_COLUMN, LEVEL_COLUMN, MESSAGE_COLUMN },
- new String [] { "log line index", "log level", "log message"},
- new OpenType[] { SimpleType.INTEGER, SimpleType.STRING, SimpleType.STRING }
- );
- final String [] indexes = { INDEX_COLUMN };
- LOG_TABLE_TYPE = new TabularType("LogTable", "Result log messages", LOG_ROW_TYPE, indexes);
- } catch(Exception ignore) {
- // row or table type will be null if this happens
- }
- }
-
- public HealthCheckMBean(final ServiceReference ref, final ExtendedHealthCheckExecutor executor) {
- this.healthCheckRef = ref;
- this.executor = executor;
- this.mbeanInfo = this.createMBeanInfo(ref);
- this.defaultAttributes = this.createDefaultAttributes(ref);
- }
-
- @Override
- public Object getAttribute(final String attribute)
- throws AttributeNotFoundException, MBeanException, ReflectionException {
- // we should call getAttributes - and not vice versa to have the result
- // of a single check call - and not do a check call for each attribute
- final AttributeList result = this.getAttributes(new String[] {attribute});
- if ( result.size() == 0 ) {
- throw new AttributeNotFoundException(attribute);
- }
- final Attribute attr = (Attribute) result.get(0);
- return attr.getValue();
- }
-
- private TabularData logData(final Result er) throws OpenDataException {
- final TabularDataSupport result = new TabularDataSupport(LOG_TABLE_TYPE);
- int i = 1;
- for(final ResultLog.Entry e : er) {
- final Map<String, Object> data = new HashMap<String, Object>();
- data.put(INDEX_COLUMN, i++);
- data.put(LEVEL_COLUMN, e.getStatus().toString());
- data.put(MESSAGE_COLUMN, e.getMessage());
-
- result.put(new CompositeDataSupport(LOG_ROW_TYPE, data));
- }
- return result;
- }
-
- @Override
- public AttributeList getAttributes(final String[] attributes) {
- final AttributeList result = new AttributeList();
- if ( attributes != null ) {
- HealthCheckExecutionResult hcResult = null;
- for(final String key : attributes) {
- final Object defaultValue = this.defaultAttributes.get(key);
- if ( defaultValue != null ) {
- result.add(new Attribute(key, defaultValue));
- } else {
- // we assume that a valid attribute name is used
- // which is requesting a hc result
- if ( hcResult == null ) {
- hcResult = this.getHealthCheckResult();
- }
-
- if ( HC_OK_ATTRIBUTE_NAME.equals(key) ) {
- result.add(new Attribute(key, hcResult.getHealthCheckResult().isOk()));
- } else if ( HC_LOG_ATTRIBUTE_NAME.equals(key) ) {
- try {
- result.add(new Attribute(key, logData(hcResult.getHealthCheckResult())));
- } catch ( final OpenDataException ignore ) {
- // we ignore this and simply don't add the attribute
- }
- } else if ( HC_STATUS_ATTRIBUTE_NAME.equals(key) ) {
- result.add(new Attribute(key, hcResult.getHealthCheckResult().getStatus().toString()));
- } else if ( HC_ELAPSED_TIMED_ATTRIBUTE_NAME.equals(key) ) {
- result.add(new Attribute(key, hcResult.getElapsedTimeInMs()));
- } else if ( HC_FINISHED_AT_ATTRIBUTE_NAME.equals(key) ) {
- result.add(new Attribute(key, hcResult.getFinishedAt()));
- } else if ( HC_TIMED_OUT_ATTRIBUTE_NAME.equals(key) ) {
- result.add(new Attribute(key, hcResult.hasTimedOut()));
- }
- }
- }
- }
-
- return result;
- }
-
- /**
- * Create the mbean info
- */
- private MBeanInfo createMBeanInfo(final ServiceReference serviceReference) {
- final List<MBeanAttributeInfo> attrs = new ArrayList<MBeanAttributeInfo>();
-
- // add relevant service properties
- if ( serviceReference.getProperty(HealthCheck.NAME) != null ) {
- attrs.add(new MBeanAttributeInfo(HealthCheck.NAME, String.class.getName(), "The name of the health check service.", true, false, false));
- }
- if ( serviceReference.getProperty(HealthCheck.TAGS) != null ) {
- attrs.add(new MBeanAttributeInfo(HealthCheck.TAGS, String.class.getName(), "The tags of the health check service.", true, false, false));
- }
-
- // add standard attributes
- attrs.add(new MBeanAttributeInfo(HC_OK_ATTRIBUTE_NAME, Boolean.class.getName(), "The health check result", true, false, false));
- attrs.add(new MBeanAttributeInfo(HC_STATUS_ATTRIBUTE_NAME, String.class.getName(), "The health check status", true, false, false));
- attrs.add(new MBeanAttributeInfo(HC_ELAPSED_TIMED_ATTRIBUTE_NAME, Long.class.getName(), "The elapsed time in miliseconds", true, false, false));
- attrs.add(new MBeanAttributeInfo(HC_FINISHED_AT_ATTRIBUTE_NAME, Date.class.getName(), "The date when the execution finished", true, false, false));
- attrs.add(new MBeanAttributeInfo(HC_TIMED_OUT_ATTRIBUTE_NAME, Boolean.class.getName(), "Indicates of the execution timed out", true, false, false));
- attrs.add(new OpenMBeanAttributeInfoSupport(HC_LOG_ATTRIBUTE_NAME, "The health check result log", LOG_TABLE_TYPE, true, false, false));
-
- final String description;
- if ( serviceReference.getProperty(Constants.SERVICE_DESCRIPTION) != null ) {
- description = serviceReference.getProperty(Constants.SERVICE_DESCRIPTION).toString();
- } else {
- description = "Health check";
- }
- return new MBeanInfo(this.getClass().getName(),
- description,
- attrs.toArray(new MBeanAttributeInfo[attrs.size()]), null, null, null);
- }
-
- /**
- * Create the default attributes.
- */
- private Map<String, Object> createDefaultAttributes(final ServiceReference serviceReference) {
- final Map<String, Object> list = new HashMap<String, Object>();
- if ( serviceReference.getProperty(HealthCheck.NAME) != null ) {
- list.put(HealthCheck.NAME, serviceReference.getProperty(HealthCheck.NAME).toString());
- }
- if ( serviceReference.getProperty(HealthCheck.TAGS) != null ) {
- final Object value = serviceReference.getProperty(HealthCheck.TAGS);
- if ( value instanceof String[] ) {
- list.put(HealthCheck.TAGS, Arrays.toString((String[])value));
- } else {
- list.put(HealthCheck.TAGS, value.toString());
- }
- }
-
- return list;
- }
-
- @Override
- public MBeanInfo getMBeanInfo() {
- return this.mbeanInfo;
- }
-
- @Override
- public Object invoke(final String actionName, final Object[] params, final String[] signature)
- throws MBeanException, ReflectionException {
- throw new MBeanException(new UnsupportedOperationException(getClass().getSimpleName() + " does not support operations."));
- }
-
- @Override
- public void setAttribute(final Attribute attribute)
- throws AttributeNotFoundException, InvalidAttributeValueException,
- MBeanException, ReflectionException {
- throw new MBeanException(new UnsupportedOperationException(getClass().getSimpleName() + " does not support setting attributes."));
- }
-
- @Override
- public AttributeList setAttributes(final AttributeList attributes) {
- return new AttributeList();
- }
-
- @Override
- public String toString() {
- return "HealthCheckMBean [healthCheck=" + this.healthCheckRef + "]";
- }
-
- private HealthCheckExecutionResult getHealthCheckResult() {
- return this.executor.execute(this.healthCheckRef);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/hc/jmx/impl/HealthCheckMBeanCreator.java b/src/main/java/org/apache/sling/hc/jmx/impl/HealthCheckMBeanCreator.java
deleted file mode 100644
index 4f4ddcf..0000000
--- a/src/main/java/org/apache/sling/hc/jmx/impl/HealthCheckMBeanCreator.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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.sling.hc.jmx.impl;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-import javax.management.DynamicMBean;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.core.impl.executor.ExtendedHealthCheckExecutor;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Creates an {@link HealthCheckMBean} for every {@link HealthCheckMBean} service
- *
- */
-@Component
-public class HealthCheckMBeanCreator {
-
- private static final String JMX_TYPE_NAME = "HealthCheck";
- private static final String JMX_DOMAIN = "org.apache.sling.healthcheck";
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private final Map<ServiceReference, Registration> registeredServices = new HashMap<ServiceReference, Registration>();
-
- private final Map<String, List<ServiceReference>> sortedRegistrations = new HashMap<String, List<ServiceReference>>();
-
- private ServiceTracker hcTracker;
-
- @Reference
- private ExtendedHealthCheckExecutor executor;
-
- @Activate
- protected void activate(final BundleContext btx) {
- this.hcTracker = new ServiceTracker(btx, HealthCheck.class.getName(), null) {
-
- @Override
- public Object addingService(final ServiceReference reference) {
- return registerHCMBean(btx, reference);
- }
-
- @Override
- public void modifiedService(final ServiceReference reference,
- final Object service) {
- unregisterHCMBean(btx, reference);
- registerHCMBean(btx, reference);
- }
-
- @Override
- public void removedService(final ServiceReference reference,
- final Object service) {
- unregisterHCMBean(btx, reference);
- }
-
- };
- this.hcTracker.open();
- }
-
- @Deactivate
- protected void deactivate() {
- if ( this.hcTracker != null ) {
- this.hcTracker.close();
- this.hcTracker = null;
- }
- }
-
- /**
- * Register an mbean for a health check service.
- * The mbean is only registered if
- * - the service has an mbean registration property
- * - if there is no other service with the same name but a higher service ranking
- *
- * @param bundleContext The bundle context
- * @param reference The service reference to the health check service
- * @return The registered mbean or <code>null</code>
- */
- private synchronized Object registerHCMBean(final BundleContext bundleContext, final ServiceReference reference) {
- final Registration reg = getRegistration(reference);
- if ( reg != null ) {
- this.registeredServices.put(reference, reg);
-
- List<ServiceReference> registered = this.sortedRegistrations.get(reg.name);
- if ( registered == null ) {
- registered = new ArrayList<ServiceReference>();
- this.sortedRegistrations.put(reg.name, registered);
- }
- registered.add(reference);
- // sort orders the references with lowest ranking first
- // we want the highest!
- Collections.sort(registered);
- final int lastIndex = registered.size() - 1;
- if ( registered.get(lastIndex).equals(reference) ) {
- if ( registered.size() > 1 ) {
- final ServiceReference prevRef = registered.get(lastIndex - 1);
- final Registration prevReg = this.registeredServices.get(prevRef);
- prevReg.unregister();
- }
- reg.register(bundleContext);
- }
- }
- return reg;
- }
-
- private synchronized void unregisterHCMBean(final BundleContext bundleContext, final ServiceReference ref) {
- final Registration reg = registeredServices.remove(ref);
- if ( reg != null ) {
- final boolean registerFirst = reg.unregister();
- final List<ServiceReference> registered = this.sortedRegistrations.get(reg.name);
- registered.remove(ref);
- if ( registered.size() == 0 ) {
- this.sortedRegistrations.remove(reg.name);
- } else if ( registerFirst ) {
- final ServiceReference newRef = registered.get(0);
- final Registration newReg = this.registeredServices.get(newRef);
- newReg.register(bundleContext);
- }
- bundleContext.ungetService(ref);
- }
- }
-
- private final class Registration {
- private final String name;
- private final HealthCheckMBean mbean;
-
- private final String objectName;
-
- private ServiceRegistration registration;
-
- Registration(final String name, final HealthCheckMBean mbean) {
- this.name = name;
- this.mbean = mbean;
- objectName = String.format("%s:type=%s,name=%s", JMX_DOMAIN, JMX_TYPE_NAME, name);
- }
-
- void register(final BundleContext btx) {
- logger.debug("Registering health check mbean {} with name {}", mbean, objectName);
- final Dictionary<String, String> mbeanProps = new Hashtable<String, String>();
- mbeanProps.put("jmx.objectname", objectName);
- this.registration = btx.registerService(DynamicMBean.class.getName(), this.mbean, mbeanProps);
- }
-
- boolean unregister() {
- if ( this.registration != null ) {
- logger.debug("Unregistering health check mbean {} with name {}", mbean, objectName);
- this.registration.unregister();
- this.registration = null;
- return true;
- }
- return false;
- }
- }
-
- private Registration getRegistration(final ServiceReference ref) {
- final Object nameObj = ref.getProperty(HealthCheck.MBEAN_NAME);
- if ( nameObj != null ) {
- final HealthCheckMBean mbean = new HealthCheckMBean(ref, executor);
- return new Registration(nameObj.toString().replace(',', '.'), mbean);
- }
- return null;
- }
-
-}
diff --git a/src/test/java/org/apache/sling/hc/core/impl/CompositeHealthCheckTest.java b/src/test/java/org/apache/sling/hc/core/impl/CompositeHealthCheckTest.java
deleted file mode 100644
index 1555be8..0000000
--- a/src/test/java/org/apache/sling/hc/core/impl/CompositeHealthCheckTest.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionOptions;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.apache.sling.hc.core.impl.executor.ExecutionResult;
-import org.apache.sling.hc.util.HealthCheckFilter;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.hamcrest.Description;
-import org.hamcrest.Matcher;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.Spy;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.component.ComponentConstants;
-import org.osgi.service.component.ComponentContext;
-
-public class CompositeHealthCheckTest {
-
- @Spy
- private CompositeHealthCheck compositeHealthCheck = new CompositeHealthCheck();
-
- @Mock
- private HealthCheckExecutor healthCheckExecutor;
-
- @Mock
- private ComponentContext componentContext;
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- compositeHealthCheck.setHealthCheckExecutor(healthCheckExecutor);
- compositeHealthCheck.setFilterTags(new String[] {});
- compositeHealthCheck.setComponentContext(componentContext);
- }
-
- @Test
- public void testExecution() {
-
- doReturn((Result) null).when(compositeHealthCheck).checkForRecursion(Matchers.<ServiceReference> any(), Matchers.<Set<String>> any());
- String[] testTags = new String[] { "tag1" };
- compositeHealthCheck.setFilterTags(testTags);
-
-
- List<HealthCheckExecutionResult> executionResults = new LinkedList<HealthCheckExecutionResult>();
- executionResults.add(createExecutionResult("Check 1", testTags, new Result(Result.Status.INFO, "Good")));
- executionResults.add(createExecutionResult("Check 2", testTags, new Result(Result.Status.CRITICAL, "Bad")));
-
- when(healthCheckExecutor.execute(any(HealthCheckSelector.class), any(HealthCheckExecutionOptions.class))).thenReturn(executionResults);
-
- Result result = compositeHealthCheck.execute();
-
- verify(healthCheckExecutor, times(1)).execute(argThat(selectorWithTags(testTags)), argThat(andOptions));
-
- assertEquals(Result.Status.CRITICAL, result.getStatus());
-
- }
-
- private Matcher<HealthCheckSelector> selectorWithTags(final String[] tags) {
- return new TypeSafeMatcher<HealthCheckSelector>() {
- @Override
- protected boolean matchesSafely(HealthCheckSelector healthCheckSelector) {
- return Arrays.equals(healthCheckSelector.tags(), tags) && healthCheckSelector.names() == null;
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("a select with tags (" + Arrays.toString(tags) +") and no names.");
- }
- };
- }
-
- private HealthCheckExecutionResult createExecutionResult(String name, String[] testTags, Result result) {
- HealthCheckExecutionResult healthCheckExecutionResult = new ExecutionResult(new HealthCheckMetadata(new DummyHcServiceReference(name, testTags,
- new String[0])), result, 0L);
- return healthCheckExecutionResult;
- }
-
- @Test
- public void testSimpleRecursion() {
-
- // composite check referencing itself
- final String[] filterTags = new String[] { "check1" };
- final DummyHcServiceReference hcRef = new DummyHcServiceReference("Check 1", new String[] { "check1" }, filterTags);
-
- // test check is hcRef
- doReturn(hcRef).when(componentContext).getServiceReference();
- compositeHealthCheck.setFilterTags(filterTags);
-
- compositeHealthCheck.setHealthCheckFilter(new HealthCheckFilter(null) {
-
- @Override
- public ServiceReference[] getHealthCheckServiceReferences(HealthCheckSelector selector) {
- String[] tags = selector.tags();
- ServiceReference[] result = new ServiceReference[] {};
- if (tags.length > 0) {
- if (tags[0].equals(filterTags[0])) {
- result = new ServiceReference[] { hcRef };
- }
- }
- return result;
- }
-
- });
-
- Result result = compositeHealthCheck.execute();
-
- verify(healthCheckExecutor, never()).execute(any(HealthCheckSelector.class));
- assertEquals(Result.Status.HEALTH_CHECK_ERROR, result.getStatus());
- }
-
- @Test
- public void testCyclicRecursion() {
-
- // three checks, cyclic
- final String[] filterTags = new String[] { "check2" };
- final DummyHcServiceReference hcRef1 = new DummyHcServiceReference("Check 1", new String[] { "check1" }, filterTags);
- final DummyHcServiceReference hcRef2 = new DummyHcServiceReference("Check 2", new String[] { "check2" }, new String[] { "check3" });
- final DummyHcServiceReference hcRef3 = new DummyHcServiceReference("Check 3", new String[] { "check3" }, new String[] { "check1" });
-
- // test check is hcRef1
- doReturn(hcRef1).when(componentContext).getServiceReference();
- compositeHealthCheck.setFilterTags(filterTags);
-
- compositeHealthCheck.setHealthCheckFilter(new HealthCheckFilter(null) {
-
- @Override
- public ServiceReference[] getHealthCheckServiceReferences(HealthCheckSelector selector, boolean combineTagsWithOr) {
- String[] tags = selector.tags();
- ServiceReference[] result = new ServiceReference[] {};
- if (tags.length > 0) {
- if (tags[0].equals(filterTags[0])) {
- result = new ServiceReference[] { hcRef2 };
- } else if (tags[0].equals("check3")) {
- result = new ServiceReference[] { hcRef3 };
- } else if (tags[0].equals("check1")) {
- result = new ServiceReference[] { hcRef1 };
- }
- }
-
- return result;
- }
-
- });
-
- Result result = compositeHealthCheck.execute();
-
- verify(healthCheckExecutor, never()).execute(any(HealthCheckSelector.class));
- assertEquals(Result.Status.HEALTH_CHECK_ERROR, result.getStatus());
- }
-
- @Test
- public void testCombineWithOr() {
-
- // composite check referencing itself
- final String[] filterTags = new String[] { "check1" };
- compositeHealthCheck.setFilterTags(filterTags);
- compositeHealthCheck.setCombineTagsWithOr(true);
-
- compositeHealthCheck.execute();
-
- verify(healthCheckExecutor, times(1)).execute(argThat(selectorWithTags(filterTags)), argThat(orOptions));
- }
-
- private Matcher<HealthCheckExecutionOptions> orOptions = new TypeSafeMatcher<HealthCheckExecutionOptions>() {
- @Override
- protected boolean matchesSafely(HealthCheckExecutionOptions options) {
- return options.isCombineTagsWithOr();
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("options combining tags with or.");
- }
- };
-
- private Matcher<HealthCheckExecutionOptions> andOptions = new TypeSafeMatcher<HealthCheckExecutionOptions>() {
- @Override
- protected boolean matchesSafely(HealthCheckExecutionOptions options) {
- return !options.isCombineTagsWithOr();
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText("options combining tags with and.");
- }
- };
-
- private static class DummyHcServiceReference implements ServiceReference {
-
- private long id;
- private String name;
- private String[] tags;
- private String[] filterTags;
-
- public DummyHcServiceReference(String name, String[] tags, String[] filterTags) {
- super();
- this.id = (long) (Math.random() * Long.MAX_VALUE);
- this.name = name;
- this.tags = tags;
- this.filterTags = filterTags;
- }
-
- @Override
- public Object getProperty(String key) {
-
- if (Constants.SERVICE_ID.equals(key)) {
- return id;
- } else if (HealthCheck.NAME.equals(key)) {
- return name;
- } else if (HealthCheck.MBEAN_NAME.equals(key)) {
- return name;
- } else if (HealthCheck.TAGS.equals(key)) {
- return tags;
- } else if (CompositeHealthCheck.PROP_FILTER_TAGS.equals(key)) {
- return filterTags;
- } else if (ComponentConstants.COMPONENT_NAME.equals(key)) {
- return filterTags != null ? CompositeHealthCheck.class.getName() : "some.other.HealthCheck";
- } else {
- return null;
- }
- }
-
- @Override
- public String[] getPropertyKeys() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Bundle getBundle() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Bundle[] getUsingBundles() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isAssignableTo(Bundle bundle, String className) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public int compareTo(Object reference) {
- throw new UnsupportedOperationException();
- }
-
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/core/impl/JmxAttributeHealthCheckTest.java b/src/test/java/org/apache/sling/hc/core/impl/JmxAttributeHealthCheckTest.java
deleted file mode 100644
index eb4f335..0000000
--- a/src/test/java/org/apache/sling/hc/core/impl/JmxAttributeHealthCheckTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import org.apache.sling.hc.api.Result;
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class JmxAttributeHealthCheckTest {
-
- static void assertJmxValue(String objectName, String attributeName, String constraint, boolean expected) {
- final JmxAttributeHealthCheck hc = new JmxAttributeHealthCheck();
-
- final JmxAttributeHealthCheckConfiguration configuration = mock(JmxAttributeHealthCheckConfiguration.class);
- when(configuration.mbean_name()).thenReturn(objectName);
- when(configuration.attribute_name()).thenReturn(attributeName);
- when(configuration.attribute_value_constraint()).thenReturn(constraint);
-
- hc.activate(configuration);
-
- final Result r = hc.execute();
- assertEquals("Expected result " + expected, expected, r.isOk());
- }
-
- @Test
- public void testJmxAttributeMatch() {
- assertJmxValue("java.lang:type=ClassLoading", "LoadedClassCount", "> 10", true);
- }
-
- @Test
- public void testJmxAttributeNoMatch() {
- assertJmxValue("java.lang:type=ClassLoading", "LoadedClassCount", "< 10", false);
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/core/impl/JmxScriptBindingsProviderTest.java b/src/test/java/org/apache/sling/hc/core/impl/JmxScriptBindingsProviderTest.java
deleted file mode 100644
index 498a1e7..0000000
--- a/src/test/java/org/apache/sling/hc/core/impl/JmxScriptBindingsProviderTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.lang.management.ManagementFactory;
-
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.junit.Test;
-
-public class JmxScriptBindingsProviderTest {
-
- @Test
- public void testJmxAttribute() throws Exception {
- final FormattingResultLog resultLog = new FormattingResultLog();
- final JmxScriptBindingsProvider.AttributeBinding b = new JmxScriptBindingsProvider.AttributeBinding(ManagementFactory.getPlatformMBeanServer(), resultLog);
- final Object value= b.attribute("java.lang:type=ClassLoading", "LoadedClassCount");
- assertNotNull("Expecting non-null attribute value", value);
- assertTrue("Expecting non-empty value", value.toString().length() > 0);
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/hc/core/impl/ScriptableHealthCheckTest.java b/src/test/java/org/apache/sling/hc/core/impl/ScriptableHealthCheckTest.java
deleted file mode 100644
index af3a142..0000000
--- a/src/test/java/org/apache/sling/hc/core/impl/ScriptableHealthCheckTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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.sling.hc.core.impl;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-
-import org.apache.commons.lang3.reflect.FieldUtils;
-import org.apache.sling.hc.api.Result;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Matchers;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class ScriptableHealthCheckTest {
-
- private ScriptableHealthCheck hc;
-
- private final JmxScriptBindingsProvider jmxScriptBindingsProvider = new JmxScriptBindingsProvider();
-
- private void assertExpression(String expression, String languageExtension, boolean expected) throws Exception {
- final ScriptEngine rhino = new ScriptEngineManager().getEngineByExtension("js");
- assertNotNull("With the rhino jar in our classpath, we should get a js script engine", rhino);
- final ScriptEngineManager manager = mock(ScriptEngineManager.class);
- when(manager.getEngineByExtension(Matchers.same("ecma"))).thenReturn(rhino);
- FieldUtils.writeDeclaredField(hc, "scriptEngineManager", manager, true);
-
- final ScriptableHealthCheckConfiguration configuration = mock(ScriptableHealthCheckConfiguration.class);
- when(configuration.expression()).thenReturn(expression);
- if (languageExtension != null) {
- when(configuration.language_extension()).thenReturn(languageExtension);
- } else {
- when(configuration.language_extension()).thenReturn("ecma");
- }
- hc.activate(configuration);
- final Result r = hc.execute();
- assertEquals("Expecting result " + expected, expected, r.isOk());
- }
-
- @Before
- public void setup() {
- hc = new ScriptableHealthCheck();
- hc.bindBindingsValuesProvider(jmxScriptBindingsProvider);
- }
-
- @Test
- public void testSimpleExpression() throws Exception {
- assertExpression("2 + 3 == 5", null, true);
- }
-
- @Test
- public void testRemoveBinding() throws Exception {
- final String expr = "jmx.attribute('java.lang:type=ClassLoading', 'LoadedClassCount') > 10";
- assertExpression(expr, "ecma", true);
- hc.unbindBindingsValuesProvider(jmxScriptBindingsProvider);
- assertExpression(expr, "ecma", false);
- }
-
- @Test
- public void testJmxExpression() throws Exception {
- assertExpression(
- "jmx.attribute('java.lang:type=ClassLoading', 'LoadedClassCount') > 10"
- + " && jmx.attribute('java.lang:type=Runtime', 'ManagementSpecVersion') > 1",
- "ecma", true);
- }
-
- @Test
- public void testFalseExpression() throws Exception {
- assertExpression("2 + 3 == 15", null, false);
- }
-
- @Test
- public void testSyntaxError() throws Exception {
- assertExpression("{not [valid ok?", null, false);
- }
-
- @Test
- public void testNoEngine() throws Exception {
- assertExpression("2 + 3 == 5", null, true);
- assertExpression("2 + 3 == 5", "groovy", false);
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImplTest.java b/src/test/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImplTest.java
deleted file mode 100644
index 367f70a..0000000
--- a/src/test/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImplTest.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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.sling.hc.core.impl.executor;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.Result.Status;
-import org.apache.sling.hc.api.ResultLog.Entry;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Spy;
-
-public class HealthCheckExecutorImplTest {
-
- @InjectMocks
- private HealthCheckExecutorImpl healthCheckExecutorImpl = new HealthCheckExecutorImpl();;
-
- @Mock
- private HealthCheckFuture future;
-
- @Mock
- private HealthCheckMetadata HealthCheckMetadata;
-
- @Spy
- private HealthCheckResultCache healthCheckResultCache = new HealthCheckResultCache();
-
- @Before
- public void setup() {
- initMocks(this);
-
- when(future.getHealthCheckMetadata()).thenReturn(HealthCheckMetadata);
- when(HealthCheckMetadata.getTitle()).thenReturn("Test Check");
-
-
- // 2 sec normal timeout
- healthCheckExecutorImpl.setTimeoutInMs(2000L);
- // 10 sec timeout for critical
- healthCheckExecutorImpl.setLongRunningFutureThresholdForRedMs(10000L);
- }
-
- @Test
- public void testCollectResultsFromFutures() throws Exception {
-
- List<HealthCheckFuture> futures = new LinkedList<HealthCheckFuture>();
- futures.add(future);
- Collection<HealthCheckExecutionResult> results = new TreeSet<HealthCheckExecutionResult>();
-
- when(future.isDone()).thenReturn(true);
- ExecutionResult testResult = new ExecutionResult(HealthCheckMetadata, new Result(Result.Status.OK, "test"), 10L);
- when(future.get()).thenReturn(testResult);
-
- healthCheckExecutorImpl.collectResultsFromFutures(futures, results);
-
- verify(future, times(1)).get();
-
- assertEquals(1, results.size());
- assertTrue(results.contains(testResult));
- }
-
- @Test
- public void testCollectResultsFromFuturesTimeout() throws Exception {
-
- // add an earlier result with status ok (that will be shown as part of the log)
- addResultToCache(Status.OK);
-
- List<HealthCheckFuture> futures = new LinkedList<HealthCheckFuture>();
- futures.add(future);
- Set<HealthCheckExecutionResult> results = new TreeSet<HealthCheckExecutionResult>();
-
- when(future.isDone()).thenReturn(false);
- // simulating a future that was created 5sec ago
- when(future.getCreatedTime()).thenReturn(new Date(new Date().getTime() - 1000 * 5));
-
- healthCheckExecutorImpl.collectResultsFromFutures(futures, results);
-
- verify(future, times(0)).get();
-
- assertEquals(1, results.size());
- HealthCheckExecutionResult result = results.iterator().next();
-
- assertEquals(Result.Status.WARN, result.getHealthCheckResult().getStatus());
-
- // 3 because previous result exists and is part of log
- assertEquals(3, getLogEntryCount(result));
- }
-
- @Test
- public void testCollectResultsFromFuturesCriticalTimeout() throws Exception {
-
- List<HealthCheckFuture> futures = new LinkedList<HealthCheckFuture>();
- futures.add(future);
- Set<HealthCheckExecutionResult> results = new TreeSet<HealthCheckExecutionResult>();
-
- when(future.isDone()).thenReturn(false);
-
- // use an old date now (simulating a future that has run for an hour)
- when(future.getCreatedTime()).thenReturn(new Date(new Date().getTime() - 1000 * 60 * 60));
-
- healthCheckExecutorImpl.collectResultsFromFutures(futures, results);
- assertEquals(1, results.size());
- HealthCheckExecutionResult result = results.iterator().next();
-
- verify(future, times(0)).get();
-
- assertEquals(Result.Status.CRITICAL, result.getHealthCheckResult().getStatus());
- assertEquals(1, getLogEntryCount(result));
- }
-
- @Test
- public void testCollectResultsFromFuturesWarnTimeoutWithPreviousCritical() throws Exception {
-
- // an earlier result with critical
- addResultToCache(Status.CRITICAL);
-
- List<HealthCheckFuture> futures = new LinkedList<HealthCheckFuture>();
- futures.add(future);
- Set<HealthCheckExecutionResult> results = new TreeSet<HealthCheckExecutionResult>();
-
- when(future.isDone()).thenReturn(false);
- // simulating a future that was created 5sec ago
- when(future.getCreatedTime()).thenReturn(new Date(new Date().getTime() - 1000 * 5));
-
-
- healthCheckExecutorImpl.collectResultsFromFutures(futures, results);
- assertEquals(1, results.size());
- HealthCheckExecutionResult result = results.iterator().next();
-
- verify(future, times(0)).get();
-
- // expect CRITICAL because previous result (before timeout) was CRITICAL (and not only WARN)
- assertEquals(Result.Status.CRITICAL, result.getHealthCheckResult().getStatus());
- assertEquals(3, getLogEntryCount(result));
- }
-
-
- private int getLogEntryCount(HealthCheckExecutionResult result) {
- int logEntryCount = 0;
- final Iterator<Entry> it = result.getHealthCheckResult().iterator();
- while(it.hasNext()) {
- it.next();
- logEntryCount++;
- }
- return logEntryCount;
- }
-
- private void addResultToCache(Status status) {
- healthCheckResultCache.updateWith(new ExecutionResult(HealthCheckMetadata, new Result(status, "Status "+status), 1000));
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/core/impl/executor/HealthCheckResultCacheTest.java b/src/test/java/org/apache/sling/hc/core/impl/executor/HealthCheckResultCacheTest.java
deleted file mode 100644
index 888e694..0000000
--- a/src/test/java/org/apache/sling/hc/core/impl/executor/HealthCheckResultCacheTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * 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.sling.hc.core.impl.executor;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.ResultLog;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-public class HealthCheckResultCacheTest {
-
- private static final int HC_TIMEOUT_NOT_SET = -1;
- private static final int DUR_1_MIN = 60 * 1000;
- private static final int DUR_2_MIN = 2 * DUR_1_MIN;
- private static final int DUR_3_MIN = 3 * DUR_1_MIN;
- private static final int DUR_4_MIN = 4 * DUR_1_MIN;
-
- private HealthCheckResultCache healthCheckResultCache = new HealthCheckResultCache();
-
- @Mock
- ServiceReference serviceRef;
-
- @Before
- public void setup() {
- initMocks(this);
- }
-
- private HealthCheckMetadata setupHealthCheckMetadata(long id, long ttl) {
- reset(serviceRef);
- doReturn(id).when(serviceRef).getProperty(Constants.SERVICE_ID);
- doReturn(ttl).when(serviceRef).getProperty(HealthCheck.RESULT_CACHE_TTL_IN_MS);
- doReturn("HC id="+id).when(serviceRef).getProperty(HealthCheck.NAME);
- return new HealthCheckMetadata(serviceRef);
- }
-
- @Test
- public void testHealthCheckResultCache() {
-
- HealthCheckMetadata hc1 = setupHealthCheckMetadata(1, HC_TIMEOUT_NOT_SET);
- ExecutionResult executionResult1 = spy(new ExecutionResult(hc1, new Result(Result.Status.OK, "result for hc1"), 1));
- doReturn(new Date(new Date().getTime() - DUR_1_MIN)).when(executionResult1).getFinishedAt();
- healthCheckResultCache.updateWith(executionResult1);
-
- HealthCheckMetadata hc2 = setupHealthCheckMetadata(2, HC_TIMEOUT_NOT_SET);
- ExecutionResult executionResult2 = spy(new ExecutionResult(hc2, new Result(Result.Status.OK, "result for hc2"), 1));
- doReturn(new Date(new Date().getTime() - DUR_3_MIN)).when(executionResult2).getFinishedAt();
- healthCheckResultCache.updateWith(executionResult2);
-
- HealthCheckMetadata hc3 = setupHealthCheckMetadata(3, DUR_4_MIN);
- ExecutionResult executionResult3 = spy(new ExecutionResult(hc3, new Result(Result.Status.OK, "result for hc3"), 1));
- doReturn(new Date(new Date().getTime() - DUR_3_MIN)).when(executionResult3).getFinishedAt();
- healthCheckResultCache.updateWith(executionResult3);
-
- HealthCheckMetadata hc4 = setupHealthCheckMetadata(4, HC_TIMEOUT_NOT_SET);
- // no result for this yet
-
- List<HealthCheckMetadata> hcList = new ArrayList<HealthCheckMetadata>(Arrays.asList(hc1,hc2,hc3,hc4));
- List<HealthCheckExecutionResult> results = new ArrayList<HealthCheckExecutionResult>();
-
- healthCheckResultCache.useValidCacheResults(hcList, results, DUR_2_MIN);
-
- assertTrue(hcList.contains(hc2)); // result too old, left in hcList for later execution
- assertTrue(hcList.contains(hc4)); // no result was added to cache via updateWith()
-
- assertTrue(results.contains(executionResult1)); // true <= result one min old, global timeout 2min
- assertFalse(results.contains(executionResult2)); // false <= result three min old, global timeout 2min
- assertTrue(results.contains(executionResult3)); // true <= result one three old, HC timeout 4min
-
- // values not found in cache are left in hcList
- assertEquals(2, hcList.size());
- assertEquals(2, results.size());
-
- }
-
- @Test
- public void testHealthCheckResultCacheTtl() {
-
- //-- test cache miss due to HC TTL
- HealthCheckMetadata hcWithTtl = setupHealthCheckMetadata(1, DUR_1_MIN);
- ExecutionResult executionResult = spy(new ExecutionResult(hcWithTtl, new Result(Result.Status.OK, "result for hc"), 1));
- doReturn(new Date(new Date().getTime() - DUR_2_MIN)).when(executionResult).getFinishedAt();
- healthCheckResultCache.updateWith(executionResult);
-
- HealthCheckExecutionResult result = healthCheckResultCache.getValidCacheResult(hcWithTtl, DUR_3_MIN);
- assertNull(result); // even though global timeout would be ok (2min<3min, the hc timeout of 1min invalidates the result)
-
- //-- test cache hit due to HC TTL
- hcWithTtl = setupHealthCheckMetadata(2, DUR_3_MIN);
- executionResult = spy(new ExecutionResult(hcWithTtl, new Result(Result.Status.OK, "result for hc"), 1));
- doReturn(new Date(new Date().getTime() - DUR_2_MIN)).when(executionResult).getFinishedAt();
- healthCheckResultCache.updateWith(executionResult);
-
- result = healthCheckResultCache.getValidCacheResult(hcWithTtl, DUR_1_MIN);
- assertEquals(executionResult, result); // even though global timeout would invalidate this result (1min<2min, the hc timeout of 3min allows the result)
-
- //-- test Long.MAX_VALUE
- hcWithTtl = setupHealthCheckMetadata(3, Long.MAX_VALUE);
- executionResult = spy(new ExecutionResult(hcWithTtl, new Result(Result.Status.OK, "result for hc"), 1));
- doReturn(new Date(new Date().getTime() - DUR_4_MIN)).when(executionResult).getFinishedAt();
- healthCheckResultCache.updateWith(executionResult);
-
- result = healthCheckResultCache.getValidCacheResult(hcWithTtl, DUR_1_MIN);
- assertEquals(executionResult, result);
-
- }
-
- private HealthCheckMetadata setupHealthCheckMetadataWithStickyResults(long id, long warningsStickForMinutes) {
- reset(serviceRef);
- doReturn(id).when(serviceRef).getProperty(Constants.SERVICE_ID);
- doReturn(warningsStickForMinutes).when(serviceRef).getProperty(HealthCheck.WARNINGS_STICK_FOR_MINUTES);
- doReturn("HC id=" + id).when(serviceRef).getProperty(HealthCheck.NAME);
- return new HealthCheckMetadata(serviceRef);
- }
-
- @Test
- public void testCreateExecutionResultWithStickyResults() {
-
- HealthCheckMetadata hcWithStickyResultsSet = setupHealthCheckMetadataWithStickyResults(1, 2 /* 2 minutes */);
- ExecutionResult currentResult = spy(new ExecutionResult(hcWithStickyResultsSet, new Result(Result.Status.OK, "result for hc"), 1));
- HealthCheckExecutionResult overallResultWithStickyResults = healthCheckResultCache.createExecutionResultWithStickyResults(currentResult);
- assertTrue("Exact same result is expected if no history exists", currentResult == overallResultWithStickyResults);
-
- // add 4 minutes old WARN to cache
- ExecutionResult oldWarnResult = spy(new ExecutionResult(hcWithStickyResultsSet, new Result(Result.Status.WARN, "result for hc"), 1));
- doReturn(new Date(System.currentTimeMillis() - DUR_4_MIN)).when(oldWarnResult).getFinishedAt();
- healthCheckResultCache.updateWith(oldWarnResult);
-
- // check that it is not used
- currentResult = new ExecutionResult(hcWithStickyResultsSet, new Result(Result.Status.OK, "result for hc"), 1);
- overallResultWithStickyResults = healthCheckResultCache.createExecutionResultWithStickyResults(currentResult);
- assertTrue("Exact same result is expected if WARN HC Result is too old", currentResult == overallResultWithStickyResults);
-
- // change WARN to 1 minute age
- doReturn(new Date(System.currentTimeMillis() - DUR_1_MIN)).when(oldWarnResult).getFinishedAt();
- overallResultWithStickyResults = healthCheckResultCache.createExecutionResultWithStickyResults(currentResult);
- assertTrue("Expect newly created result as sticky result should be taken into account", currentResult != overallResultWithStickyResults);
- assertEquals("Expect status to be taken over from old, sticky WARN", Result.Status.WARN,
- overallResultWithStickyResults.getHealthCheckResult().getStatus());
- assertEquals("Expect 4 entries, two each for current and WARN", 4, getLogMsgCount(overallResultWithStickyResults));
-
- // add 1 minutes old CRITICAL to cache
- ExecutionResult oldCriticalResult = spy(new ExecutionResult(hcWithStickyResultsSet, new Result(Result.Status.CRITICAL, "result for hc"), 1));
- doReturn(new Date(System.currentTimeMillis() - DUR_1_MIN)).when(oldCriticalResult).getFinishedAt();
- healthCheckResultCache.updateWith(oldCriticalResult);
-
- overallResultWithStickyResults = healthCheckResultCache.createExecutionResultWithStickyResults(currentResult);
- assertTrue("Expect newly created result as sticky result should be taken into account", currentResult != overallResultWithStickyResults);
- assertEquals("Expect status to be taken over from old, sticky CRITICAL", Result.Status.CRITICAL,
- overallResultWithStickyResults.getHealthCheckResult().getStatus());
- assertEquals("Expect six entries, two each for current, WARN and CRITICAL result", 6, getLogMsgCount(overallResultWithStickyResults));
-
- }
-
- private int getLogMsgCount(HealthCheckExecutionResult result) {
- int count = 0;
- for (ResultLog.Entry entry : result.getHealthCheckResult()) {
- count++;
- }
- return count;
- }
-
-}
diff --git a/src/test/java/org/apache/sling/hc/core/impl/servlet/HealthCheckExecutorServletTest.java b/src/test/java/org/apache/sling/hc/core/impl/servlet/HealthCheckExecutorServletTest.java
deleted file mode 100644
index 1376687..0000000
--- a/src/test/java/org/apache/sling/hc/core/impl/servlet/HealthCheckExecutorServletTest.java
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * 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.sling.hc.core.impl.servlet;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.contains;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.Result.Status;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionOptions;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.apache.sling.hc.core.impl.executor.ExecutionResult;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.hamcrest.Description;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-public class HealthCheckExecutorServletTest {
-
- @InjectMocks
- private HealthCheckExecutorServlet healthCheckExecutorServlet = new HealthCheckExecutorServlet();
-
- @Mock
- private HttpServletRequest request;
-
- @Mock
- private HttpServletResponse response;
-
- @Mock
- private HealthCheckExecutor healthCheckExecutor;
-
- @Mock
- private ResultHtmlSerializer htmlSerializer;
-
- @Mock
- private ResultJsonSerializer jsonSerializer;
-
- @Mock
- private ResultTxtSerializer txtSerializer;
-
- @Mock
- private ResultTxtVerboseSerializer verboseTxtSerializer;
-
- @Mock
- private ServiceReference hcServiceRef;
-
- @Mock
- private PrintWriter writer;
-
- @Before
- public void setup() throws IOException {
- initMocks(this);
-
- doReturn(500L).when(hcServiceRef).getProperty(Constants.SERVICE_ID);
- doReturn(writer).when(response).getWriter();
- }
-
- @Test
- public void testDoGetHtml() throws ServletException, IOException {
-
- final String testTag = "testTag";
- doReturn(testTag).when(request).getParameter(HealthCheckExecutorServlet.PARAM_TAGS.name);
- doReturn("false").when(request).getParameter(HealthCheckExecutorServlet.PARAM_COMBINE_TAGS_WITH_OR.name);
- final List<HealthCheckExecutionResult> executionResults = getExecutionResults(Result.Status.CRITICAL);
- doReturn(executionResults).when(healthCheckExecutor).execute(selector(new String[] { testTag }, new String[0]), eq(new HealthCheckExecutionOptions()));
-
- healthCheckExecutorServlet.doGet(request, response);
-
- verifyZeroInteractions(jsonSerializer);
- verifyZeroInteractions(txtSerializer);
- verifyZeroInteractions(verboseTxtSerializer);
- verify(htmlSerializer)
- .serialize(resultEquals(new Result(Result.Status.CRITICAL, "Overall Status CRITICAL")), eq(executionResults), contains("Supported URL parameters"), eq(false));
- }
-
- @Test
- public void testDoGetNameAndTagInPath() throws ServletException, IOException {
-
- final String testTag = "testTag";
- final String testName = "test name";
-
- doReturn(testTag + "," + testName).when(request).getPathInfo();
- doReturn("false").when(request).getParameter(HealthCheckExecutorServlet.PARAM_COMBINE_TAGS_WITH_OR.name);
- final List<HealthCheckExecutionResult> executionResults = getExecutionResults(Result.Status.CRITICAL);
- doReturn(executionResults).when(healthCheckExecutor).execute(selector(new String[] { testTag }, new String[] { testName }), eq(new HealthCheckExecutionOptions()));
-
- healthCheckExecutorServlet.doGet(request, response);
-
- verify(request, never()).getParameter(HealthCheckExecutorServlet.PARAM_TAGS.name);
- verify(request, never()).getParameter(HealthCheckExecutorServlet.PARAM_NAMES.name);
- verifyZeroInteractions(jsonSerializer);
- verifyZeroInteractions(txtSerializer);
- verifyZeroInteractions(verboseTxtSerializer);
- verify(htmlSerializer)
- .serialize(resultEquals(new Result(Result.Status.CRITICAL, "Overall Status CRITICAL")), eq(executionResults), contains("Supported URL parameters"), eq(false));
- }
-
- @Test
- public void testDoGetJson() throws ServletException, IOException {
-
- final String testTag = "testTag";
- doReturn("true").when(request).getParameter(HealthCheckExecutorServlet.PARAM_COMBINE_TAGS_WITH_OR.name);
- int timeout = 5000;
- doReturn(timeout + "").when(request).getParameter(HealthCheckExecutorServlet.PARAM_OVERRIDE_GLOBAL_TIMEOUT.name);
- doReturn("/" + testTag + ".json").when(request).getPathInfo();
- final List<HealthCheckExecutionResult> executionResults = getExecutionResults(Result.Status.WARN);
- HealthCheckExecutionOptions options = new HealthCheckExecutionOptions();
- options.setCombineTagsWithOr(true);
- options.setOverrideGlobalTimeout(timeout);
- doReturn(executionResults).when(healthCheckExecutor).execute(selector(new String[] { testTag }, new String[0]), eq(options));
-
- healthCheckExecutorServlet.doGet(request, response);
-
- verifyZeroInteractions(htmlSerializer);
- verifyZeroInteractions(txtSerializer);
- verifyZeroInteractions(verboseTxtSerializer);
- verify(jsonSerializer).serialize(resultEquals(new Result(Result.Status.WARN, "Overall Status WARN")), eq(executionResults), anyString(),
- eq(false));
-
- }
-
- @Test
- public void testDoGetTxt() throws ServletException, IOException {
-
- final String testTag = "testTag";
- doReturn(testTag).when(request).getParameter(HealthCheckExecutorServlet.PARAM_TAGS.name);
- doReturn(HealthCheckExecutorServlet.FORMAT_TXT).when(request).getParameter(HealthCheckExecutorServlet.PARAM_FORMAT.name);
- doReturn("true").when(request).getParameter(HealthCheckExecutorServlet.PARAM_COMBINE_TAGS_WITH_OR.name);
- int timeout = 5000;
- doReturn(timeout + "").when(request).getParameter(HealthCheckExecutorServlet.PARAM_OVERRIDE_GLOBAL_TIMEOUT.name);
- final List<HealthCheckExecutionResult> executionResults = getExecutionResults(Result.Status.WARN);
- HealthCheckExecutionOptions options = new HealthCheckExecutionOptions();
- options.setCombineTagsWithOr(true);
- options.setOverrideGlobalTimeout(timeout);
-
- doReturn(executionResults).when(healthCheckExecutor).execute(selector(new String[] { testTag }, new String[0]), eq(options));
-
- healthCheckExecutorServlet.doGet(request, response);
-
- verifyZeroInteractions(htmlSerializer);
- verifyZeroInteractions(jsonSerializer);
- verifyZeroInteractions(verboseTxtSerializer);
- verify(txtSerializer).serialize(resultEquals(new Result(Result.Status.WARN, "Overall Status WARN")));
-
- }
-
- @Test
- public void testDoGetVerboseTxt() throws ServletException, IOException {
-
- String testTag = "testTag";
- doReturn(testTag).when(request).getParameter(HealthCheckExecutorServlet.PARAM_TAGS.name);
- doReturn(HealthCheckExecutorServlet.FORMAT_VERBOSE_TXT).when(request).getParameter(HealthCheckExecutorServlet.PARAM_FORMAT.name);
-
- List<HealthCheckExecutionResult> executionResults = getExecutionResults(Result.Status.WARN);
- doReturn(executionResults).when(healthCheckExecutor).execute(selector(new String[] { testTag }, new String[0]), any(HealthCheckExecutionOptions.class));
-
- healthCheckExecutorServlet.doGet(request, response);
-
- verifyZeroInteractions(htmlSerializer);
- verifyZeroInteractions(jsonSerializer);
- verifyZeroInteractions(txtSerializer);
- verify(verboseTxtSerializer).serialize(resultEquals(new Result(Result.Status.WARN, "Overall Status WARN")), eq(executionResults), eq(false));
-
- }
-
- private List<HealthCheckExecutionResult> getExecutionResults(Result.Status worstStatus) {
- List<HealthCheckExecutionResult> results = new ArrayList<HealthCheckExecutionResult>();
- results.add(new ExecutionResult(new HealthCheckMetadata(hcServiceRef), new Result(worstStatus, worstStatus.name()), 100));
- results.add(new ExecutionResult(new HealthCheckMetadata(hcServiceRef), new Result(Result.Status.OK, "OK"), 100));
- return results;
- }
-
- @Test
- public void testGetStatusMapping() throws ServletException {
-
- Map<Status, Integer> statusMapping = healthCheckExecutorServlet.getStatusMapping("CRITICAL:503");
- assertEquals(statusMapping.get(Result.Status.OK), (Integer) 200);
- assertEquals(statusMapping.get(Result.Status.WARN), (Integer) 200);
- assertEquals(statusMapping.get(Result.Status.CRITICAL), (Integer) 503);
- assertEquals(statusMapping.get(Result.Status.HEALTH_CHECK_ERROR), (Integer) 503);
-
- statusMapping = healthCheckExecutorServlet.getStatusMapping("OK:333");
- assertEquals(statusMapping.get(Result.Status.OK), (Integer) 333);
- assertEquals(statusMapping.get(Result.Status.WARN), (Integer) 333);
- assertEquals(statusMapping.get(Result.Status.CRITICAL), (Integer) 333);
- assertEquals(statusMapping.get(Result.Status.HEALTH_CHECK_ERROR), (Integer) 333);
-
- statusMapping = healthCheckExecutorServlet.getStatusMapping("OK:200,WARN:418,CRITICAL:503,HEALTH_CHECK_ERROR:500");
- assertEquals(statusMapping.get(Result.Status.OK), (Integer) 200);
- assertEquals(statusMapping.get(Result.Status.WARN), (Integer) 418);
- assertEquals(statusMapping.get(Result.Status.CRITICAL), (Integer) 503);
- assertEquals(statusMapping.get(Result.Status.HEALTH_CHECK_ERROR), (Integer) 500);
-
- statusMapping = healthCheckExecutorServlet.getStatusMapping("CRITICAL:503,HEALTH_CHECK_ERROR:500");
- assertEquals(statusMapping.get(Result.Status.OK), (Integer) 200);
- assertEquals(statusMapping.get(Result.Status.WARN), (Integer) 200);
- assertEquals(statusMapping.get(Result.Status.CRITICAL), (Integer) 503);
- assertEquals(statusMapping.get(Result.Status.HEALTH_CHECK_ERROR), (Integer) 500);
-
- }
-
- @Test(expected = ServletException.class)
- public void testGetStatusMappingInvalidToken() throws ServletException {
- healthCheckExecutorServlet.getStatusMapping("CRITICAL");
- }
-
- @Test(expected = ServletException.class)
- public void testGetStatusMappingInvalidStatus() throws ServletException {
- healthCheckExecutorServlet.getStatusMapping("INVALID:200");
- }
-
- @Test(expected = ServletException.class)
- public void testGetStatusMappingInvalidStatusCode() throws ServletException {
- healthCheckExecutorServlet.getStatusMapping("CRITICAL:xxx");
- }
-
- static Result resultEquals(Result expected) {
- return argThat(new ResultMatcher(expected));
- }
-
- static class ResultMatcher extends ArgumentMatcher<Result> {
-
- private final Result expectedResult;
-
- public ResultMatcher(Result expected) {
- this.expectedResult = expected;
- }
-
- @Override
- public boolean matches(Object actual) {
- Result actualResult = (Result) actual;
- return actualResult.getStatus().equals(expectedResult.getStatus()); // simple status matching only sufficient for this test case
- }
-
- @Override
- public void describeTo(Description description) {
- description.appendText(expectedResult == null ? null : expectedResult.toString());
- }
- }
-
- HealthCheckSelector selector(final String[] tags, final String[] names) {
- return argThat(new ArgumentMatcher<HealthCheckSelector>() {
- @Override
- public boolean matches(Object actual) {
- if (actual instanceof HealthCheckSelector) {
- HealthCheckSelector actualSelector = (HealthCheckSelector) actual;
- return Arrays.equals(actualSelector.tags(), tags.length == 0 ? new String[] { "" } : tags) &&
- Arrays.equals(actualSelector.names(), names.length == 0 ? new String[] { "" } : names);
- } else {
- return false;
- }
- }
- });
- }
-
-
-}
diff --git a/src/test/java/org/apache/sling/hc/core/it/AsyncHealthCheckIT.java b/src/test/java/org/apache/sling/hc/core/it/AsyncHealthCheckIT.java
deleted file mode 100644
index 543cd56..0000000
--- a/src/test/java/org/apache/sling/hc/core/it/AsyncHealthCheckIT.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.sling.hc.core.it;
-
-import static org.junit.Assert.assertTrue;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.inject.Inject;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import static org.junit.Assert.fail;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-@RunWith(PaxExam.class)
-public class AsyncHealthCheckIT {
-
- @Inject
- private HealthCheckExecutor executor;
-
- @Inject
- private BundleContext bundleContext;
-
- @Configuration
- public Option[] config() {
- return U.config();
- }
-
- final AtomicInteger counter = new AtomicInteger(Integer.MIN_VALUE);
-
- final static int MAX_VALUE = 12345678;
-
- class TestHC implements HealthCheck {
- @Override
- public Result execute() {
- final int v = counter.incrementAndGet();
- return new Result(v > MAX_VALUE ? Result.Status.WARN : Result.Status.OK, "counter is now " + v);
- }
- }
-
- private ServiceRegistration register(HealthCheck hc, String id, int stickyMinutes) {
- final Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(HealthCheck.NAME, "name_" + id);
- props.put(HealthCheck.TAGS, id);
- props.put(HealthCheck.ASYNC_CRON_EXPRESSION, "*/1 * * * * ?");
-
- if(stickyMinutes > 0) {
- props.put(HealthCheck.WARNINGS_STICK_FOR_MINUTES, stickyMinutes);
- }
-
- final ServiceRegistration result = bundleContext.registerService(HealthCheck.class.getName(), hc, props);
-
- // Wait for HC to be registered
- U.expectHealthChecks(1, executor, id);
-
- return result;
- }
-
- private void assertStatus(String id, Result.Status expected, long maxMsec, String msg) throws InterruptedException {
- final long timeout = System.currentTimeMillis() + 5000L;
- while(System.currentTimeMillis() < timeout) {
- final Result.Status actual = executor.execute(HealthCheckSelector.tags(id)).get(0).getHealthCheckResult().getStatus();
- if(actual == expected) {
- return;
- }
- Thread.sleep(100L);
- }
- fail("Did not get status " + expected + " after " + maxMsec + " msec " + msg);
- }
-
- @Test
- public void testAsyncHealthCheckExecution() throws InterruptedException {
- final String id = UUID.randomUUID().toString();
- final HealthCheck hc = new TestHC();
- final ServiceRegistration reg = register(hc, id, 0);
- final long maxMsec = 5000L;
-
- try {
- // Reset the counter and check that HC increments it even if we don't
- // use the executor
- {
- counter.set(0);
- final long timeout = System.currentTimeMillis() + maxMsec;
- while(System.currentTimeMillis() < timeout) {
- if(counter.get() > 0) {
- break;
- }
- Thread.sleep(100L);
- }
- assertTrue("Expecting counter to be incremented", counter.get() > 0);
- }
-
- // Verify that we get the right log
- final String msg = executor.execute(HealthCheckSelector.tags(id)).get(0).getHealthCheckResult().iterator().next().getMessage();
- assertTrue("Expecting the right message: " + msg, msg.contains("counter is now"));
-
- // And verify that calling executor lots of times doesn't increment as much
- final int previous = counter.get();
- final int n = 100;
- for(int i=0; i < n; i++) {
- executor.execute(HealthCheckSelector.tags(id));
- }
- assertTrue("Expecting counter to increment asynchronously", counter.get() < previous + n);
-
- // Verify that results are not sticky
- assertStatus(id, Result.Status.OK, maxMsec, "before WARN");
- counter.set(MAX_VALUE + 1);
- assertStatus(id, Result.Status.WARN, maxMsec, "right after WARN");
- counter.set(0);
- assertStatus(id, Result.Status.OK, maxMsec, "after resetting counter");
-
- } finally {
- reg.unregister();
- }
-
- }
-
- @Test
- public void testAsyncHealthCheckWithStickyResults() throws InterruptedException {
- final String id = UUID.randomUUID().toString();
- final HealthCheck hc = new TestHC();
- final long maxMsec = 5000L;
- final int stickyMinutes = 1;
- final ServiceRegistration reg = register(hc, id, stickyMinutes);
-
- try {
- assertStatus(id, Result.Status.OK, maxMsec, "before WARN");
- counter.set(MAX_VALUE + 1);
- assertStatus(id, Result.Status.WARN, maxMsec, "right after WARN");
- counter.set(0);
-
- // Counter should be incremented after a while, and in range, but with sticky WARN result
- final long timeout = System.currentTimeMillis() + maxMsec;
- boolean ok = false;
- while(System.currentTimeMillis() < timeout) {
- if(counter.get() > 0 && counter.get() < MAX_VALUE) {
- ok = true;
- break;
- }
- Thread.sleep(100L);
- }
-
- assertTrue("expecting counter to be incremented", ok);
- assertStatus(id, Result.Status.WARN, maxMsec, "after resetting counter, expecting sticky result");
-
- } finally {
- reg.unregister();
- }
- }
-
-}
diff --git a/src/test/java/org/apache/sling/hc/core/it/ExtendedHealthCheckExecutorIT.java b/src/test/java/org/apache/sling/hc/core/it/ExtendedHealthCheckExecutorIT.java
deleted file mode 100644
index fcb8df6..0000000
--- a/src/test/java/org/apache/sling/hc/core/it/ExtendedHealthCheckExecutorIT.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.sling.hc.core.it;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.apache.sling.hc.util.HealthCheckFilter;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/** Additional executor tests */
-@RunWith(PaxExam.class)
-public class ExtendedHealthCheckExecutorIT {
-
- @Inject
- private HealthCheckExecutor executor;
-
- @Inject
- private BundleContext bundleContext;
-
- @SuppressWarnings("rawtypes")
- private List<ServiceRegistration> regs = new ArrayList<ServiceRegistration>();
-
- private String testTag;
- private final Result.Status testResult = Result.Status.OK;
-
- @Configuration
- public Option[] config() {
- return U.config();
- }
-
- private void registerHC(final String ... tags) {
- final HealthCheck hc = new HealthCheck() {
- @Override
- public Result execute() {
- return new Result(testResult, "Returning " + testResult + " for " + tags[0]);
- }
-
- };
-
- final Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(HealthCheck.NAME, "name_" + tags[0]);
- props.put(HealthCheck.TAGS, tags);
-
- regs.add(bundleContext.registerService(HealthCheck.class.getName(), hc, props));
- }
-
- @Before
- public void setup() {
- testTag = "TEST_" + UUID.randomUUID().toString();
- registerHC(testTag);
- U.expectHealthChecks(1, executor, testTag);
- }
-
- @After
- public void cleanup() {
- for(ServiceRegistration reg : regs) {
- reg.unregister();
- }
- }
-
- @Test
- public void testSingleExecution() throws Exception {
- final HealthCheckFilter filter = new HealthCheckFilter(bundleContext);
- final ServiceReference [] refs = filter.getHealthCheckServiceReferences(HealthCheckSelector.tags(testTag));
- assertNotNull(refs);
- assertEquals(1, refs.length);
-
- // The ExtendedHealthCheckExecutor interface is not public, so we cheat
- // to be able to test its implementation
- final Method m = executor.getClass().getMethod("execute", ServiceReference.class);
- final HealthCheckExecutionResult result = (HealthCheckExecutionResult)m.invoke(executor, refs[0]);
- assertEquals(testResult, result.getHealthCheckResult().getStatus());
- }
-}
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/hc/core/it/HealthCheckExecutorSelectionIT.java b/src/test/java/org/apache/sling/hc/core/it/HealthCheckExecutorSelectionIT.java
deleted file mode 100644
index 088c490..0000000
--- a/src/test/java/org/apache/sling/hc/core/it/HealthCheckExecutorSelectionIT.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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.sling.hc.core.it;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionOptions;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-/** Test the HealthCheckExecutor selection mechanism */
-@RunWith(PaxExam.class)
-public class HealthCheckExecutorSelectionIT {
-
- @Inject
- private HealthCheckExecutor executor;
-
- @Inject
- private BundleContext bundleContext;
-
- private static String idA;
- private static String idB;
- private HealthCheckExecutionOptions options;
-
- @SuppressWarnings("rawtypes")
- private List<ServiceRegistration> regs = new ArrayList<ServiceRegistration>();
-
- @Configuration
- public Option[] config() {
- return U.config();
- }
-
- private void registerHC(final String ... tags) {
- final HealthCheck hc = new HealthCheck() {
- @Override
- public Result execute() {
- return new Result(Result.Status.OK, "All good for " + tags[0]);
- }
-
- };
-
- final Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(HealthCheck.NAME, "name_" + tags[0]);
- props.put(HealthCheck.TAGS, tags);
-
- regs.add(bundleContext.registerService(HealthCheck.class.getName(), hc, props));
- }
-
- @BeforeClass
- public static void setId() {
- idA = UUID.randomUUID().toString();
- idB = UUID.randomUUID().toString();
- }
-
- @Before
- public void setup() {
- options = new HealthCheckExecutionOptions();
-
- U.expectHealthChecks(0, executor, idA);
- U.expectHealthChecks(0, executor, idB);
-
- registerHC(idA);
- registerHC(idB);
- registerHC(idB);
- registerHC(idA, idB);
- }
-
- @After
- @SuppressWarnings("rawtypes")
- public void cleanup() {
- for(ServiceRegistration r : regs) {
- r.unregister();
- }
- regs.clear();
-
- U.expectHealthChecks(0, executor, idA);
- U.expectHealthChecks(0, executor, idB);
- }
-
- @Test
- public void testDefaultSelectionA(){
- U.expectHealthChecks(2, executor, idA);
- U.expectHealthChecks(2, executor, options, idA);
- }
-
- @Test
- public void testDefaultSelectionB(){
- U.expectHealthChecks(3, executor, idB);
- U.expectHealthChecks(3, executor, options, idB);
- }
-
- @Test
- public void testDefaultSelectionAB(){
- U.expectHealthChecks(1, executor, idA, idB);
- U.expectHealthChecks(1, executor, options, idA, idB);
- }
-
- @Test
- public void testOrSelectionA(){
- options.setCombineTagsWithOr(true);
- U.expectHealthChecks(1, executor, options, idA);
- }
-
- @Test
- public void testOrSelectionB(){
- options.setCombineTagsWithOr(true);
- U.expectHealthChecks(3, executor, options, idB);
- }
-
- @Test
- public void testOrSelectionAB(){
- options.setCombineTagsWithOr(true);
- U.expectHealthChecks(4, executor, options, idA, idB);
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/core/it/HealthCheckFilterIT.java b/src/test/java/org/apache/sling/hc/core/it/HealthCheckFilterIT.java
deleted file mode 100644
index ffb2f31..0000000
--- a/src/test/java/org/apache/sling/hc/core/it/HealthCheckFilterIT.java
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * 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.sling.hc.core.it;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.inject.Inject;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.apache.sling.hc.util.HealthCheckFilter;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@RunWith(PaxExam.class)
-public class HealthCheckFilterIT {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- private HealthCheckFilter filter;
-
- @Inject
- private BundleContext bundleContext;
-
- private List<TestHealthCheck> testServices = new ArrayList<TestHealthCheck>();
- private static int instanceCounter = 0;
-
- class TestHealthCheckBuilder {
-
- String[] tags;
- String name;
-
- TestHealthCheckBuilder withTags(String... tags) {
- this.tags = tags;
- return this;
- }
-
- TestHealthCheckBuilder withName(String name) {
- this.name = name;
- return this;
- }
-
- TestHealthCheck build() {
- final Dictionary<String, Object> props = new Hashtable<String, Object>();
- if (tags != null) {
- props.put(HealthCheck.TAGS, tags);
- }
- if (name != null) {
- props.put(HealthCheck.NAME, name);
- }
-
- return new TestHealthCheck(props);
-
- }
- }
-
- class TestHealthCheck implements HealthCheck {
-
- private final int id;
- private final ServiceRegistration reg;
-
- TestHealthCheck(Dictionary<String, Object> props) {
- id = instanceCounter++;
- reg = bundleContext.registerService(HealthCheck.class.getName(),
- this, props);
- log.info("Registered {} with name {} and tags {}", new Object[] { this, props.get(HealthCheck.NAME), Arrays.toString((String[]) props.get(HealthCheck.TAGS)) });
- }
-
- @Override
- public String toString() {
- return "TestHealthCheck#" + id;
- }
-
- @Override
- public boolean equals(Object other) {
- return other instanceof TestHealthCheck
- && ((TestHealthCheck) other).id == id;
- }
-
- @Override
- public int hashCode() {
- return id;
- }
-
- @Override
- public Result execute() {
- return null;
- }
-
- void unregister() {
- reg.unregister();
- }
- }
-
- private TestHealthCheckBuilder builder() {
- return new TestHealthCheckBuilder();
- }
-
- @Configuration
- public Option[] config() {
- return U.config();
- }
-
- @Before
- public void setup() {
- testServices.add(builder().withTags("foo").withName("test1").build());
- testServices.add(builder().withTags("bar").withName("test2").build());
- testServices.add(builder().withTags("foo", "bar").withName("test3").build());
- testServices.add(builder().withTags("other", "thing").withName("test4").build());
- testServices.add(builder().withName("test5").build());
- filter = new HealthCheckFilter(bundleContext);
- }
-
- @After
- public void cleanup() {
- for (TestHealthCheck tc : testServices) {
- tc.unregister();
- }
- }
-
- /**
- * @param included
- * true or false, in the same order as testServices
- */
- private void assertServices(List<HealthCheck> s, boolean... included) {
- final Iterator<TestHealthCheck> it = testServices.iterator();
- for (boolean inc : included) {
- final TestHealthCheck thc = it.next();
- if (inc) {
- assertTrue("Expecting list of services to include " + thc,
- s.contains(thc));
- } else {
- assertFalse("Not expecting list of services to include " + thc,
- s.contains(thc));
- }
- }
- }
-
- @Test
- public void testSelectorService() {
- assertNotNull("Expecting HealthCheckSelector service to be provided",
- filter);
- }
-
- @Test
- public void testAllServices() {
- final List<HealthCheck> s = filter.getHealthChecks(null);
- assertServices(s, true, true, true, true, true);
- }
-
- @Test
- public void testEmptyTags() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("", "", ""));
- assertServices(s, true, true, true, true, true);
- }
-
- @Test
- public void testFooTag() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("foo"));
- assertServices(s, true, false, true, false, false);
- }
-
- @Test
- public void testBarTag() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("bar"));
- assertServices(s, false, true, true, false, false);
- }
-
- @Test
- public void testFooAndBar() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("foo", "bar"));
- assertServices(s, false, false, true, false, false);
- }
-
- @Test
- public void testFooMinusBar() {
- final List<HealthCheck> s = filter
- .getHealthChecks(HealthCheckSelector.tags("foo", "-bar"));
- assertServices(s, true, false, false, false, false);
- }
-
- @Test
- public void testWhitespace() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags(
- "\t \n\r foo \t", "", " \t-bar\n", ""));
- assertServices(s, true, false, false, false, false);
- }
-
- @Test
- public void testOther() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("other"));
- assertServices(s, false, false, false, true, false);
- }
-
- @Test
- public void testMinusOther() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("-other"));
- assertServices(s, true, true, true, false, true);
- }
-
- @Test
- public void testMinusOtherFoo() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("-other",
- "-foo"));
- assertServices(s, false, true, false, false, true);
- }
-
- @Test
- public void testNoResults() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("NOT A TAG"));
- assertTrue("Expecting no services", s.isEmpty());
- }
-
- @Test
- public void testSingleName() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.names("test1"));
- assertServices(s, true, false, false, false, false);
- }
-
- @Test
- public void testMultipleNames() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.names("test1", "test3"));
- assertServices(s, true, false, true, false, false);
- }
-
- @Test
- public void testExcludeName() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("foo").withNames("-test1"));
- assertServices(s, false, false, true, false, false);
- }
-
- @Test
- public void testNameOrTag() {
- final List<HealthCheck> s = filter.getHealthChecks(HealthCheckSelector.tags("foo").withNames("test4"));
- assertServices(s, true, false, true, true, false);
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/core/it/HealthCheckServletIT.java b/src/test/java/org/apache/sling/hc/core/it/HealthCheckServletIT.java
deleted file mode 100644
index 2a90159..0000000
--- a/src/test/java/org/apache/sling/hc/core/it/HealthCheckServletIT.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.sling.hc.core.it;
-
-import static org.junit.Assert.assertEquals;
-
-import java.io.IOException;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.UUID;
-
-import javax.inject.Inject;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.http.HttpService;
-
-/** Verify that the HealthCheckExecutorServlet becomes available
- * after creating the corresponding config
- */
-@RunWith(PaxExam.class)
-public class HealthCheckServletIT {
-
- @Inject
- private ConfigurationAdmin configAdmin;
-
- @Inject
- private BundleContext bundleContext;
-
- private MockHttpService httpService;
- private ServiceRegistration reg;
-
- @Configuration
- public Option[] config() {
- return U.config();
- }
-
- private int countServletServices(String packageNamePrefix) throws InvalidSyntaxException {
- final List<String> classNames = httpService.getServletClassNames();
- int count = 0;
- for(final String className : classNames) {
- if(className.startsWith(packageNamePrefix)) {
- count++;
- }
- }
- return count;
- }
-
- @Before
- public void setup() {
- httpService = new MockHttpService();
- reg = bundleContext.registerService(HttpService.class.getName(), httpService, null);
- }
-
- @After
- public void cleanup() {
- reg.unregister();
- reg = null;
- httpService = null;
- }
-
- @Test
- public void testServletBecomesActive() throws InvalidSyntaxException, IOException, InterruptedException {
- final String property = "servletPath";
- final String path = "/test/" + UUID.randomUUID();
- final String packagePrefix = "org.apache.sling.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.sling.hc.core.impl.servlet.HealthCheckExecutorServlet";
- final org.osgi.service.cm.Configuration cfg = configAdmin.getConfiguration(pid, null);
- final Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(property, path);
- cfg.update(props);
-
- final long timeoutMsec = 5000L;
- final long endTime = System.currentTimeMillis() + timeoutMsec;
- while(System.currentTimeMillis() < endTime) {
- if(countServletServices(packagePrefix) > 0) {
- break;
- }
- Thread.sleep(50L);
- }
-
- int expectedServletCount = 6;
- assertEquals("After adding configuration, expecting six servlets from " + packagePrefix, expectedServletCount, 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, 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", paths.get(paths.size() - 1));
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/core/it/JmxAdjustableStatusForTestingIT.java b/src/test/java/org/apache/sling/hc/core/it/JmxAdjustableStatusForTestingIT.java
deleted file mode 100644
index 517434b..0000000
--- a/src/test/java/org/apache/sling/hc/core/it/JmxAdjustableStatusForTestingIT.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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.sling.hc.core.it;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.management.DynamicMBean;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.ResultLog;
-import org.apache.sling.hc.api.ResultLog.Entry;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.apache.sling.hc.util.FormattingResultLog;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-
-/** Test jmx-adjustable status for testing HC. */
-@RunWith(PaxExam.class)
-public class JmxAdjustableStatusForTestingIT {
-
- @Inject
- private HealthCheckExecutor executor;
-
- @Inject
- private BundleContext bundleContext;
-
- private static String testTag = "testTagName";
-
- @SuppressWarnings("rawtypes")
- private List<ServiceRegistration> regs = new ArrayList<ServiceRegistration>();
-
- @Configuration
- public Option[] config() {
- return U.config();
- }
-
- private void assertResult(String tag, Result.Status expected) {
- final Result result = getOverallResult(executor.execute(HealthCheckSelector.tags(tag)));
- assertEquals("Expected status " + expected + " for tag " + tag, expected, result.getStatus());
- }
-
- @Before
- public void setup() {
- U.expectHealthChecks(0, executor, testTag);
- registerHC(testTag);
- U.expectHealthChecks(1, executor, testTag);
- assertResult(testTag, Result.Status.OK);
- }
-
- @After
- @SuppressWarnings("rawtypes")
- public void cleanup() throws Exception {
- invokeMBean("reset", new Object[] {}, new String[] {});
-
- U.expectHealthChecks(1, executor, testTag);
- assertResult(testTag, Result.Status.OK);
-
- for (ServiceRegistration r : regs) {
- r.unregister();
- }
- regs.clear();
- U.expectHealthChecks(0, executor, testTag);
- }
-
- @Test
- public void testWarnStatus() throws Exception {
- invokeMBean("addWarnResultForTags", new Object[] { testTag }, new String[] { String.class.getName() });
- U.expectHealthChecks(2, executor, testTag);
- assertResult(testTag, Result.Status.WARN);
- }
-
- @Test
- public void testCriticalStatus() throws Exception {
- invokeMBean("addCriticalResultForTags", new Object[] { "anotherTag," + testTag },
- new String[] { String.class.getName() });
-
- final String [] tags = { "anotherTag", testTag };
- for(String tag : tags) {
- U.expectHealthChecks(2, executor, testTag);
- assertResult(tag, Result.Status.CRITICAL);
- }
- }
-
- @Test
- public void testAnotherTag() throws Exception {
- // Selecting an unused tag returns WARN - not sure why but
- // if that changes we should detect it.
- assertResult("some_unused_tag", Result.Status.WARN);
- }
-
- private void registerHC(final String... tags) {
- final HealthCheck hc = new HealthCheck() {
- @Override
- public Result execute() {
- return new Result(Result.Status.OK, "All good for " + tags[0]);
- }
- };
-
- final Dictionary<String, Object> props = new Hashtable<String, Object>();
- props.put(HealthCheck.NAME, "name_" + tags[0]);
- props.put(HealthCheck.TAGS, tags);
-
- regs.add(bundleContext.registerService(HealthCheck.class.getName(), hc, props));
- }
-
- private void invokeMBean(String operation, Object[] args, String[] signature) throws Exception {
-
- ServiceReference[] serviceReference = bundleContext.getServiceReferences(DynamicMBean.class.getName(),
- "(jmx.objectname=org.apache.sling.healthcheck:type=AdjustableHealthCheckForTesting)");
- DynamicMBean mBean = (DynamicMBean) bundleContext.getService(serviceReference[0]);
- mBean.invoke(operation, args, signature);
-
- }
-
- private Result getOverallResult(List<HealthCheckExecutionResult> results) {
- FormattingResultLog resultLog = new FormattingResultLog();
- for (HealthCheckExecutionResult executionResult : results) {
- for (Entry entry : executionResult.getHealthCheckResult()) {
- resultLog.add(new ResultLog.Entry(entry.getStatus(), entry.getMessage(), entry.getException()));
- }
- }
- return new Result(resultLog);
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/core/it/MockHttpService.java b/src/test/java/org/apache/sling/hc/core/it/MockHttpService.java
deleted file mode 100644
index 9c33f47..0000000
--- a/src/test/java/org/apache/sling/hc/core/it/MockHttpService.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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.sling.hc.core.it;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.List;
-
-import javax.servlet.Servlet;
-
-import org.osgi.service.http.HttpContext;
-import org.osgi.service.http.HttpService;
-
-class MockHttpService implements HttpService {
-
- private List<String> paths = new ArrayList<String>();
-
- private List<String> classNames = new ArrayList<String>();
-
- @Override
- public void registerResources(String alias, String name, HttpContext context) {
- }
-
- @Override
- public void registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext context) {
- paths.add(alias);
- classNames.add(servlet.getClass().getName());
- }
-
- public void unregister(String alias) {
- paths.remove(alias);
- }
-
- @Override
- public HttpContext createDefaultHttpContext() {
- return null;
- }
-
- List<String> getPaths() {
- return Collections.unmodifiableList(paths);
- }
-
- List<String> getServletClassNames() {
- return Collections.unmodifiableList(classNames);
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/core/it/U.java b/src/test/java/org/apache/sling/hc/core/it/U.java
deleted file mode 100644
index b03e315..0000000
--- a/src/test/java/org/apache/sling/hc/core/it/U.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * 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.sling.hc.core.it;
-
-import static org.junit.Assert.fail;
-import static org.ops4j.pax.exam.CoreOptions.bundle;
-import static org.ops4j.pax.exam.CoreOptions.junitBundles;
-import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.provision;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-import static org.ops4j.pax.exam.CoreOptions.when;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.sling.hc.api.execution.HealthCheckExecutionOptions;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckExecutor;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.ops4j.pax.exam.CoreOptions;
-import org.ops4j.pax.exam.Option;
-
-/** Test utilities */
-public class U {
-
- // the name of the system property providing the bundle file to be installed and tested
- private static final String BUNDLE_JAR_SYS_PROP = "project.bundle.file";
-
- /** Wait until the specified number of health checks are seen by supplied executor */
- static void expectHealthChecks(int howMany, HealthCheckExecutor executor, String ... tags) {
- expectHealthChecks(howMany, executor, new HealthCheckExecutionOptions(), tags);
- }
-
- /** Wait until the specified number of health checks are seen by supplied executor */
- static void expectHealthChecks(int howMany, HealthCheckExecutor executor, HealthCheckExecutionOptions options, String ... tags) {
- final long timeout = System.currentTimeMillis() + 10000L;
- int count = 0;
- while(System.currentTimeMillis() < timeout) {
- final List<HealthCheckExecutionResult> results = executor.execute(HealthCheckSelector.tags(tags), options);
- count = results.size();
- if(count== howMany) {
- return;
- }
- try {
- Thread.sleep(100L);
- } catch(InterruptedException iex) {
- throw new RuntimeException("Unexpected InterruptedException");
- }
- }
- fail("Did not get " + howMany + " health checks with tags " + Arrays.asList(tags) + " after " + timeout + " msec (last count=" + count + ")");
- }
-
- static Option[] config() {
- final String localRepo = System.getProperty("maven.repo.local", "");
- final boolean felixShell = "true".equals(System.getProperty("felix.shell", "false"));
-
- final String bundleFileName = System.getProperty(BUNDLE_JAR_SYS_PROP);
- final File bundleFile = new File(bundleFileName);
- if (!bundleFile.canRead()) {
- throw new IllegalArgumentException( "Cannot read from bundle file " + bundleFileName + " specified in the "
- + BUNDLE_JAR_SYS_PROP + " system property" );
- }
-
- // As we're using the forked pax exam container, we need to add a VM
- // option to activate the jacoco test coverage agent.
- final String coverageCommand = System.getProperty("coverage.command");
-
- return options(
- when(localRepo.length() > 0).useOptions(
- systemProperty("org.ops4j.pax.url.mvn.localRepository").value(localRepo)
- ),
- junitBundles(),
- when(coverageCommand != null && coverageCommand.trim().length() > 0).useOptions(
- CoreOptions.vmOption(coverageCommand)
- ),
- when(felixShell).useOptions(
- provision(
- mavenBundle("org.apache.felix", "org.apache.felix.gogo.shell", "0.10.0"),
- mavenBundle("org.apache.felix", "org.apache.felix.gogo.runtime", "0.10.0"),
- mavenBundle("org.apache.felix", "org.apache.felix.gogo.command", "0.12.0"),
- mavenBundle("org.apache.felix", "org.apache.felix.shell.remote", "1.1.2")
- )
- ),
- provision(
- bundle(bundleFile.toURI().toString()),
- mavenBundle().groupId("javax.servlet").artifactId("javax.servlet-api").versionAsInProject(),
- mavenBundle("org.apache.felix", "org.apache.felix.scr", "2.0.14"),
- mavenBundle("org.apache.felix", "org.apache.felix.configadmin", "1.8.16"),
- mavenBundle("org.apache.sling", "org.apache.sling.commons.osgi", "2.2.0"),
- mavenBundle("org.apache.sling", "org.apache.sling.commons.johnzon").versionAsInProject(),
- mavenBundle("org.apache.sling", "org.apache.sling.jcr.jcr-wrapper", "2.0.0"),
- mavenBundle("org.apache.sling", "org.apache.sling.api", "2.4.2"),
- mavenBundle("org.apache.sling", "org.apache.sling.hc.api").versionAsInProject(),
- mavenBundle("org.apache.sling", "org.apache.sling.jcr.api", "2.1.0"),
- mavenBundle("org.apache.sling", "org.apache.sling.engine", "2.2.8"),
- mavenBundle("org.apache.sling", "org.apache.sling.auth.core", "1.1.2"),
- mavenBundle("org.apache.sling", "org.apache.sling.commons.mime", "2.1.4"),
- mavenBundle("org.apache.sling", "org.apache.sling.settings", "1.2.2"),
- mavenBundle("org.apache.sling", "org.apache.sling.launchpad.api", "1.1.0"),
- mavenBundle("org.apache.sling", "org.apache.sling.scripting.api", "2.1.0"),
- mavenBundle("org.apache.sling", "org.apache.sling.commons.threads", "3.1.0"),
- mavenBundle("org.apache.sling", "org.apache.sling.commons.scheduler", "2.4.2"),
- mavenBundle("commons-collections", "commons-collections", "3.2.1"),
- mavenBundle().groupId("commons-io").artifactId("commons-io").versionAsInProject(),
- mavenBundle("commons-fileupload", "commons-fileupload", "1.2.2"),
- mavenBundle().groupId("org.apache.commons").artifactId("commons-lang3").versionAsInProject()
- )
- );
- }
-}
diff --git a/src/test/java/org/apache/sling/hc/jmx/impl/HealthCheckMBeanTest.java b/src/test/java/org/apache/sling/hc/jmx/impl/HealthCheckMBeanTest.java
deleted file mode 100644
index 7bc1047..0000000
--- a/src/test/java/org/apache/sling/hc/jmx/impl/HealthCheckMBeanTest.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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.sling.hc.jmx.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.lang.management.ManagementFactory;
-import java.util.Date;
-import java.util.List;
-
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.apache.sling.hc.api.HealthCheck;
-import org.apache.sling.hc.api.Result;
-import org.apache.sling.hc.api.ResultLog;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionOptions;
-import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
-import org.apache.sling.hc.api.execution.HealthCheckSelector;
-import org.apache.sling.hc.core.impl.executor.ExtendedHealthCheckExecutor;
-import org.apache.sling.hc.util.HealthCheckMetadata;
-import org.apache.sling.hc.util.SimpleConstraintChecker;
-import org.junit.Test;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-
-public class HealthCheckMBeanTest {
- private final MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();
- private boolean resultOk;
- public static final String OBJECT_NAME = "org.apache.sling.testing:type=HealthCheckMBeanTest";
-
- private HealthCheck testHealthCheck = new HealthCheck() {
-
- @Override
- public Result execute() {
- if(resultOk) {
- return new Result(Result.Status.OK, "Nothing to report, result ok");
- } else {
- return new Result(Result.Status.WARN, "Result is not ok!");
- }
- }
- };
-
- private void assertJmxValue(String mbeanName, String attributeName, String constraint, boolean expected) throws Exception {
- final MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();
- final ObjectName objectName = new ObjectName(mbeanName);
- if(jmxServer.queryNames(objectName, null).size() == 0) {
- fail("MBean not found: " + objectName);
- }
- final Object value = jmxServer.getAttribute(objectName, attributeName);
- final ResultLog resultLog = new ResultLog();
- new SimpleConstraintChecker().check(value, constraint, resultLog);
- assertEquals("Expecting result " + expected + "(" + resultLog + ")", expected, resultLog.getAggregateStatus().equals(Result.Status.OK));
-
- }
-
- @Test
- public void testBean() throws Exception {
- final ServiceReference ref = new ServiceReference() {
-
- @Override
- public boolean isAssignableTo(Bundle bundle, String className) {
- return false;
- }
-
- @Override
- public Bundle[] getUsingBundles() {
- return null;
- }
-
- @Override
- public String[] getPropertyKeys() {
- return null;
- }
-
- @Override
- public Object getProperty(String key) {
- return null;
- }
-
- @Override
- public Bundle getBundle() {
- return null;
- }
-
- @Override
- public int compareTo(Object reference) {
- return 0;
- }
- };
- final HealthCheckMBean mbean = new HealthCheckMBean(ref, new ExtendedHealthCheckExecutor() {
-
- @SuppressWarnings("deprecation")
- @Override
- public List<HealthCheckExecutionResult> execute(String... tags) {
- return null;
- }
-
- @Override
- public HealthCheckExecutionResult execute(ServiceReference ref) {
- // TODO Auto-generated method stub
- return new HealthCheckExecutionResult() {
-
- @Override
- public Result getHealthCheckResult() {
- // TODO Auto-generated method stub
- return testHealthCheck.execute();
- }
-
- @Override
- public HealthCheckMetadata getHealthCheckMetadata() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Date getFinishedAt() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public long getElapsedTimeInMs() {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public boolean hasTimedOut() {
- // TODO Auto-generated method stub
- return false;
- }
- };
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public List<HealthCheckExecutionResult> execute(HealthCheckExecutionOptions options, String... tags) {
- return null;
- }
-
- @Override
- public List<HealthCheckExecutionResult> execute(HealthCheckSelector selector) {
- return null;
- }
-
- @Override
- public List<HealthCheckExecutionResult> execute(HealthCheckSelector selector, HealthCheckExecutionOptions options) {
- return null;
- }
- });
- final ObjectName name = new ObjectName(OBJECT_NAME);
- jmxServer.registerMBean(mbean, name);
- try {
- resultOk = true;
- assertJmxValue(OBJECT_NAME, "ok", "true", true);
-
- Thread.sleep(1500);
- resultOk = false;
- assertJmxValue(OBJECT_NAME, "ok", "true", false);
-
- Thread.sleep(1500);
- assertJmxValue(OBJECT_NAME, "log", "contains message=Result is not ok!", true);
- } finally {
- jmxServer.unregisterMBean(name);
- }
- }
-
-}
\ No newline at end of file