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

Rename outcome to status #127

Merged
merged 6 commits into from
Jun 22, 2018
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
29 changes: 15 additions & 14 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,31 @@
// limitations under the License.
//

# MicroProfile Health
= MicroProfile Health

## Motivation
== Motivation

Health checks are used to probe the state of a computing node from another machine (i.e. kubernetes service controller) with the primary target being cloud infrastructure environments where automated processes maintain the state of computing nodes.

In this scenario, _health checks are used to determine if a computing node needs to be discarded (terminated, shutdown)_ and eventually replaced by another (healthy) instance.

It’s not intended (although could be used) as a monitoring solution for human operators.

## Proposed solution
== Proposed solution

The proposed solution breaks down into two parts:

- A health check protocol and wireformat
- A Java API to implement health check procedures

## Detailed design
== Detailed design

### Protocol
=== Protocol

This project defines a protocol (wireformat, semantics and possible forms of interactions) between system components that need to determine the “liveliness” of computing nodes in a bigger architecture.
A detailed description of the health check protocol can be found in the link:https:/eclipse/microprofile-health/tree/master/spec/src/main/asciidoc/protocol-wireformat.adoc[companion document].

### API Usage
=== API Usage

The main API to provide health check procedures on the application level is the `HealthCheck` interface:

Expand Down Expand Up @@ -71,7 +71,8 @@ public abstract class HealthCheckResponse {
[...]
}
```
### Constructing `HealthCheckResponse`s

=== Constructing `HealthCheckResponse`s

Application level code is expected to use one of static methods on `HealthCheckResponse` to retrieve a `HealthCheckResponseBuilder` used to construct a response, i.e. :

Expand All @@ -84,7 +85,7 @@ public class SuccessfulCheck implements HealthCheck {
}
```

### Integration with CDI
=== Integration with CDI

Within CDI contexts, beans that implement `HealthCheck` and annotated with `@Health` are discovered automatically and are invoked by the framework or runtime when the outermost protocol entry point (i.e. `http://HOST:PORT/health`) receives an inbound request.

Expand All @@ -99,34 +100,34 @@ public class CheckDiskSpace implements HealthCheck {
}
```

### On the wire
=== On the wire

It's the responsibility of the runtime to gather all `HealthCheckResponse` s for `HealthCheck` s known to the runtime. This means an inbound HTTP request will lead to a series of invocations
on health check procedures and the runtime will provide a composite response, with a single overall outcome, i.e.:
on health check procedures and the runtime will provide a composite response, with a single overall status, i.e.:

```
{
"outcome": "UP",
"status": "UP",
"checks": [
{
"name": "first-check",
"state": "UP",
"status": "UP",
"data": {
"key": "foo",
"foo": "bar"
}
},
{
"name": "second-check",
"state": "UP"
"status": "UP"
}
]
}
```

The link:https:/eclipse/microprofile-health/tree/master/spec/src/main/asciidoc/protocol-wireformat.adoc[companion document] contains further information on forms of interaction and the wireformat.

# SPI Usage
= SPI Usage

Implementors of the API are expected to supply implementations of `HealthCheckResponse` and `HealthCheckResponseBuilder` by providing a `HealthCheckResponseProvider` to their implementation. The `HealthCheckResponseProvider` is discovered using the default JDK service loader.

Expand Down
6 changes: 3 additions & 3 deletions sample-implementation/README.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# Health API Reference Implementation Notes
= Health API Reference Implementation Notes

The RI TCK coverage currently depends on custom Wildfly Swarm branch:

Expand All @@ -12,7 +12,7 @@ Since this is not published to maven central, test execution is disabled by defa
mvn -Dmaven.test.skip=false test
```

## Building the Sample Implementation
== Building the Sample Implementation


```
Expand All @@ -21,7 +21,7 @@ cd health-sample
mvn clean install
```

## Running the TCK against the sample implementation
== Running the TCK against the sample implementation

- Update the propoerty `wildfly-swarm.version` in `sample-implementation/pom.xml` to the version used in `health-sample/pom.xml` (i.e. 2017.9.0-SNAPSHOT)
- Run the tests with `mvn -Dmaven.test.skip=false test`
Expand Down
2 changes: 1 addition & 1 deletion spec/src/main/asciidoc/java-api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public abstract class HealthCheckResponse {
}
```

The status of all `HealthCheck` 's determines the overall outcome.
The status of all `HealthCheck` 's determines the overall status.

== Constructing `HealthCheckResponse`s

Expand Down
55 changes: 28 additions & 27 deletions spec/src/main/asciidoc/protocol-wireformat.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ Note that the force of these words is modified by the requirement level of the d
| Health Check Procedure
| The code executed to determine the liveliness of a Producer

| Producer Outcome
| The overall outcome, determined by considering all health check procedure results
| Producer status
| The overall status, determined by considering all health check procedure results

| Health check procedure result
| The result of single check
Expand All @@ -76,11 +76,11 @@ Note that the force of these words is modified by the requirement level of the d
1. Consumer invokes the health check of a Producer through any of the supported protocols
2. Producer enforces security constraints on the invocation (i.e authentication)
3. Producer executes a set of Health check procedures (could be a set with one element)
4. Producer determines the overall outcome (Producer outcome)
5. The outcome is mapped to outermost protocol (i.e. HTTP status codes)
4. Producer determines the overall status
5. The status is mapped to outermost protocol (i.e. HTTP status codes)
6. The payload is written to the response stream
7. The consumer reads the response
8. The consumer determines the overall outcome
8. The consumer determines the overall status

=== Protocol Specifics
This section describes the specifics of the HTTP protocol usage.
Expand All @@ -95,9 +95,10 @@ Health checks (innermost) can and should be mapped to the actual invocation prot

* Producers MAY support a variety of protocols but the information items in the response payload MUST remain the same.
* Producers SHOULD define a well known default context to perform checks
* Each response SHOULD integrate with the outermost protocol whenever it makes sense (i.e. using HTTP status codes to signal the overall state)
* Each response SHOULD integrate with the outermost protocol whenever it makes sense (i.e. using HTTP status codes to
signal the overall status)
* Inner protocol information items MUST NOT be replaced by outer protocol information items, rather kept redundantly.
* The inner protocol response MUST be self-contained, that is carrying all information needed to reason about the producer outcome
* The inner protocol response MUST be self-contained, that is carrying all information needed to reason about the producer status

=== Mandatory and optional protocol types

Expand All @@ -114,7 +115,7 @@ Each provider MUST provide the REST/HTTP interaction, but MAY provide other prot
* The primary information MUST be boolean, it needs to be consumed by other machines. Anything between available/unavailable doesn’t make sense or would increase the complexity on the side of the consumer processing that information.
* The response information MAY contain an additional information holder
* Consumers MAY process the additional information holder or simply decide to ignore it
* The response information MUST contain the boolean state of each check
* The response information MUST contain the boolean `status` of each check
* The response information MUST contain the name of each check

=== Wireformats
Expand All @@ -123,21 +124,21 @@ Each provider MUST provide the REST/HTTP interaction, but MAY provide other prot
* Producers MAY support an additional information holder with key/value pairs to provide further context (i.e. disk.free.space=120mb).
* The JSON response payload MUST be compatible with the one described in Appendix B
* The JSON response MUST contain the `name` entry specifying the name of the check, to support protocols that support external identifier (i.e. URI)
* The JSON response MUST contain the `state` entry specifying the state as String: “UP” or “DOWN”
* The JSON response MUST contain the `status` entry specifying the state as String: “UP” or “DOWN”
* The JSON MAY support an additional information holder to carry key value pairs that provide additional context

== Health Check Procedures
* A producer MUST support custom, application level health check procedures
* A producer SHOULD support reasonable out-of-the-box procedures
* A producer without health check procedures installed MUST returns positive overall outcome (i.e. HTTP 200)
* A producer without health check procedures installed MUST returns positive overall status (i.e. HTTP 200)

=== Policies to determine the overall outcome
=== Policies to determine the overall status

When multiple procedures are installed all procedures MUST be executed and the overall outcome needs to be determined.
When multiple procedures are installed all procedures MUST be executed and the overall status needs to be determined.

* Consumers MUST support a logical conjunction policy to determine the outcome
* Consumers MUST use the logical conjunction policy by default to determine the outcome
* Consumers MAY support custom policies to determine the outcome
* Consumers MUST support a logical conjunction policy to determine the status
* Consumers MUST use the logical conjunction policy by default to determine the status
* Consumers MAY support custom policies to determine the status

== Security

Expand All @@ -158,8 +159,8 @@ Aspects regarding the secure access of health check information.

=== Status Codes:

* 200 for a health check with a positive outcome
* 503 in case the overall outcome is negative
* 200 for a health check with a positive status (`UP`)
* 503 in case the overall status is negative (`DOWN`)
* 500 in case the producer wasn’t able to process the health check request (i.e. error in procedure)


Expand Down Expand Up @@ -203,7 +204,7 @@ The following table give valid health check responses:
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"outcome": {
"status": {
"type": "string"
},
"checks": {
Expand All @@ -214,7 +215,7 @@ The following table give valid health check responses:
"name": {
"type": "string"
},
"state": {
"status": {
"type": "string"
},
"data": {
Expand All @@ -231,13 +232,13 @@ The following table give valid health check responses:
},
"required": [
"name",
"state"
"status"
]
}
}
},
"required": [
"outcome",
"status",
"checks"
]
}
Expand All @@ -250,11 +251,11 @@ The following table give valid health check responses:
Status 200
```
{
"outcome": "UP",
"status": "UP",
"checks": [
{
"name": "myCheck",
"state": "UP",
"status": "UP",
"data": {
"key": "value",
"foo": "bar"
Expand All @@ -267,19 +268,19 @@ Status 200
Status 503
```
{
"outcome": "DOWN",
"status": "DOWN",
"checks": [
{
"name": "firstCheck",
"state": "DOWN",
"status": "DOWN",
"data": {
"key": "value",
"foo": "bar"
}
},
{
"name": "secondCheck",
"state": "UP"
"status": "UP"
}
]
}
Expand All @@ -291,7 +292,7 @@ Status `200` and the following payload:

```
{
"outcome": "UP",
"status": "UP",
"checks": []
}
```
1 change: 0 additions & 1 deletion tck/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
<relativePath>../</relativePath>
</parent>

<groupId>org.eclipse.microprofile.health</groupId>
<artifactId>microprofile-health-tck</artifactId>
<name>MicroProfile Health TCK</name>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@ public void testSuccessfulDelegateInvocation() throws Exception {
);

Assert.assertEquals(
asJsonObject(checks.get(0)).getString("state"),
asJsonObject(checks.get(0)).getString("status"),
"UP",
"Expected a successful check result"
);

// overall outcome
Assert.assertEquals(
json.getString("outcome"),
json.getString("status"),
"UP",
"Expected overall outcome to be successful"
"Expected overall status to be successful"
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void testSuccessResponsePayload() throws Exception {
);

Assert.assertEquals(
asJsonObject(check).getString("state"),
asJsonObject(check).getString("status"),
"UP",
"Expected a successful check result"
);
Expand All @@ -97,7 +97,7 @@ public void testSuccessResponsePayload() throws Exception {

// overall outcome
Assert.assertEquals(
json.getString("outcome"),
json.getString("status"),
"UP",
"Expected overall outcome to be successful"
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ public void testFailureResponsePayload() throws Exception {

// overall outcome
Assert.assertEquals(
json.getString("outcome"),
json.getString("status"),
"DOWN",
"Expected overall outcome to be unsuccessful"
"Expected overall status to be unsuccessful"
);
}

Expand All @@ -101,7 +101,7 @@ private void verifyFailurePayload(JsonValue check) {
);

Assert.assertEquals(
asJsonObject(check).getString("state"),
asJsonObject(check).getString("status"),
"DOWN",
"Expected a successful check result"
);
Expand All @@ -116,7 +116,7 @@ private void verifySuccessPayload(JsonValue check) {
);

Assert.assertEquals(
asJsonObject(check).getString("state"),
asJsonObject(check).getString("status"),
"UP",
"Expected a successful check result"
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ public void testSuccessResponsePayload() throws Exception {

JsonReader jsonReader = Json.createReader(new StringReader(response.getBody().get()));
JsonObject json = jsonReader.readObject();
System.out.println(json);

Assert.assertEquals(json.getString("outcome"), "UP","Expected outcome UP");
Assert.assertEquals(json.getString("status"), "UP","Expected status UP");
Assert.assertTrue(json.getJsonArray("checks").isEmpty(), "Expected empty checks array");

}
Expand Down
Loading