You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2014/06/05 09:04:54 UTC
svn commit: r1600564 - in
/sling/trunk/bundles/extensions/healthcheck/core/src:
main/java/org/apache/sling/hc/api/ main/java/org/apache/sling/hc/core/impl/
main/java/org/apache/sling/hc/core/impl/executor/
test/java/org/apache/sling/hc/core/impl/
Author: bdelacretaz
Date: Thu Jun 5 07:04:54 2014
New Revision: 1600564
URL: http://svn.apache.org/r1600564
Log:
SLING-3500 - use HealthCheckExecutor in CompositeHealthCheck - contributed by Georg Henzler, thanks!
Added:
sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeResult.java
sling/trunk/bundles/extensions/healthcheck/core/src/test/java/org/apache/sling/hc/core/impl/CompositeHealthCheckTest.java
Modified:
sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/api/Result.java
sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheck.java
sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/ExecutionResult.java
sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImpl.java
Modified: sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/api/Result.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/api/Result.java?rev=1600564&r1=1600563&r2=1600564&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/api/Result.java (original)
+++ sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/api/Result.java Thu Jun 5 07:04:54 2014
@@ -22,7 +22,7 @@ import java.util.Iterator;
/** The result of executing a {@link HealthCheck} */
public class Result implements Iterable <ResultLog.Entry> {
- private final ResultLog resultLog;
+ protected final ResultLog resultLog;
public enum Status {
DEBUG, // used by ResultLog for debug messages, not an actual output status
Modified: sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheck.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheck.java?rev=1600564&r1=1600563&r2=1600564&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheck.java (original)
+++ sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeHealthCheck.java Thu Jun 5 07:04:54 2014
@@ -18,7 +18,9 @@
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.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -27,15 +29,22 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyUnbounded;
+import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
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.ResultLog;
+import org.apache.sling.hc.api.execution.HealthCheckExecutionResult;
+import org.apache.sling.hc.api.execution.HealthCheckExecutor;
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.ServiceReference;
+import org.osgi.service.component.ComponentConstants;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -66,73 +75,140 @@ import org.slf4j.LoggerFactory;
public class CompositeHealthCheck implements HealthCheck {
private final Logger log = LoggerFactory.getLogger(getClass());
- private BundleContext bundleContext;
@Property(unbounded=PropertyUnbounded.ARRAY,
label="Filter Tags",
description="Tags used to select which health checks the composite health check executes.")
- private static final String PROP_FILTER_TAGS = "filter.tags";
+ static final String PROP_FILTER_TAGS = "filter.tags";
private String [] filterTags;
- private final ThreadLocal<Boolean> recursionLock = new ThreadLocal<Boolean>();
+ @Reference
+ private HealthCheckExecutor healthCheckExecutor;
+
+ private BundleContext bundleContext;
+ private ServiceReference referenceToThis;
+ private HealthCheckFilter healthCheckFilter;
+
@Activate
protected void activate(final ComponentContext ctx) {
bundleContext = ctx.getBundleContext();
+ healthCheckFilter = new HealthCheckFilter(bundleContext);
+ referenceToThis = getReferenceByPid(PropertiesUtil.toString(ctx.getProperties().get(Constants.SERVICE_PID), "-1"));
+
filterTags = PropertiesUtil.toStringArray(ctx.getProperties().get(PROP_FILTER_TAGS), new String[] {});
log.debug("Activated, will select HealthCheck having tags {}", Arrays.asList(filterTags));
}
@Deactivate
protected void deactivate() {
- this.bundleContext = null;
+ bundleContext = null;
+ healthCheckFilter = null;
+ referenceToThis = null;
}
@Override
public Result execute() {
- if ( recursionLock.get() != null ) {
- // recursion
- return new Result(Status.CRITICAL,
- "Recursive invocation of composite health checks with filter tags : " + Arrays.asList(filterTags));
- }
- final FormattingResultLog resultLog = new FormattingResultLog();
- final HealthCheckFilter filter = new HealthCheckFilter(bundleContext);
- this.recursionLock.set(Boolean.TRUE);
- try {
- final List<HealthCheck> checks = filter.getTaggedHealthChecks(filterTags);
- if (checks.size() == 0) {
- resultLog.warn("HealthCheckFilter returns no HealthCheck for tags {}", Arrays.asList(filterTags));
- return new Result(resultLog);
- }
- int executed = 0;
- resultLog.debug("Executing {} HealthCheck selected by the {} tags", checks.size(), Arrays.asList(filterTags));
- int failures = 0;
- for (final HealthCheck hc : checks) {
- if(hc == this) {
- resultLog.info("Cowardly forfeiting execution of this HealthCheck in an infinite loop, ignoring it");
- continue;
- }
- resultLog.debug("Executing {}", hc);
- executed++;
- final Result sub = hc.execute();
- if(!sub.isOk()) {
- failures++;
- }
- for(final ResultLog.Entry e : sub) {
- resultLog.add(e);
+ Result result = null;
+ if ((result = checkForRecursion(referenceToThis, new HashSet<String>())) != null) {
+ // return recursion error
+ return result;
+ }
+
+ FormattingResultLog resultLog = new FormattingResultLog();
+ List<HealthCheckExecutionResult> executionResults = healthCheckExecutor.execute(filterTags);
+ 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_PID) + ") 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.getTaggedHealthCheckServiceReferences(tagsForIncludedChecksArr);
+ 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;
}
}
- if (failures == 0) {
- resultLog.debug("{} HealthCheck executed, all ok", executed);
- } else {
- resultLog.warn("{} HealthCheck executed, {} failures", executed, failures);
- }
- } finally {
- filter.dispose();
- this.recursionLock.remove();
}
- return new Result(resultLog);
+
+ // no recursion detected
+ return null;
+
+ }
+
+ private ServiceReference getReferenceByPid(String servicePid) {
+
+ if (servicePid == null) {
+ return null;
+ }
+
+ String filterString = "(" + Constants.SERVICE_PID + "=" + servicePid + ")";
+ ServiceReference[] refs = null;
+ try {
+ refs = bundleContext.getServiceReferences(HealthCheck.class.getName(), filterString);
+ } catch (InvalidSyntaxException e) {
+ log.error("Invalid filter " + filterString, e);
+ }
+ if (refs == null || refs.length == 0) {
+ return null;
+ } else if (refs.length == 1) {
+ return refs[0];
+ } else {
+ throw new IllegalStateException("OSGi Framework returned more than one service reference for unique service pid =" + servicePid);
+ }
+
}
+
+ void setHealthCheckFilter(HealthCheckFilter healthCheckFilter) {
+ this.healthCheckFilter = healthCheckFilter;
+ }
+
+ void setFilterTags(String[] filterTags) {
+ this.filterTags = filterTags;
+ }
+
+ void setHealthCheckExecutor(HealthCheckExecutor healthCheckExecutor) {
+ this.healthCheckExecutor = healthCheckExecutor;
+ }
+
+ void setReferenceToThis(ServiceReference referenceToThis) {
+ this.referenceToThis = referenceToThis;
+ }
+
}
Added: sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeResult.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeResult.java?rev=1600564&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeResult.java (added)
+++ sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/CompositeResult.java Thu Jun 5 07:04:54 2014
@@ -0,0 +1,29 @@
+package org.apache.sling.hc.core.impl;
+
+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.core.impl.executor.HealthCheckExecutorImpl;
+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 "
+ + HealthCheckExecutorImpl.msHumanReadable(executionResult.getElapsedTimeInMs())
+ + (executionResult.hasTimedOut() ? " (timed out)" : "")));
+ }
+ }
+
+}
Modified: sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/ExecutionResult.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/ExecutionResult.java?rev=1600564&r1=1600563&r2=1600564&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/ExecutionResult.java (original)
+++ sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/ExecutionResult.java Thu Jun 5 07:04:54 2014
@@ -43,7 +43,7 @@ public class ExecutionResult implements
/**
* Full constructor
*/
- ExecutionResult(final HealthCheckMetadata metadata,
+ public ExecutionResult(final HealthCheckMetadata metadata,
final Result simpleResult,
final long elapsedTimeInMs,
final boolean timedout) {
@@ -57,7 +57,7 @@ public class ExecutionResult implements
/**
* Shortcut constructor for a result
*/
- ExecutionResult(final HealthCheckMetadata metadata,
+ public ExecutionResult(final HealthCheckMetadata metadata,
final Result simpleResult,
final long elapsedTimeInMs) {
this(metadata, simpleResult, elapsedTimeInMs, false);
@@ -66,7 +66,7 @@ public class ExecutionResult implements
/**
* Shortcut constructor to create error/timed out result.
*/
- ExecutionResult(final HealthCheckMetadata metadata,
+ public ExecutionResult(final HealthCheckMetadata metadata,
final Result.Status status,
final String errorMessage,
final long elapsedTime, boolean timedOut) {
Modified: sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImpl.java?rev=1600564&r1=1600563&r2=1600564&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImpl.java (original)
+++ sling/trunk/bundles/extensions/healthcheck/core/src/main/java/org/apache/sling/hc/core/impl/executor/HealthCheckExecutorImpl.java Thu Jun 5 07:04:54 2014
@@ -408,7 +408,7 @@ public class HealthCheckExecutorImpl imp
return result;
}
- static String msHumanReadable(final long millis) {
+ public static String msHumanReadable(final long millis) {
double number = millis;
final String[] units = new String[] { "ms", "sec", "min", "h", "days" };
Added: sling/trunk/bundles/extensions/healthcheck/core/src/test/java/org/apache/sling/hc/core/impl/CompositeHealthCheckTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/healthcheck/core/src/test/java/org/apache/sling/hc/core/impl/CompositeHealthCheckTest.java?rev=1600564&view=auto
==============================================================================
--- sling/trunk/bundles/extensions/healthcheck/core/src/test/java/org/apache/sling/hc/core/impl/CompositeHealthCheckTest.java (added)
+++ sling/trunk/bundles/extensions/healthcheck/core/src/test/java/org/apache/sling/hc/core/impl/CompositeHealthCheckTest.java Thu Jun 5 07:04:54 2014
@@ -0,0 +1,226 @@
+/*
+ * 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.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.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.HealthCheckExecutionResult;
+import org.apache.sling.hc.api.execution.HealthCheckExecutor;
+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.junit.Before;
+import org.junit.Test;
+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;
+
+public class CompositeHealthCheckTest {
+
+ @Spy
+ private CompositeHealthCheck compositeHealthCheck = new CompositeHealthCheck();
+
+ @Mock
+ private HealthCheckExecutor healthCheckExecutor;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ compositeHealthCheck.setHealthCheckExecutor(healthCheckExecutor);
+ compositeHealthCheck.setFilterTags(new String[] {});
+
+ }
+
+ @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(testTags)).thenReturn(executionResults);
+
+ Result result = compositeHealthCheck.execute();
+
+ verify(healthCheckExecutor, times(1)).execute(testTags);
+
+ assertEquals(Result.Status.CRITICAL, result.getStatus());
+
+ }
+
+ 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 testRecursionCheckSimle() {
+
+ // 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
+ compositeHealthCheck.setReferenceToThis(hcRef);
+ compositeHealthCheck.setFilterTags(filterTags);
+
+ compositeHealthCheck.setHealthCheckFilter(new HealthCheckFilter(null) { // not using @Spy because varargs matcher does not work with spies
+
+ @Override
+ public ServiceReference[] getTaggedHealthCheckServiceReferences(String... 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(Matchers.any(String[].class));
+ assertEquals(Result.Status.HEALTH_CHECK_ERROR, result.getStatus());
+ }
+
+ @Test
+ public void testRecursionCheckCyclic() {
+
+ // 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
+ compositeHealthCheck.setReferenceToThis(hcRef1);
+ compositeHealthCheck.setFilterTags(filterTags);
+
+ compositeHealthCheck.setHealthCheckFilter(new HealthCheckFilter(null) {
+
+ @Override
+ public ServiceReference[] getTaggedHealthCheckServiceReferences(String... tags) { // not using @Spy because varargs matcher does not work with spies
+ 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(Matchers.any(String[].class));
+ assertEquals(Result.Status.HEALTH_CHECK_ERROR, result.getStatus());
+ }
+
+
+ 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();
+ }
+
+ }
+}