From 7e541b5068d6d0e7b39e308a35364fb94453f26e Mon Sep 17 00:00:00 2001 From: Antoine Sabot-Durand Date: Fri, 10 Jan 2020 10:20:20 +0100 Subject: [PATCH 1/4] microprofile-health-81 Ability to execute only some health checks Adding annotations Amend specification Add TCK tests Signed-off-by: Antoine Sabot-Durand --- .../microprofile/health/HealthGroup.java | 57 +++++++++++++ .../microprofile/health/HealthGroups.java | 50 +++++++++++ spec/src/main/asciidoc/java-api.adoc | 15 +++- .../main/asciidoc/protocol-wireformat.adoc | 11 +++ .../health/tck/MultipleCustomFailedTest.java | 85 +++++++++++++++++++ .../tck/SingleCustomSuccessfulTest.java | 70 +++++++++++++++ .../microprofile/health/tck/TCKBase.java | 4 + .../health/tck/deployment/FailedCustom.java | 41 +++++++++ .../tck/deployment/SuccessfulCustom.java | 39 +++++++++ 9 files changed, 371 insertions(+), 1 deletion(-) create mode 100644 api/src/main/java/org/eclipse/microprofile/health/HealthGroup.java create mode 100644 api/src/main/java/org/eclipse/microprofile/health/HealthGroups.java create mode 100644 tck/src/main/java/org/eclipse/microprofile/health/tck/MultipleCustomFailedTest.java create mode 100644 tck/src/main/java/org/eclipse/microprofile/health/tck/SingleCustomSuccessfulTest.java create mode 100644 tck/src/main/java/org/eclipse/microprofile/health/tck/deployment/FailedCustom.java create mode 100644 tck/src/main/java/org/eclipse/microprofile/health/tck/deployment/SuccessfulCustom.java diff --git a/api/src/main/java/org/eclipse/microprofile/health/HealthGroup.java b/api/src/main/java/org/eclipse/microprofile/health/HealthGroup.java new file mode 100644 index 0000000..e37fc88 --- /dev/null +++ b/api/src/main/java/org/eclipse/microprofile/health/HealthGroup.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2017-2020 Contributors to the Eclipse Foundation + * + * See the NOTICES file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +package org.eclipse.microprofile.health; + +import javax.inject.Qualifier; + +import java.lang.annotation.Documented; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + + +/** + * + * This qualifier is used to define a custom Health Check procedure by applying a group name to it + * + * @author Antoine Sabot-Durand + * @since 2.2 + */ +@Target({TYPE, METHOD, PARAMETER, FIELD}) +@Retention(RUNTIME) +@Documented +@Qualifier +@Repeatable(HealthGroups.class) +public @interface HealthGroup { + + /** + * @return name of the custom group + */ + String value(); +} + diff --git a/api/src/main/java/org/eclipse/microprofile/health/HealthGroups.java b/api/src/main/java/org/eclipse/microprofile/health/HealthGroups.java new file mode 100644 index 0000000..8acc3bf --- /dev/null +++ b/api/src/main/java/org/eclipse/microprofile/health/HealthGroups.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2017-2020 Contributors to the Eclipse Foundation + * + * See the NOTICES file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +package org.eclipse.microprofile.health; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.PARAMETER; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * + * This annotation allow to repeat {@link HealthGroup} qualifier + * + * @author Antoine Sabot-Durand + * @since 2.2 + */ +@Target({ PARAMETER, FIELD, METHOD, TYPE }) +@Documented +@Retention(RUNTIME) +public @interface HealthGroups { + /** + * @return list of {@link HealthGroup} + */ + HealthGroup[] value(); +} + diff --git a/spec/src/main/asciidoc/java-api.adoc b/spec/src/main/asciidoc/java-api.adoc index 664eab8..2b9d1b1 100644 --- a/spec/src/main/asciidoc/java-api.adoc +++ b/spec/src/main/asciidoc/java-api.adoc @@ -42,6 +42,7 @@ The nature of the procedure is defined by annotating the `HealthCheck` procedure * Readiness checks defined with `@Readiness` annotation * Liveness checks defined with `@Liveness` annotation +* Custom checks defined with `@HealthGroup` annotation * Backward compatible checks defined with `@Health` annotation @@ -60,6 +61,18 @@ This means that if this procedure fails the application can be discarded (termin The `@Liveness` annotation must be applied on a `HealthCheck` implementation to define a Liveness check procedure, otherwise, this annotation is ignored. +=== Custom check + +A new kind of Health Check can be defined with the `@HealthGroup` annotation. + +One or more Health Check procedure(s) can be annotated with `@HealthGroup` to apply a custom group name to the procedure. + +All the Health Check procedures belonging to the same group defined a new kind of Health Check. + +The `@HealthGroup` annotation must be applied on a `HealthCheck` implementation to define a custom check procedure with the given name, otherwise, this annotation is ignored. + +An `HealthCheck` implementation can have multiple `@HealthGroup` annotation to make it member of multiple custom Health Check's group. + === Backward compatible check @@ -149,7 +162,7 @@ public class CheckDiskspace implements HealthCheck { == Integration with CDI -Any enabled bean with a bean of type `org.eclipse.microprofile.health.HealthCheck` and `@Liveness`, `@Readiness` or `@Health` qualifier can be used as health check procedure. +Any enabled bean with a bean of type `org.eclipse.microprofile.health.HealthCheck` and `@Liveness`, `@Readiness`, `@HealthGroup` or `@Health` qualifier can be used as health check procedure. Contextual references of health check procedures are invoked by runtime when the outermost protocol entry point (i.e. `http://HOST:PORT/health`) receives an inbound request diff --git a/spec/src/main/asciidoc/protocol-wireformat.adoc b/spec/src/main/asciidoc/protocol-wireformat.adoc index 96c3a93..0d47603 100644 --- a/spec/src/main/asciidoc/protocol-wireformat.adoc +++ b/spec/src/main/asciidoc/protocol-wireformat.adoc @@ -184,6 +184,12 @@ Aspects regarding the secure access of health check information. | Readiness | See Appendix B +| /health/group/{name} +| GET +| 200, 500, 503 +| Custom with given name +| See Appendix B + | /health | GET | 200, 500, 503 @@ -208,6 +214,7 @@ The following table gives valid health check responses for all kinds of health c | Request | HTTP Status | JSON Payload | State | Comment | /health/live /health/ready + /health/group/{name} /health | 200 | Yes @@ -216,6 +223,7 @@ The following table gives valid health check responses for all kinds of health c | /health/live /health/ready + /health/group/{name} /health | 200 | Yes @@ -224,6 +232,7 @@ The following table gives valid health check responses for all kinds of health c | /health/live /health/ready + /health/group/{name} /health | 503 | Yes @@ -232,6 +241,7 @@ The following table gives valid health check responses for all kinds of health c | /health/live /health/ready + /health/group/{name} /health | 503 | Yes @@ -240,6 +250,7 @@ The following table gives valid health check responses for all kinds of health c | /health/live /health/ready + /health/group/{name} /health | 500 | No diff --git a/tck/src/main/java/org/eclipse/microprofile/health/tck/MultipleCustomFailedTest.java b/tck/src/main/java/org/eclipse/microprofile/health/tck/MultipleCustomFailedTest.java new file mode 100644 index 0000000..59ca853 --- /dev/null +++ b/tck/src/main/java/org/eclipse/microprofile/health/tck/MultipleCustomFailedTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017-2020 Contributors to the Eclipse Foundation + * + * See the NOTICES file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +package org.eclipse.microprofile.health.tck; + +import javax.json.JsonArray; +import javax.json.JsonObject; + + +import org.eclipse.microprofile.health.tck.deployment.FailedCustom; +import org.eclipse.microprofile.health.tck.deployment.SuccessfulCustom; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.shrinkwrap.api.Archive; +import org.testng.Assert; +import org.testng.annotations.Test; + +import static org.eclipse.microprofile.health.tck.DeploymentUtils.createWarFileWithClasses; + +/** + * @author Antoine Sabot-Durand + */ +public class MultipleCustomFailedTest extends TCKBase { + + @Deployment + public static Archive getDeployment() { + return createWarFileWithClasses(MultipleCustomFailedTest.class.getSimpleName(), + FailedCustom.class, SuccessfulCustom.class); + } + + /** + * Verifies the liveness health integration with CDI at the scope of a server runtime + */ + @Test + @RunAsClient + public void testFailureLivenessResponsePayload() { + Response response = getUrlCustomHealthContents("goup2"); + + // status code + Assert.assertEquals(response.getStatus(),503); + + JsonObject json = readJson(response); + + // response size + JsonArray checks = json.getJsonArray("checks"); + Assert.assertEquals(checks.size(), 2, "Expected two check responses"); + + for (JsonObject check : checks.getValuesAs(JsonObject.class)) { + String id = check.getString("name"); + switch (id) { + case "successful-check": + verifySuccessStatus(check); + break; + case "failed-check": + verifyFailureStatus(check); + break; + default: + Assert.fail("Unexpected response payload structure"); + } + } + + assertOverallFailure(json); + } + +} + diff --git a/tck/src/main/java/org/eclipse/microprofile/health/tck/SingleCustomSuccessfulTest.java b/tck/src/main/java/org/eclipse/microprofile/health/tck/SingleCustomSuccessfulTest.java new file mode 100644 index 0000000..a3ab08c --- /dev/null +++ b/tck/src/main/java/org/eclipse/microprofile/health/tck/SingleCustomSuccessfulTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2017-2020 Contributors to the Eclipse Foundation + * + * See the NOTICES file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +package org.eclipse.microprofile.health.tck; + +import javax.json.JsonArray; +import javax.json.JsonObject; + +import org.eclipse.microprofile.health.tck.deployment.SuccessfulCustom; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.shrinkwrap.api.Archive; +import org.testng.Assert; +import org.testng.annotations.Test; + +import static org.eclipse.microprofile.health.tck.DeploymentUtils.createWarFileWithClasses; + +/** + * @author Antoine Sabot-Durand + */ +public class SingleCustomSuccessfulTest extends TCKBase { + + @Deployment + public static Archive getDeployment() { + return createWarFileWithClasses(SingleCustomSuccessfulTest.class.getSimpleName(), SuccessfulCustom.class); + } + + /** + * Verifies the health integration with CDI at the scope of a server runtime + */ + @Test + @RunAsClient + public void testSuccessResponsePayload() { + Response response = getUrlCustomHealthContents("goup1"); + + // status code + Assert.assertEquals(response.getStatus(),200); + + JsonObject json = readJson(response); + + // response size + JsonArray checks = json.getJsonArray("checks"); + Assert.assertEquals(checks.size(),1,"Expected a single check response"); + + // single procedure response + assertSuccessfulCheck(checks.getJsonObject(0), "successful-check"); + + assertOverallSuccess(json); + } +} + diff --git a/tck/src/main/java/org/eclipse/microprofile/health/tck/TCKBase.java b/tck/src/main/java/org/eclipse/microprofile/health/tck/TCKBase.java index fca0c85..984d920 100644 --- a/tck/src/main/java/org/eclipse/microprofile/health/tck/TCKBase.java +++ b/tck/src/main/java/org/eclipse/microprofile/health/tck/TCKBase.java @@ -66,6 +66,10 @@ Response getUrlHealthContents() { return getUrlContents(this.uri + "/health", false); } + Response getUrlCustomHealthContents(String name) { + return getUrlContents(this.uri + "/health/group/" + name , false); + } + Response getUrlLiveContents() { return getUrlContents(this.uri + "/health/live", false); } diff --git a/tck/src/main/java/org/eclipse/microprofile/health/tck/deployment/FailedCustom.java b/tck/src/main/java/org/eclipse/microprofile/health/tck/deployment/FailedCustom.java new file mode 100644 index 0000000..e5a6aab --- /dev/null +++ b/tck/src/main/java/org/eclipse/microprofile/health/tck/deployment/FailedCustom.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2017-2019 Contributors to the Eclipse Foundation + * + * See the NOTICES file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +package org.eclipse.microprofile.health.tck.deployment; + +import javax.enterprise.context.ApplicationScoped; + +import org.eclipse.microprofile.health.HealthCheck; +import org.eclipse.microprofile.health.HealthCheckResponse; +import org.eclipse.microprofile.health.HealthGroup; + +/** + * @author Antone Sabot-Durand + * @since 2.0 + */ +@HealthGroup("group2") +@ApplicationScoped +public class FailedCustom implements HealthCheck { + @Override + public HealthCheckResponse call() { + return HealthCheckResponse.down("failed-check"); + } +} diff --git a/tck/src/main/java/org/eclipse/microprofile/health/tck/deployment/SuccessfulCustom.java b/tck/src/main/java/org/eclipse/microprofile/health/tck/deployment/SuccessfulCustom.java new file mode 100644 index 0000000..92e9e36 --- /dev/null +++ b/tck/src/main/java/org/eclipse/microprofile/health/tck/deployment/SuccessfulCustom.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017 Contributors to the Eclipse Foundation + * + * See the NOTICES file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +package org.eclipse.microprofile.health.tck.deployment; + +import javax.enterprise.context.ApplicationScoped; + +import org.eclipse.microprofile.health.HealthCheck; +import org.eclipse.microprofile.health.HealthCheckResponse; +import org.eclipse.microprofile.health.HealthGroup; + + +@HealthGroup("group1") +@HealthGroup("group2") +@ApplicationScoped +public class SuccessfulCustom implements HealthCheck { + @Override + public HealthCheckResponse call() { + return HealthCheckResponse.up("successful-check"); + } +} From 56bc68487c8393c376635508f2191084ec12a368 Mon Sep 17 00:00:00 2001 From: Antoine Sabot-Durand Date: Fri, 10 Jan 2020 13:51:28 +0100 Subject: [PATCH 2/4] Correct typos Signed-off-by: Antoine Sabot-Durand --- .../microprofile/health/tck/MultipleCustomFailedTest.java | 6 +++--- .../microprofile/health/tck/SingleCustomSuccessfulTest.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tck/src/main/java/org/eclipse/microprofile/health/tck/MultipleCustomFailedTest.java b/tck/src/main/java/org/eclipse/microprofile/health/tck/MultipleCustomFailedTest.java index 59ca853..86163fb 100644 --- a/tck/src/main/java/org/eclipse/microprofile/health/tck/MultipleCustomFailedTest.java +++ b/tck/src/main/java/org/eclipse/microprofile/health/tck/MultipleCustomFailedTest.java @@ -48,12 +48,12 @@ public static Archive getDeployment() { } /** - * Verifies the liveness health integration with CDI at the scope of a server runtime + * Verifies the custom health integration with CDI at the scope of a server runtime */ @Test @RunAsClient - public void testFailureLivenessResponsePayload() { - Response response = getUrlCustomHealthContents("goup2"); + public void testFailureResponsePayload() { + Response response = getUrlCustomHealthContents("group2"); // status code Assert.assertEquals(response.getStatus(),503); diff --git a/tck/src/main/java/org/eclipse/microprofile/health/tck/SingleCustomSuccessfulTest.java b/tck/src/main/java/org/eclipse/microprofile/health/tck/SingleCustomSuccessfulTest.java index a3ab08c..0cd9094 100644 --- a/tck/src/main/java/org/eclipse/microprofile/health/tck/SingleCustomSuccessfulTest.java +++ b/tck/src/main/java/org/eclipse/microprofile/health/tck/SingleCustomSuccessfulTest.java @@ -45,12 +45,12 @@ public static Archive getDeployment() { } /** - * Verifies the health integration with CDI at the scope of a server runtime + * Verifies the custom health integration with CDI at the scope of a server runtime */ @Test @RunAsClient public void testSuccessResponsePayload() { - Response response = getUrlCustomHealthContents("goup1"); + Response response = getUrlCustomHealthContents("group1"); // status code Assert.assertEquals(response.getStatus(),200); From 7d4936d66788606ca46079720e52f3930c16efe0 Mon Sep 17 00:00:00 2001 From: Antoine Sabot-Durand Date: Mon, 13 Jan 2020 11:44:53 +0100 Subject: [PATCH 3/4] Update spec/src/main/asciidoc/java-api.adoc typo Co-Authored-By: Martin Stefanko --- spec/src/main/asciidoc/java-api.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/src/main/asciidoc/java-api.adoc b/spec/src/main/asciidoc/java-api.adoc index 2b9d1b1..7f1bf59 100644 --- a/spec/src/main/asciidoc/java-api.adoc +++ b/spec/src/main/asciidoc/java-api.adoc @@ -67,7 +67,7 @@ A new kind of Health Check can be defined with the `@HealthGroup` annotation. One or more Health Check procedure(s) can be annotated with `@HealthGroup` to apply a custom group name to the procedure. -All the Health Check procedures belonging to the same group defined a new kind of Health Check. +All the Health Check procedures belonging to the same group define a new kind of Health Check. The `@HealthGroup` annotation must be applied on a `HealthCheck` implementation to define a custom check procedure with the given name, otherwise, this annotation is ignored. From 1500ed5b2553300fdb92ea3da0c884aa21935ef7 Mon Sep 17 00:00:00 2001 From: Antoine Sabot-Durand Date: Mon, 13 Jan 2020 11:45:11 +0100 Subject: [PATCH 4/4] Update spec/src/main/asciidoc/java-api.adoc typo Co-Authored-By: Martin Stefanko --- spec/src/main/asciidoc/java-api.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/src/main/asciidoc/java-api.adoc b/spec/src/main/asciidoc/java-api.adoc index 7f1bf59..d96fff1 100644 --- a/spec/src/main/asciidoc/java-api.adoc +++ b/spec/src/main/asciidoc/java-api.adoc @@ -71,7 +71,7 @@ All the Health Check procedures belonging to the same group define a new kind of The `@HealthGroup` annotation must be applied on a `HealthCheck` implementation to define a custom check procedure with the given name, otherwise, this annotation is ignored. -An `HealthCheck` implementation can have multiple `@HealthGroup` annotation to make it member of multiple custom Health Check's group. +A `HealthCheck` implementation can have multiple `@HealthGroup` annotations to make it a member of multiple custom Health Check's groups. === Backward compatible check