Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

microprofile-health-81 Ability to execute only some health checks #221

Merged
merged 4 commits into from
Jan 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions api/src/main/java/org/eclipse/microprofile/health/HealthGroup.java
Original file line number Diff line number Diff line change
@@ -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();
}

Original file line number Diff line number Diff line change
@@ -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();
}

15 changes: 14 additions & 1 deletion spec/src/main/asciidoc/java-api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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 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.

A `HealthCheck` implementation can have multiple `@HealthGroup` annotations to make it a member of multiple custom Health Check's groups.


=== Backward compatible check

Expand Down Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions spec/src/main/asciidoc/protocol-wireformat.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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 custom health integration with CDI at the scope of a server runtime
*/
@Test
@RunAsClient
public void testFailureResponsePayload() {
Response response = getUrlCustomHealthContents("group2");

// 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);
}

}

Original file line number Diff line number Diff line change
@@ -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 custom health integration with CDI at the scope of a server runtime
*/
@Test
@RunAsClient
public void testSuccessResponsePayload() {
Response response = getUrlCustomHealthContents("group1");

// 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);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Loading