Repository: smallrye/smallrye-health
Pull request #1 (2018-06-20 12:26:10)

Initial implementation

jmesnil: This implementation is based on Servlet API that is not a specification provided for MicroProfile.

In my case, I was planning to use Undertow handler to provide the HTTP endpoint.
I wonder if this implementation should provide a SPI so that integrators can plug it into their web stack (whether it is based on Undertow, Servlet, or other lib/frameworks)

kenfinnigan: For the initial version I'm ok with it being tightly coupled, but agree we should provide something more clever going forward.

@jmesnil, can you create an issue in the repo describing your proposal?
sberyozkin: Yes, I thought that was something that would be easier to look at it once the external integrators will look at reusing it. I thought that 'servlet' may not be the common implementation idea, possibly JAX-RS instead.

@jmesnil, thanks, though I did not understand your comment about Servlet impl being not the Spec provided, the spec does not talk about the impl details ? 
jmesnil: @sberyozkin sorry, I was not very clear.

The microprofile umbrella specification does not include the servlet API. I don't think that this implementation of the health spec should mandate to use it.
In my case (WildFly) we are interested to implement the health check API in our low-level kernel code using Undertow handler. We will not have access to the servlet API there.

I'll open an issue with some proposal about this point.

sberyozkin: @jmesnil thanks, yes, this implementation is just once concrete instance of the Health API implementation based on, in this case, Servlet API. Right, so you'd like to reuse only the implementation part related to managing the HealthCheck calls, etc...Sounds good  
sberyozkin: Though I guess some default implementation should be there anyway. I guess it can be discussed later :-)

Patch:
diff --git a/docs/pom.xml b/docs/pom.xml
new file mode 100644
index 0000000..19c6c25
--- /dev/null
+++ b/docs/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~  Copyright 2017 Red Hat, Inc.
+ ~
+ ~  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>io.smallrye</groupId>
+    <artifactId>smallrye-health-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>smallrye-health-docs</artifactId>
+  <name>SmallRye: MicroProfile Health - Documentation</name>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.asciidoctor</groupId>
+          <artifactId>asciidoctor-maven-plugin</artifactId>
+          <configuration>
+            <resources>
+              <resource>
+                <directory>src/main/asciidoc/images</directory>
+                <targetPath>images</targetPath>
+              </resource>
+              <resource>
+                <directory>src/main/asciidoc/downloads</directory>
+                <targetPath>downloads</targetPath>
+              </resource>
+            </resources>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+  <profiles>
+    <profile>
+      <id>html</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.asciidoctor</groupId>
+            <artifactId>asciidoctor-maven-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>gerenate-docs-html</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>process-asciidoc</goal>
+                </goals>
+                <configuration>
+                  <backend>html5</backend>
+                  <attributes>
+                    <toc>left</toc>
+                    <linkcss>false</linkcss>
+                  </attributes>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+    </profile>
+  </profiles>
+</project>
diff --git a/docs/src/main/asciidoc/index.adoc b/docs/src/main/asciidoc/index.adoc
new file mode 100644
index 0000000..65a3305
--- /dev/null
+++ b/docs/src/main/asciidoc/index.adoc
@@ -0,0 +1,12 @@
+[[index]]
+= SmallRye Health Documentation
+:ext-relative: {outfilesuffix}
+:toc!:
+
+TODO
+
+[[more-resources]]
+== More Resources
+
+* https://github.com/smallrye/smallrye-health/[GitHub project repository]
+* https://github.com/eclipse/microprofile-health/[Eclipse MicroProfile Health]
diff --git a/implementation/pom.xml b/implementation/pom.xml
new file mode 100644
index 0000000..eb82071
--- /dev/null
+++ b/implementation/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~  Copyright 2017 Red Hat, Inc.
+ ~
+ ~  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>io.smallrye</groupId>
+    <artifactId>smallrye-health-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>smallrye-health</artifactId>
+
+  <name>SmallRye: MicroProfile Health Implementation</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.eclipse.microprofile.health</groupId>
+      <artifactId>microprofile-health-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.spec.javax.servlet</groupId>
+      <artifactId>jboss-servlet-api_3.1_spec</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.enterprise</groupId>
+      <artifactId>cdi-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish</groupId>
+      <artifactId>javax.json</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <scope>test</scope>
+        <version>4.11</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/implementation/src/main/java/io/smallrye/health/Response.java b/implementation/src/main/java/io/smallrye/health/Response.java
new file mode 100644
index 0000000..349fc11
--- /dev/null
+++ b/implementation/src/main/java/io/smallrye/health/Response.java
@@ -0,0 +1,36 @@
+package io.smallrye.health;
+
+import java.util.Map;
+import java.util.Optional;
+
+import org.eclipse.microprofile.health.HealthCheckResponse;
+
+class Response extends HealthCheckResponse {
+
+    Response(String name, State state, Map<String, Object> data) {
+        this.name = name;
+        this.state = state;
+        this.data = data;
+    }
+
+    @Override
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public State getState() {
+        return this.state;
+    }
+
+    @Override
+    public Optional<Map<String, Object>> getData() {
+        return Optional.ofNullable(this.data);
+    }
+
+    private final String name;
+
+    private final State state;
+
+    private final Map<String, Object> data;
+}
diff --git a/implementation/src/main/java/io/smallrye/health/ResponseBuilder.java b/implementation/src/main/java/io/smallrye/health/ResponseBuilder.java
new file mode 100644
index 0000000..287f8ac
--- /dev/null
+++ b/implementation/src/main/java/io/smallrye/health/ResponseBuilder.java
@@ -0,0 +1,66 @@
+package io.smallrye.health;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.microprofile.health.HealthCheckResponse;
+import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
+
+class ResponseBuilder extends HealthCheckResponseBuilder {
+
+    @Override
+    public HealthCheckResponseBuilder name(String name) {
+        this.name = name;
+        return this;
+    }
+
+    @Override
+    public HealthCheckResponseBuilder withData(String key, String value) {
+        this.data.put(key, value);
+        return this;
+    }
+
+    @Override
+    public HealthCheckResponseBuilder withData(String key, long value) {
+        this.data.put(key, value);
+        return this;
+    }
+
+    @Override
+    public HealthCheckResponseBuilder withData(String key, boolean value) {
+        this.data.put(key, value);
+        return this;
+    }
+
+    @Override
+    public HealthCheckResponseBuilder up() {
+        this.state = HealthCheckResponse.State.UP;
+        return this;
+    }
+
+    @Override
+    public HealthCheckResponseBuilder down() {
+        this.state = HealthCheckResponse.State.DOWN;
+        return this;
+    }
+
+    @Override
+    public HealthCheckResponseBuilder state(boolean up) {
+        if (up) {
+            return up();
+        }
+
+        return down();
+    }
+
+    @Override
+    public HealthCheckResponse build() {
+        return new Response(this.name, this.state, this.data.isEmpty() ? null : this.data);
+    }
+
+    private String name;
+
+    private HealthCheckResponse.State state = HealthCheckResponse.State.DOWN;
+
+    private Map<String, Object> data = new HashMap<>();
+}
diff --git a/implementation/src/main/java/io/smallrye/health/ResponseProvider.java b/implementation/src/main/java/io/smallrye/health/ResponseProvider.java
new file mode 100644
index 0000000..1a7317d
--- /dev/null
+++ b/implementation/src/main/java/io/smallrye/health/ResponseProvider.java
@@ -0,0 +1,12 @@
+package io.smallrye.health;
+
+import org.eclipse.microprofile.health.HealthCheckResponseBuilder;
+import org.eclipse.microprofile.health.spi.HealthCheckResponseProvider;
+
+public class ResponseProvider implements HealthCheckResponseProvider {
+
+    @Override
+    public HealthCheckResponseBuilder createResponseBuilder() {
+        return new ResponseBuilder();
+    }
+}
diff --git a/implementation/src/main/java/io/smallrye/health/SmallRyeHealthServlet.java b/implementation/src/main/java/io/smallrye/health/SmallRyeHealthServlet.java
new file mode 100644
index 0000000..0768ceb
--- /dev/null
+++ b/implementation/src/main/java/io/smallrye/health/SmallRyeHealthServlet.java
@@ -0,0 +1,107 @@
+package io.smallrye.health;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collections;
+import java.util.Map;
+
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.json.Json;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonWriter;
+import javax.json.JsonWriterFactory;
+import javax.json.stream.JsonGenerator;
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.microprofile.health.Health;
+import org.eclipse.microprofile.health.HealthCheck;
+import org.eclipse.microprofile.health.HealthCheckResponse;
+
+
+@SuppressWarnings("serial")
+@WebServlet(name = "SmallRyeHealthServlet", urlPatterns = "/*")
+public class SmallRyeHealthServlet extends HttpServlet {
+    private static final Map<String, ?> JSON_CONFIG = Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true);
+    
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+        OutputStream out = resp.getOutputStream();
+        JsonWriterFactory factory = Json.createWriterFactory(JSON_CONFIG);
+        JsonWriter writer = factory.createWriter(out);
+
+        JsonObject payload = jsonObject();
+        String outcome = payload.getString("outcome");
+        if ( outcome.equals(HealthCheckResponse.State.DOWN.toString())) {
+            resp.setStatus(503);
+        }
+
+        writer.writeObject(payload);
+        writer.close();
+    }
+
+    private JsonObject jsonObject() {
+        JsonArrayBuilder results = Json.createArrayBuilder();
+        HealthCheckResponse.State outcome = HealthCheckResponse.State.UP;
+
+        for (HealthCheck check : checks) {
+            if (check == null) {
+                continue;
+            }
+            JsonObject each = jsonObject(check);
+            results.add(each);
+            if (outcome == HealthCheckResponse.State.UP) {
+                String state = each.getString("state");
+                if (state.equals("DOWN")) {
+                    outcome = HealthCheckResponse.State.DOWN;
+                }
+            }
+        }
+
+        JsonObjectBuilder builder = Json.createObjectBuilder();
+
+
+        builder.add("outcome", outcome.toString());
+        builder.add("checks", results);
+
+        return builder.build();
+    }
+
+    private JsonObject jsonObject(HealthCheck check) {
+        return jsonObject(check.call());
+    }
+
+    private JsonObject jsonObject(HealthCheckResponse response) {
+        JsonObjectBuilder builder = Json.createObjectBuilder();
+        builder.add("name", response.getName());
+        builder.add("state", response.getState().toString());
+        response.getData().ifPresent(d -> {
+            JsonObjectBuilder data = Json.createObjectBuilder();
+            for (Map.Entry<String, Object> entry : d.entrySet()) {
+                Object value = entry.getValue();
+                if (value instanceof String) {
+                    data.add(entry.getKey(), (String) value);
+                } else if (value instanceof Long) {
+                    data.add(entry.getKey(), (Long) value);
+                } else if (value instanceof Boolean) {
+                    data.add(entry.getKey(), (Boolean) value);
+                }
+            }
+            builder.add("data", data.build());
+        });
+
+        return builder.build();
+    }
+
+    @Inject
+    @Health
+    private Instance<HealthCheck> checks;
+}
+
+
diff --git a/implementation/src/main/resources/META-INF/beans.xml b/implementation/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..57b5190
--- /dev/null
+++ b/implementation/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,5 @@
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="annotated">
+</beans>
\ No newline at end of file
diff --git a/implementation/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider b/implementation/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider
new file mode 100644
index 0000000..0d5a450
--- /dev/null
+++ b/implementation/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider
@@ -0,0 +1,1 @@
+io.smallrye.health.ResponseProvider
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..f651d8a
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~  Copyright 2017 Red Hat, Inc.
+ ~
+ ~  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>io.smallrye</groupId>
+    <artifactId>smallrye-parent</artifactId>
+    <version>1</version>
+  </parent>
+
+  <artifactId>smallrye-health-parent</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+
+  <packaging>pom</packaging>
+  <name>SmallRye: MicroProfile Health Parent</name>
+
+  <properties>
+    <version.asciidoctor.plugin>1.5.6</version.asciidoctor.plugin>
+    <version.eclipse.microprofile.health>1.0</version.eclipse.microprofile.health>
+    <version.javax.javaee-api>7.0</version.javax.javaee-api>
+    <version.javax.enterprise.cdi-api>2.0</version.javax.enterprise.cdi-api>
+    <version.junit>4.11</version.junit>
+    <version.org.jboss.arquillian>1.4.0.Final</version.org.jboss.arquillian>
+    <version.org.jboss.logging>2.0.1.Final</version.org.jboss.logging>
+    <version.maven-compiler-plugin>3.7.0</version.maven-compiler-plugin>
+    <version.weld>2.4.7.Final</version.weld>
+    <version.arquillian.wildfly>2.1.0.Final</version.arquillian.wildfly>
+    <version.wildfly>13.0.0.Final</version.wildfly>
+    <version.jboss.servlet>1.0.0.Final</version.jboss.servlet> 
+    <version.javax-json>1.1.2</version.javax-json>
+  </properties>
+
+  <scm>
+    <connection>scm:git:git@github.com:smallrye/smallrye-health.git</connection>
+    <developerConnection>scm:git:git@github.com:smallrye/smallrye-health.git</developerConnection>
+    <url>https://github.com/smallrye/smallrye-health/</url>
+    <tag>HEAD</tag>
+  </scm>
+
+  <modules>
+    <module>docs</module>
+    <module>implementation</module>
+    <module>tck</module>
+  </modules>
+
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.eclipse.microprofile.health</groupId>
+        <artifactId>microprofile-health-api</artifactId>
+        <version>${version.eclipse.microprofile.health}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.annotation.versioning</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.eclipse.microprofile.health</groupId>
+        <artifactId>microprofile-health-tck</artifactId>
+        <version>${version.eclipse.microprofile.health}</version>
+      </dependency>
+      
+      <dependency>
+         <groupId>org.glassfish</groupId>
+         <artifactId>javax.json</artifactId>
+         <version>${version.javax-json}</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.jboss.spec.javax.servlet</groupId>
+         <artifactId>jboss-servlet-api_3.1_spec</artifactId>
+         <version>${version.jboss.servlet}</version>
+      </dependency>
+
+      <!-- Other dependencies -->
+      <dependency>
+        <groupId>javax.enterprise</groupId>
+        <artifactId>cdi-api</artifactId>
+        <version>${version.javax.enterprise.cdi-api}</version>
+      </dependency>
+      
+      <dependency>
+         <groupId>org.jboss.arquillian</groupId>
+         <artifactId>arquillian-bom</artifactId>
+         <version>${version.org.jboss.arquillian}</version>
+         <scope>import</scope>
+         <type>pom</type>
+      </dependency>
+
+      <dependency>
+        <groupId>org.wildfly.arquillian</groupId>
+        <artifactId>wildfly-arquillian-container-managed</artifactId>
+        <version>${version.arquillian.wildfly}</version>
+        <scope>test</scope>
+      </dependency>
+
+      <dependency>
+        <groupId>org.jboss.weld.servlet</groupId>
+        <artifactId>weld-servlet-core</artifactId>
+        <version>${version.weld}</version>
+        <scope>test</scope>
+      </dependency>
+      
+      <dependency>
+        <groupId>org.jboss.spec.javax.servlet</groupId>
+        <artifactId>jboss-servlet-api_3.1_spec</artifactId>
+        <version>${version.jboss.servlet}</version>
+      </dependency>
+
+      <!-- Dependencies provided by the project -->
+      <dependency>
+        <groupId>io.smallrye</groupId>
+        <artifactId>smallrye-health</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.asciidoctor</groupId>
+          <artifactId>asciidoctor-maven-plugin</artifactId>
+          <version>${version.asciidoctor.plugin}</version>
+          <configuration>
+            <sourceHighlighter>coderay</sourceHighlighter>
+            <attributes>
+              <icons>font</icons>
+              <pagenums />
+              <version>${project.version}</version>
+              <idprefix />
+              <idseparator>-</idseparator>
+              <allow-uri-read>true</allow-uri-read>
+              <revnumber>${project.version}</revnumber>
+              <revdate>${maven.build.timestamp}</revdate>
+              <organization>${project.organization.name}</organization>
+            </attributes>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>${version.maven-compiler-plugin}</version>
+          <configuration>
+            <source>1.8</source>
+            <target>1.8</target>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/tck/pom.xml b/tck/pom.xml
new file mode 100644
index 0000000..cee6347
--- /dev/null
+++ b/tck/pom.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~  Copyright 2017 Red Hat, Inc.
+ ~
+ ~  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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>io.smallrye</groupId>
+    <artifactId>smallrye-health-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>smallrye-health-tck</artifactId>
+
+  <name>SmallRye: MicroProfile Health TCK</name>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <dependenciesToScan>
+            <dependency>org.eclipse.microprofile.health:microprofile-health-tck</dependency>
+          </dependenciesToScan>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.jboss.spec.javax.servlet</groupId>
+      <artifactId>jboss-servlet-api_3.1_spec</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.weld.servlet</groupId>
+      <artifactId>weld-servlet-core</artifactId>
+      <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.arquillian.container</groupId>
+      <artifactId>arquillian-container-spi</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.arquillian.container</groupId>
+      <artifactId>arquillian-container-test-spi</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jboss.shrinkwrap.resolver</groupId>
+      <artifactId>shrinkwrap-resolver-depchain</artifactId>
+      <type>pom</type>
+    </dependency>
+    <dependency>
+      <groupId>io.smallrye</groupId>
+      <artifactId>smallrye-health</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.glassfish</groupId>
+      <artifactId>javax.json</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.microprofile.health</groupId>
+      <artifactId>microprofile-health-tck</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+         <groupId>org.jboss.arquillian.testng</groupId>
+         <artifactId>arquillian-testng-container</artifactId>
+         <version>${version.org.jboss.arquillian}</version>
+         <scope>test</scope>
+    </dependency>
+ 
+  </dependencies>
+  <profiles>
+    <profile>
+      <id>wildfly-servlet</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+      <dependencies>
+        <dependency>
+          <groupId>org.wildfly.arquillian</groupId>
+          <artifactId>wildfly-arquillian-container-managed</artifactId>
+          <scope>test</scope>
+        </dependency>
+      </dependencies>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <environmentVariables>
+                <JBOSS_HOME>${project.build.directory}/wildfly-servlet-${version.wildfly}</JBOSS_HOME>
+              </environmentVariables>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-dependency-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>unpack</id>
+                <phase>process-test-classes</phase>
+                <goals>
+                  <goal>unpack</goal>
+                </goals>
+                <configuration>
+                  <artifactItems>
+                    <artifactItem>
+                      <groupId>org.wildfly</groupId>
+                      <artifactId>wildfly-servlet-dist</artifactId>
+                      <version>${version.wildfly}</version>
+                      <type>zip</type>
+                      <overWrite>false</overWrite>
+                      <outputDirectory>${project.build.directory}</outputDirectory>
+                    </artifactItem>
+                  </artifactItems>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>


Test patch:
diff --git a/implementation/src/test/java/io/smallrye/health/HealthCheckResponseProviderTest.java b/implementation/src/test/java/io/smallrye/health/HealthCheckResponseProviderTest.java
new file mode 100644
index 0000000..bf35a81
--- /dev/null
+++ b/implementation/src/test/java/io/smallrye/health/HealthCheckResponseProviderTest.java
@@ -0,0 +1,29 @@
+package io.smallrye.health;
+
+import java.util.Map;
+
+import org.eclipse.microprofile.health.HealthCheckResponse;
+import org.eclipse.microprofile.health.HealthCheckResponse.State;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class HealthCheckResponseProviderTest {
+
+    @Test
+    public void testProvider() {
+
+        HealthCheckResponse healthStatus = HealthCheckResponse.named("test")
+                .up()
+                .withData("a", "b")
+                .withData("c", "d")
+                .build();
+
+        Assert.assertEquals("test", healthStatus.getName());
+        Assert.assertSame(State.UP, healthStatus.getState());
+        Map<String, Object> data = healthStatus.getData().get();
+        Assert.assertEquals(2, data.size());
+        Assert.assertEquals("Expected a", "b", data.get("a"));
+        Assert.assertEquals("Expected c", "d", data.get("c"));
+    }
+
+}
diff --git a/tck/src/test/java/io/smallrye/health/SmallRyeBeanArchiveHandler.java b/tck/src/test/java/io/smallrye/health/SmallRyeBeanArchiveHandler.java
new file mode 100644
index 0000000..1ac0130
--- /dev/null
+++ b/tck/src/test/java/io/smallrye/health/SmallRyeBeanArchiveHandler.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2018 Red Hat, Inc, and individual contributors.
+ *
+ * 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.
+ */
+package io.smallrye.health;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import javax.annotation.Priority;
+
+import org.jboss.weld.environment.deployment.discovery.BeanArchiveBuilder;
+import org.jboss.weld.environment.deployment.discovery.BeanArchiveHandler;
+import org.jboss.weld.environment.util.Files;
+
+/**
+ * Special handler for WildFly VFS urls.
+ *
+ * @author Martin Kouba
+ */
+@Priority(1)
+public class SmallRyeBeanArchiveHandler implements BeanArchiveHandler {
+
+    @Override
+    public BeanArchiveBuilder handle(String beanArchiveReference) {
+
+        // An external form of a wildfly beans.xml URL will be something like:
+        // vfs:/content/_DEFAULT___DEFAULT__1f4a3572-fc97-41f5-8fed-0e7e7f7895df.war/WEB-INF/lib/4e0a1b50-4a74-429d-b519-9eedcac11046.jar/META-INF/beans.xml
+        beanArchiveReference = beanArchiveReference.substring(0, beanArchiveReference.lastIndexOf("/META-INF/beans.xml"));
+
+        if (beanArchiveReference.endsWith(".war")) {
+            // We only use this handler for libraries - WEB-INF classes are handled by ServletContextBeanArchiveHandler
+            return null;
+        }
+
+        try {
+            URL url = new URL(beanArchiveReference);
+            try (ZipInputStream in = openStream(url)) {
+                BeanArchiveBuilder builder = new BeanArchiveBuilder();
+                handleLibrary(url, in, builder);
+                return builder;
+            }
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    ZipInputStream openStream(URL url) throws IOException {
+        InputStream in = url.openStream();
+        return (in instanceof ZipInputStream) ? (ZipInputStream) in : new ZipInputStream(in);
+    }
+
+    private void handleLibrary(URL url, ZipInputStream zip, BeanArchiveBuilder builder) throws IOException {
+        ZipEntry entry = null;
+        while ((entry = zip.getNextEntry()) != null) {
+            if (Files.isClass(entry.getName())) {
+                builder.addClass(Files.filenameToClassname(entry.getName()));
+            }
+        }
+    }
+}
diff --git a/tck/src/test/java/io/smallrye/health/SmallRyeHealthArchiveProcessor.java b/tck/src/test/java/io/smallrye/health/SmallRyeHealthArchiveProcessor.java
new file mode 100644
index 0000000..73daa5a
--- /dev/null
+++ b/tck/src/test/java/io/smallrye/health/SmallRyeHealthArchiveProcessor.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2018 Red Hat, Inc, and individual contributors.
+ *
+ * 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.
+ */
+package io.smallrye.health;
+
+import java.io.File;
+
+import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
+import org.jboss.arquillian.test.spi.TestClass;
+import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.jboss.weld.environment.deployment.discovery.BeanArchiveHandler;
+
+public class SmallRyeHealthArchiveProcessor implements ApplicationArchiveProcessor {
+
+    @Override
+    public void process(Archive<?> applicationArchive, TestClass testClass) {
+        if (applicationArchive instanceof WebArchive) {
+            WebArchive testDeployment = (WebArchive) applicationArchive;
+            // Register SmallRyeBeanArchiveHandler using the ServiceLoader mechanism
+            testDeployment.addClass(SmallRyeBeanArchiveHandler.class);
+            testDeployment.addAsServiceProvider(BeanArchiveHandler.class, SmallRyeBeanArchiveHandler.class);
+            
+            String[] deps = { "io.smallrye:smallrye-health", "org.eclipse.microprofile.health:microprofile-health-tck", "org.jboss.weld.servlet:weld-servlet-core" };
+    
+            File[] dependencies = Maven.resolver().loadPomFromFile(new File("pom.xml")).resolve(deps).withTransitivity().asFile();
+
+            testDeployment.addAsLibraries(dependencies);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/tck/src/test/java/io/smallrye/health/SmallRyeHealthExtension.java b/tck/src/test/java/io/smallrye/health/SmallRyeHealthExtension.java
new file mode 100644
index 0000000..f471314
--- /dev/null
+++ b/tck/src/test/java/io/smallrye/health/SmallRyeHealthExtension.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2017 Red Hat, Inc.
+ *
+ * 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.
+ */
+
+package io.smallrye.health;
+
+
+import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor;
+import org.jboss.arquillian.core.spi.LoadableExtension;
+
+public class SmallRyeHealthExtension implements LoadableExtension {
+    @Override
+    public void register(ExtensionBuilder builder) {
+        builder.service(ApplicationArchiveProcessor.class, SmallRyeHealthArchiveProcessor.class);
+    }
+    
+}
diff --git a/tck/src/test/resources/META-INF/beans.xml b/tck/src/test/resources/META-INF/beans.xml
new file mode 100644
index 0000000..ad2a3b6
--- /dev/null
+++ b/tck/src/test/resources/META-INF/beans.xml
@@ -0,0 +1,5 @@
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
+       bean-discovery-mode="all">
+</beans>
diff --git a/tck/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/tck/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
new file mode 100644
index 0000000..325f7a9
--- /dev/null
+++ b/tck/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
@@ -0,0 +1,1 @@
+io.smallrye.health.SmallRyeHealthExtension