From dd7c5e45e31c3efb96c9de694b61a156b8a1a714 Mon Sep 17 00:00:00 2001 From: Thiago Henrique Hupner Date: Sun, 13 Oct 2024 00:48:04 +0000 Subject: [PATCH 01/28] Initial implementation --- appserver/distributions/glassfish/pom.xml | 4 + .../META-INF/MANIFEST.MF | 28 +++++ appserver/featuresets/glassfish/pom.xml | 23 ++++ appserver/microprofile/health/pom.xml | 113 ++++++++++++++++++ .../HealthCheckResponseBuilderImpl.java | 60 ++++++++++ .../HealthCheckResponseProviderImpl.java | 11 ++ .../microprofile/health/HealthServlet.java | 52 ++++++++ .../health/HealthServletInitializer.java | 26 ++++ .../glassfish/microprofile/health/Output.java | 8 ++ ...akarta.servlet.ServletContainerInitializer | 1 + ...ile.health.spi.HealthCheckResponseProvider | 1 + appserver/microprofile/pom.xml | 1 + appserver/pom.xml | 19 +++ .../tests/tck/microprofile/health/pom.xml | 83 +++++++++++++ .../health/tck/ConfigArquillianExtension.java | 47 ++++++++ .../tck/client/BeansXmlTransformer.java | 110 +++++++++++++++++ .../ConfigDeploymentExceptionTransformer.java | 37 ++++++ .../health/tck/client/LibraryIncluder.java | 47 ++++++++ ...boss.arquillian.core.spi.LoadableExtension | 1 + .../health/src/main/resources/beans.xml | 4 + .../health/tck/ContainerSetup.java | 40 +++++++ .../tck/microprofile/health/tck-suite.xml | 34 ++++++ appserver/tests/tck/microprofile/pom.xml | 1 + 23 files changed, 751 insertions(+) create mode 100644 appserver/distributions/glassfish/src/main/patches/microprofile-health-api/META-INF/MANIFEST.MF create mode 100644 appserver/microprofile/health/pom.xml create mode 100644 appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseBuilderImpl.java create mode 100644 appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseProviderImpl.java create mode 100644 appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java create mode 100644 appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java create mode 100644 appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java create mode 100644 appserver/microprofile/health/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer create mode 100644 appserver/microprofile/health/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider create mode 100644 appserver/tests/tck/microprofile/health/pom.xml create mode 100644 appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java create mode 100644 appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java create mode 100644 appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/ConfigDeploymentExceptionTransformer.java create mode 100644 appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java create mode 100644 appserver/tests/tck/microprofile/health/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension create mode 100644 appserver/tests/tck/microprofile/health/src/main/resources/beans.xml create mode 100644 appserver/tests/tck/microprofile/health/src/test/java/org/glassfish/microprofile/health/tck/ContainerSetup.java create mode 100644 appserver/tests/tck/microprofile/health/tck-suite.xml diff --git a/appserver/distributions/glassfish/pom.xml b/appserver/distributions/glassfish/pom.xml index 786c54e4e5f..1e2e0404527 100644 --- a/appserver/distributions/glassfish/pom.xml +++ b/appserver/distributions/glassfish/pom.xml @@ -141,6 +141,10 @@ basedir="${patches}/microprofile-rest-client-api" includes="META-INF/MANIFEST.MF" destfile="${glassfish.modules}/microprofile-rest-client-api.jar" /> + + + + org.eclipse.microprofile.health + microprofile-health-api + + + * + * + + + + + org.glassfish.main.microprofile + microprofile-health + ${project.version} + + + * + * + + + + org.eclipse.microprofile.jwt diff --git a/appserver/microprofile/health/pom.xml b/appserver/microprofile/health/pom.xml new file mode 100644 index 00000000000..07bb3ed4ce2 --- /dev/null +++ b/appserver/microprofile/health/pom.xml @@ -0,0 +1,113 @@ + + + + + 4.0.0 + + + org.glassfish.main.microprofile + microprofile-parent + 7.0.18-SNAPSHOT + + + microprofile-health + glassfish-jar + + GlassFish MicroProfile Health + + + + + org.eclipse.microprofile.health + microprofile-health-api + + + + jakarta.enterprise + jakarta.enterprise.cdi-api + + + jakarta.json.bind + jakarta.json.bind-api + + + + + org.glassfish.main.common + glassfish-api + ${project.version} + + + org.glassfish.main.common + internal-api + ${project.version} + + + org.glassfish.main.web + weld-integration + ${project.version} + + + + + + + maven-compiler-plugin + + 17 + + + + org.apache.felix + maven-bundle-plugin + + + glassfish-jar + + + + + org.glassfish.microprofile.health; + + + org.eclipse.microprofile.health.spi; + org.eclipse.microprofile.health; + jakarta.enterprise.util; + jakarta.enterprise.inject; + jakarta.servlet.http; + jakarta.servlet; + jakarta.json.bind; + jakarta.inject; + + + + + + osgi-bundle + package + + bundle + + + + + + + + diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseBuilderImpl.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseBuilderImpl.java new file mode 100644 index 00000000000..b132e888f98 --- /dev/null +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseBuilderImpl.java @@ -0,0 +1,60 @@ +package org.glassfish.microprofile.health; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.eclipse.microprofile.health.HealthCheckResponse; +import org.eclipse.microprofile.health.HealthCheckResponseBuilder; + +public class HealthCheckResponseBuilderImpl extends HealthCheckResponseBuilder { + + private String name; + private HealthCheckResponse.Status status; + private Map data = new HashMap<>(); + + @Override + public HealthCheckResponseBuilder name(String s) { + name = s; + return this; + } + + @Override + public HealthCheckResponseBuilder withData(String s, String s1) { + data.put(s, s1); + return this; + } + + @Override + public HealthCheckResponseBuilder withData(String s, long l) { + data.put(s, l); + return this; + } + + @Override + public HealthCheckResponseBuilder withData(String s, boolean b) { + data.put(s, b); + return this; + } + + @Override + public HealthCheckResponseBuilder up() { + return status(true); + } + + @Override + public HealthCheckResponseBuilder down() { + return status(false); + } + + @Override + public HealthCheckResponseBuilder status(boolean b) { + status = b ? HealthCheckResponse.Status.UP : HealthCheckResponse.Status.DOWN; + return this; + } + + @Override + public HealthCheckResponse build() { + return new HealthCheckResponse(name, status, data.isEmpty() ? null : Optional.of(data)); + } +} diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseProviderImpl.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseProviderImpl.java new file mode 100644 index 00000000000..94b94dce6e3 --- /dev/null +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseProviderImpl.java @@ -0,0 +1,11 @@ +package org.glassfish.microprofile.health; + +import org.eclipse.microprofile.health.HealthCheckResponseBuilder; +import org.eclipse.microprofile.health.spi.HealthCheckResponseProvider; + +public class HealthCheckResponseProviderImpl implements HealthCheckResponseProvider { + @Override + public HealthCheckResponseBuilder createResponseBuilder() { + return new HealthCheckResponseBuilderImpl(); + } +} diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java new file mode 100644 index 00000000000..541acb1baa1 --- /dev/null +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java @@ -0,0 +1,52 @@ +package org.glassfish.microprofile.health; + +import jakarta.enterprise.inject.Instance; +import jakarta.enterprise.inject.spi.CDI; +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.util.List; + +import org.eclipse.microprofile.health.HealthCheck; +import org.eclipse.microprofile.health.HealthCheckResponse; +import org.eclipse.microprofile.health.Liveness; +import org.eclipse.microprofile.health.Readiness; + +public class HealthServlet extends HttpServlet { + + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + + Instance select = CDI.current().select(HealthCheck.class); + if (req.getRequestURI().endsWith("health/live")) { + select = select.select(Liveness.Literal.INSTANCE); + } else if (req.getRequestURI().endsWith("health/ready")) { + select = select.select(Readiness.Literal.INSTANCE); + } + + List healthCheckResults = select + .stream() + .map(HealthCheck::call) + .toList(); + + HealthCheckResponse.Status overallStatus = healthCheckResults.stream() + .map(HealthCheckResponse::getStatus) + .filter(HealthCheckResponse.Status.DOWN::equals) + .findFirst().orElse(HealthCheckResponse.Status.UP); + + Output output = new Output(overallStatus, healthCheckResults); + try (Jsonb jsonb = JsonbBuilder.create()) { + String json = jsonb.toJson(output); + resp.getWriter().println(json); + } catch (Exception e) { + throw new RuntimeException(e); + } + + } +} diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java new file mode 100644 index 00000000000..971d86793c6 --- /dev/null +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java @@ -0,0 +1,26 @@ +package org.glassfish.microprofile.health; + +import jakarta.servlet.ServletContainerInitializer; +import jakarta.servlet.ServletContext; +import jakarta.servlet.ServletException; + +import java.util.Set; + +public class HealthServletInitializer implements ServletContainerInitializer { + static { + System.err.println("Class loaded!"); + } + + @Override + public void onStartup(Set> set, ServletContext servletContext) throws ServletException { + System.err.println("onStartup: " + servletContext.getContextPath()); + // for now +// if (!servletContext.getContextPath().isEmpty()) { +// return; +// } + servletContext.addServlet("health", HealthServlet.class) + .addMapping("/health", "/health/live", "/health/ready"); +// servletContext.addServlet("health-liveness", HealthLivenessServlet.class).addMapping("/health/live"); +// servletContext.addServlet("health-readness", HealthReadinessServlet.class).addMapping("/health/ready"); + } +} diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java new file mode 100644 index 00000000000..b12f5a5ec48 --- /dev/null +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java @@ -0,0 +1,8 @@ +package org.glassfish.microprofile.health; + +import java.util.List; + +import org.eclipse.microprofile.health.HealthCheckResponse; + +record Output(HealthCheckResponse.Status getStatus, List getChecks) { +} diff --git a/appserver/microprofile/health/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer b/appserver/microprofile/health/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer new file mode 100644 index 00000000000..3ee851e806c --- /dev/null +++ b/appserver/microprofile/health/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer @@ -0,0 +1 @@ +org.glassfish.microprofile.health.HealthServletInitializer diff --git a/appserver/microprofile/health/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider b/appserver/microprofile/health/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider new file mode 100644 index 00000000000..5979adc2230 --- /dev/null +++ b/appserver/microprofile/health/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider @@ -0,0 +1 @@ +org.glassfish.microprofile.health.HealthCheckResponseProviderImpl diff --git a/appserver/microprofile/pom.xml b/appserver/microprofile/pom.xml index cda7e0192da..53d78e98208 100644 --- a/appserver/microprofile/pom.xml +++ b/appserver/microprofile/pom.xml @@ -34,6 +34,7 @@ config + health connectors diff --git a/appserver/pom.xml b/appserver/pom.xml index 930b998d02b..de06dde4304 100644 --- a/appserver/pom.xml +++ b/appserver/pom.xml @@ -154,6 +154,12 @@ 3.0.3 3.2.8 + + + 4.0.1 + 4.1.0 + + 2.1 2.0.2 @@ -655,6 +661,19 @@ ${helidon-config.version} + + + org.eclipse.microprofile.health + microprofile-health-api + ${microprofile.health-api.version} + + + io.helidon.microprofile.health + helidon-microprofile-health + ${helidon-health.version} + + + org.eclipse.microprofile.jwt diff --git a/appserver/tests/tck/microprofile/health/pom.xml b/appserver/tests/tck/microprofile/health/pom.xml new file mode 100644 index 00000000000..a3340c0a1e4 --- /dev/null +++ b/appserver/tests/tck/microprofile/health/pom.xml @@ -0,0 +1,83 @@ + + + + + 4.0.0 + + + org.glassfish.main.tests.tck + glassfish-external-tck-microprofile + 7.0.18-SNAPSHOT + + + glassfish-external-tck-microprofile-health + jar + + TCK: MicroProfile Health + + + + + org.jboss.weld + weld-core-impl + + + + org.eclipse.microprofile.health + microprofile-health-tck + 4.0.1 + + + org.eclipse.microprofile.health + microprofile-health-api + provided + + + org.hamcrest + hamcrest + + + + + + + maven-dependency-plugin + + + + unpack-glassfish + + + + + maven-failsafe-plugin + + + tck-suite.xml + + + dummy + Tennis + 120 + + + + + + diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java new file mode 100644 index 00000000000..bf9125ba997 --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 Contributors to Eclipse Foundation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.microprofile.health.tck; + +import java.util.logging.Logger; + +import org.glassfish.microprofile.health.tck.client.BeansXmlTransformer; +import org.glassfish.microprofile.health.tck.client.ConfigDeploymentExceptionTransformer; +import org.glassfish.microprofile.health.tck.client.LibraryIncluder; +import org.jboss.arquillian.container.spi.client.container.DeploymentExceptionTransformer; +import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; +import org.jboss.arquillian.core.spi.LoadableExtension; + +public class ConfigArquillianExtension implements LoadableExtension { + + private static final Logger LOGGER = Logger.getLogger(ConfigArquillianExtension.class.getName()); + + /** + * Register this object as an Arquillian extension + * @param extensionBuilder a context object for the extension + */ + @Override + public void register(ExtensionBuilder extensionBuilder) { + + LOGGER.info("Client Arquillian extension registered"); + + extensionBuilder.service(ApplicationArchiveProcessor.class, BeansXmlTransformer.class); + extensionBuilder.service(ApplicationArchiveProcessor.class, LibraryIncluder.class); + extensionBuilder.service(DeploymentExceptionTransformer.class, ConfigDeploymentExceptionTransformer.class); + + // Register this class as an Arquillian event observer + extensionBuilder.observer(BeansXmlTransformer.class); + } +} diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java new file mode 100644 index 00000000000..3167a1648eb --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2022 Contributors to Eclipse Foundation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.microprofile.health.tck.client; + +import java.net.URL; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.logging.Logger; + +import org.jboss.arquillian.container.spi.event.container.BeforeDeploy; +import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; +import org.jboss.arquillian.core.api.annotation.Observes; +import org.jboss.arquillian.test.spi.TestClass; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ArchivePath; +import org.jboss.shrinkwrap.api.Node; +import org.jboss.shrinkwrap.api.asset.ArchiveAsset; +import org.jboss.shrinkwrap.api.asset.UrlAsset; + +import static java.lang.String.format; + +/** + * This extension replaces beans.xml files with ones declaring the 'all' bean discovery type. + * This is because version 3.0.1 of the TCK still deploys an empty beans.xml due to a faulty assumption that + * CDI < 4 is still defaulting to the 'all' type. + */ +public class BeansXmlTransformer implements ApplicationArchiveProcessor { + + private static final Logger LOGGER = Logger.getLogger(BeansXmlTransformer.class.getName()); + + private static final String LIB_DIR_PATH = format("WEB-INF%slib", ArchivePath.SEPARATOR); + private static final String[] BEANS_XML_PATHS = { + format("/META-INF%sbeans.xml", ArchivePath.SEPARATOR), + format("/WEB-INF%sbeans.xml", ArchivePath.SEPARATOR), + }; + + private final URL beansXmlResource; + + public BeansXmlTransformer() { + this.beansXmlResource = getClass().getClassLoader().getResource("beans.xml"); + if (beansXmlResource == null) { + throw new IllegalStateException("Unable to find beans.xml resource in test dir"); + } + } + + /** + * Listen for and process non-testable deployments. This is required as, by default, ShouldThrowException annotated + * deployments aren't processed by ApplicationArchiveProcessors, but the beans xml may still need fixing. + * @param event + */ + protected void onEvent(@Observes BeforeDeploy event) { + final var deployment = event.getDeployment(); + + if (!deployment.testable()) { + new BeansXmlTransformer().process(deployment.getArchive()); + } + } + + @Override + public void process(Archive archive, TestClass testClass) { + process(archive); + } + + public void process(Archive archive) { + findBeansXml(archive) + .ifPresent(beansXml -> { + LOGGER.info(() -> format("Replacing beans.xml in archive [%s]", archive.getName())); + archive.add(new UrlAsset(beansXmlResource), beansXml.getPath()); + }); + processLibraries(archive, this::process); + } + + private static Optional findBeansXml(Archive archive) { + for (String beansXmlPath : BEANS_XML_PATHS) { + final var node = archive.get(beansXmlPath); + if (node != null) { + LOGGER.info(() -> format("Discovered beans.xml at path [%s]", node.getPath())); + return Optional.of(node); + } + } + return Optional.empty(); + } + + private static void processLibraries(Archive archive, Consumer> consumer) { + final var libDir = archive.get(LIB_DIR_PATH); + + if (libDir != null) { + for (var node : libDir.getChildren()) { + final var asset = node.getAsset(); + if (asset instanceof ArchiveAsset) { + LOGGER.info(() -> format("Processing subarchive [%s]", node.getPath())); + consumer.accept(((ArchiveAsset) asset).getArchive()); + } + } + } + } +} diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/ConfigDeploymentExceptionTransformer.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/ConfigDeploymentExceptionTransformer.java new file mode 100644 index 00000000000..7a5a3ab5f1b --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/ConfigDeploymentExceptionTransformer.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Contributors to Eclipse Foundation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.microprofile.health.tck.client; + +import jakarta.enterprise.inject.spi.DeploymentException; + +import org.jboss.arquillian.container.spi.client.container.DeploymentExceptionTransformer; + +/** + * The common GlassFishClientCommon handler will always throw a GlassfishClientException, + * with a message from the response. Deployment errors can safely be converted to the expected + * exception type. + */ +public class ConfigDeploymentExceptionTransformer implements DeploymentExceptionTransformer { + + @Override + public Throwable transform(Throwable throwable) { + if (throwable != null && throwable.getMessage().contains("Error occurred during deployment")) { + return new DeploymentException(throwable); + } + return throwable; + } + +} diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java new file mode 100644 index 00000000000..9308ffa1e18 --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java @@ -0,0 +1,47 @@ +package org.glassfish.microprofile.health.tck.client; + +import java.io.File; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; + +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; + +/** + * This extension adds certain libraries to deployed Arquillian apps. + * + * Libraries added: + * - Hamcrest, to prevent ClassNotFoundExceptions when running hamcrest tests + */ +public class LibraryIncluder implements ApplicationArchiveProcessor { + + private static final Logger LOG = System.getLogger(LibraryIncluder.class.getName()); + + @Override + public void process(Archive archive, TestClass testClass) { + + // Only process web archives + if (!(archive instanceof WebArchive)) { + return; + } + final var webArchive = (WebArchive) archive; + webArchive.addAsLibraries(resolveDependency("org.hamcrest:hamcrest")); + webArchive.addAsLibraries(resolveDependencyTransitive("org.eclipse.microprofile.health:microprofile-health-tck")); + LOG.log(Level.INFO, () -> "webArchive:\n" + webArchive.toString(true)); + } + + private static File[] resolveDependency(String coordinates) { + return Maven.configureResolver().workOffline().loadPomFromFile("pom.xml") + .resolve(coordinates).withoutTransitivity() + .asFile(); + } + + private static File[] resolveDependencyTransitive(String coordinates) { + return Maven.configureResolver().workOffline().loadPomFromFile("pom.xml") + .resolve(coordinates).withTransitivity() + .asFile(); + } +} diff --git a/appserver/tests/tck/microprofile/health/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/appserver/tests/tck/microprofile/health/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension new file mode 100644 index 00000000000..eff3408537c --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension @@ -0,0 +1 @@ +org.glassfish.microprofile.health.tck.ConfigArquillianExtension \ No newline at end of file diff --git a/appserver/tests/tck/microprofile/health/src/main/resources/beans.xml b/appserver/tests/tck/microprofile/health/src/main/resources/beans.xml new file mode 100644 index 00000000000..eea1bce2d91 --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/resources/beans.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/appserver/tests/tck/microprofile/health/src/test/java/org/glassfish/microprofile/health/tck/ContainerSetup.java b/appserver/tests/tck/microprofile/health/src/test/java/org/glassfish/microprofile/health/tck/ContainerSetup.java new file mode 100644 index 00000000000..37fbcfa8c8c --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/test/java/org/glassfish/microprofile/health/tck/ContainerSetup.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Contributors to Eclipse Foundation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.microprofile.health.tck; + +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.testng.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.testng.annotations.Test; + +/** + * Setup the container via a test that runs before the TCK + */ +public class ContainerSetup extends Arquillian { + + @Deployment + public static Archive deployment() { + return ShrinkWrap.create(WebArchive.class, "container-setup.war"); + } + + @Test + public void setup() { + // Setup TCK required system properties + System.setProperty("mp.health.disable-default-procedures", "true"); + } +} diff --git a/appserver/tests/tck/microprofile/health/tck-suite.xml b/appserver/tests/tck/microprofile/health/tck-suite.xml new file mode 100644 index 00000000000..ff008a7c61a --- /dev/null +++ b/appserver/tests/tck/microprofile/health/tck-suite.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/appserver/tests/tck/microprofile/pom.xml b/appserver/tests/tck/microprofile/pom.xml index cd132aeb464..01dd3a6c69a 100644 --- a/appserver/tests/tck/microprofile/pom.xml +++ b/appserver/tests/tck/microprofile/pom.xml @@ -40,6 +40,7 @@ config + health rest-client From a1c4b385c8c75a2239aa3ed41f21d4b07c5f8556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 15 Oct 2024 08:28:11 -0300 Subject: [PATCH 02/28] Update version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- appserver/microprofile/health/pom.xml | 2 +- appserver/tests/tck/microprofile/health/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/appserver/microprofile/health/pom.xml b/appserver/microprofile/health/pom.xml index 07bb3ed4ce2..841aeb7db9a 100644 --- a/appserver/microprofile/health/pom.xml +++ b/appserver/microprofile/health/pom.xml @@ -23,7 +23,7 @@ org.glassfish.main.microprofile microprofile-parent - 7.0.18-SNAPSHOT + 7.0.19-SNAPSHOT microprofile-health diff --git a/appserver/tests/tck/microprofile/health/pom.xml b/appserver/tests/tck/microprofile/health/pom.xml index a3340c0a1e4..ab3eb856be5 100644 --- a/appserver/tests/tck/microprofile/health/pom.xml +++ b/appserver/tests/tck/microprofile/health/pom.xml @@ -23,7 +23,7 @@ org.glassfish.main.tests.tck glassfish-external-tck-microprofile - 7.0.18-SNAPSHOT + 7.0.19-SNAPSHOT glassfish-external-tck-microprofile-health From 0490f269ad2a10b810f2c6d5b36040045e157b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 15 Oct 2024 22:27:36 -0300 Subject: [PATCH 03/28] Fix TCK tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- appserver/microprofile/health/pom.xml | 11 ++- .../microprofile/health/HealthServlet.java | 86 +++++++++++++++---- .../health/HealthServletInitializer.java | 18 ++-- .../glassfish/microprofile/health/Output.java | 2 +- .../health/tck/client/LibraryIncluder.java | 1 - 5 files changed, 83 insertions(+), 35 deletions(-) diff --git a/appserver/microprofile/health/pom.xml b/appserver/microprofile/health/pom.xml index 841aeb7db9a..764eddcd06f 100644 --- a/appserver/microprofile/health/pom.xml +++ b/appserver/microprofile/health/pom.xml @@ -37,7 +37,11 @@ org.eclipse.microprofile.health microprofile-health-api - + + org.glassfish.main.microprofile + microprofile-config + ${project.version} + jakarta.enterprise jakarta.enterprise.cdi-api @@ -86,10 +90,15 @@ org.glassfish.microprofile.health; + io.helidon.config; + io.helidon.config.mp; + org.eclipse.microprofile.config.inject; + org.eclipse.microprofile.config; org.eclipse.microprofile.health.spi; org.eclipse.microprofile.health; jakarta.enterprise.util; jakarta.enterprise.inject; + jakarta.enterprise.inject.spi; jakarta.servlet.http; jakarta.servlet; jakarta.json.bind; diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java index 541acb1baa1..7b1076370db 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java @@ -1,52 +1,100 @@ package org.glassfish.microprofile.health; +import io.helidon.config.mp.MpConfigProviderResolver; import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.spi.CDI; import jakarta.json.bind.Jsonb; import jakarta.json.bind.JsonbBuilder; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; +import java.util.Objects; +import java.util.stream.Stream; +import org.eclipse.microprofile.config.Config; import org.eclipse.microprofile.health.HealthCheck; import org.eclipse.microprofile.health.HealthCheckResponse; import org.eclipse.microprofile.health.Liveness; import org.eclipse.microprofile.health.Readiness; +import org.eclipse.microprofile.health.Startup; public class HealthServlet extends HttpServlet { + private static HealthCheckResponse callHealthCheck(HealthCheck healthCheck) { + try { + return healthCheck.call(); + } catch (RuntimeException e) { + e.printStackTrace(); + return HealthCheckResponse.builder() + .down() + .name(healthCheck.getClass().getName()) + .withData("rootCause", e.getMessage()) + .build(); + } + } + @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + try (Jsonb jsonb = JsonbBuilder.create()) { - Instance select = CDI.current().select(HealthCheck.class); - if (req.getRequestURI().endsWith("health/live")) { - select = select.select(Liveness.Literal.INSTANCE); - } else if (req.getRequestURI().endsWith("health/ready")) { - select = select.select(Readiness.Literal.INSTANCE); - } + HealthCheckResponse.Status emptyResponse = HealthCheckResponse.Status.UP; - List healthCheckResults = select - .stream() - .map(HealthCheck::call) - .toList(); + Instance select = CDI.current().select(HealthCheck.class); + Stream healthChecks; + String requestURI = req.getRequestURI(); + if (requestURI.endsWith("health/live")) { + healthChecks = select.select(Liveness.Literal.INSTANCE).stream(); + } else if (requestURI.endsWith("health/ready")) { + healthChecks = select.select(Readiness.Literal.INSTANCE).stream(); + emptyResponse = Objects.equals(getConfig().getOptionalValue("mp.health.default.readiness.empty.response", String.class).orElse("DOWN"), "UP") ? HealthCheckResponse.Status.UP : HealthCheckResponse.Status.DOWN; + } else if (requestURI.endsWith("health/started")) { + healthChecks = select.select(Startup.Literal.INSTANCE).stream(); + emptyResponse = Objects.equals(getConfig().getOptionalValue("mp.health.default.startup.empty.response", String.class).orElse("DOWN"), "UP") ? HealthCheckResponse.Status.UP : HealthCheckResponse.Status.DOWN; + } else { + healthChecks = Stream.of( + select.select(Liveness.Literal.INSTANCE).stream(), + select.select(Readiness.Literal.INSTANCE).stream(), + select.select(Startup.Literal.INSTANCE).stream() + ).flatMap(s -> s); + } - HealthCheckResponse.Status overallStatus = healthCheckResults.stream() - .map(HealthCheckResponse::getStatus) - .filter(HealthCheckResponse.Status.DOWN::equals) - .findFirst().orElse(HealthCheckResponse.Status.UP); - Output output = new Output(overallStatus, healthCheckResults); - try (Jsonb jsonb = JsonbBuilder.create()) { + List healthCheckResults = healthChecks + .map(HealthServlet::callHealthCheck) + .toList(); + + HealthCheckResponse.Status overallStatus = + healthCheckResults.isEmpty() ? emptyResponse : + healthCheckResults.stream() + .map(HealthCheckResponse::getStatus) + .filter(HealthCheckResponse.Status.DOWN::equals) + .findFirst() + .orElse(HealthCheckResponse.Status.UP); + + Output output = new Output(overallStatus, healthCheckResults); + String json = jsonb.toJson(output); + + resp.setStatus(overallStatus == HealthCheckResponse.Status.UP ? + HttpServletResponse.SC_OK : + HttpServletResponse.SC_SERVICE_UNAVAILABLE); + resp.getWriter().println(json); } catch (Exception e) { - throw new RuntimeException(e); + e.printStackTrace(); + resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + resp.getWriter().println("Internal server error: "); + e.printStackTrace(resp.getWriter()); } } + + private static Config getConfig() { + // ConfigProvider.getConfig() does not work in the Arquillian deployment + return new MpConfigProviderResolver().getConfig(); + } } diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java index 971d86793c6..809759caa67 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java @@ -2,25 +2,17 @@ import jakarta.servlet.ServletContainerInitializer; import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; import java.util.Set; public class HealthServletInitializer implements ServletContainerInitializer { - static { - System.err.println("Class loaded!"); - } @Override - public void onStartup(Set> set, ServletContext servletContext) throws ServletException { - System.err.println("onStartup: " + servletContext.getContextPath()); - // for now -// if (!servletContext.getContextPath().isEmpty()) { -// return; -// } + public void onStartup(Set> set, ServletContext servletContext) { + if (servletContext.getContextPath().isEmpty()) { + return; + } servletContext.addServlet("health", HealthServlet.class) - .addMapping("/health", "/health/live", "/health/ready"); -// servletContext.addServlet("health-liveness", HealthLivenessServlet.class).addMapping("/health/live"); -// servletContext.addServlet("health-readness", HealthReadinessServlet.class).addMapping("/health/ready"); + .addMapping("/health", "/health/live", "/health/ready", "/health/started"); } } diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java index b12f5a5ec48..bf2c8c00283 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java @@ -4,5 +4,5 @@ import org.eclipse.microprofile.health.HealthCheckResponse; -record Output(HealthCheckResponse.Status getStatus, List getChecks) { +public record Output(HealthCheckResponse.Status status, List checks) { } diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java index 9308ffa1e18..fe8bbf8a10e 100644 --- a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java @@ -29,7 +29,6 @@ public void process(Archive archive, TestClass testClass) { } final var webArchive = (WebArchive) archive; webArchive.addAsLibraries(resolveDependency("org.hamcrest:hamcrest")); - webArchive.addAsLibraries(resolveDependencyTransitive("org.eclipse.microprofile.health:microprofile-health-tck")); LOG.log(Level.INFO, () -> "webArchive:\n" + webArchive.toString(true)); } From 7be24a947e06da00b609b9ff5638613a3202c6f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Wed, 16 Oct 2024 09:09:37 -0300 Subject: [PATCH 04/28] Fix Checkstyle issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../java/org/glassfish/microprofile/health/HealthServlet.java | 1 + 1 file changed, 1 insertion(+) diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java index 7b1076370db..ee1aefe885a 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java @@ -1,6 +1,7 @@ package org.glassfish.microprofile.health; import io.helidon.config.mp.MpConfigProviderResolver; + import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.spi.CDI; import jakarta.json.bind.Jsonb; From 3b9cc1719611f68354a4a6a981102a3e60fa5113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Mon, 28 Oct 2024 09:34:05 -0300 Subject: [PATCH 05/28] Ignore Microprofile Config if it is not enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../microprofile/health/HealthServlet.java | 54 ++++++++++++------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java index ee1aefe885a..46791243df9 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java @@ -1,7 +1,5 @@ package org.glassfish.microprofile.health; -import io.helidon.config.mp.MpConfigProviderResolver; - import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.spi.CDI; import jakarta.json.bind.Jsonb; @@ -10,20 +8,22 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.List; -import java.util.Objects; -import java.util.stream.Stream; - -import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.health.HealthCheck; import org.eclipse.microprofile.health.HealthCheckResponse; import org.eclipse.microprofile.health.Liveness; import org.eclipse.microprofile.health.Readiness; import org.eclipse.microprofile.health.Startup; +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + public class HealthServlet extends HttpServlet { + private static final String MP_DEFAULT_STARTUP_EMPTY_RESPONSE = "mp.health.default.startup.empty.response"; + private static final String MP_DEFAULT_READINESS_EMPTY_RESPONSE = "mp.health.default.readiness.empty.response"; private static HealthCheckResponse callHealthCheck(HealthCheck healthCheck) { try { @@ -51,10 +51,13 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO healthChecks = select.select(Liveness.Literal.INSTANCE).stream(); } else if (requestURI.endsWith("health/ready")) { healthChecks = select.select(Readiness.Literal.INSTANCE).stream(); - emptyResponse = Objects.equals(getConfig().getOptionalValue("mp.health.default.readiness.empty.response", String.class).orElse("DOWN"), "UP") ? HealthCheckResponse.Status.UP : HealthCheckResponse.Status.DOWN; + emptyResponse = getValue(MP_DEFAULT_READINESS_EMPTY_RESPONSE) + .orElse(HealthCheckResponse.Status.DOWN); + } else if (requestURI.endsWith("health/started")) { healthChecks = select.select(Startup.Literal.INSTANCE).stream(); - emptyResponse = Objects.equals(getConfig().getOptionalValue("mp.health.default.startup.empty.response", String.class).orElse("DOWN"), "UP") ? HealthCheckResponse.Status.UP : HealthCheckResponse.Status.DOWN; + emptyResponse = getValue(MP_DEFAULT_STARTUP_EMPTY_RESPONSE) + .orElse(HealthCheckResponse.Status.DOWN); } else { healthChecks = Stream.of( select.select(Liveness.Literal.INSTANCE).stream(), @@ -68,21 +71,26 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO .map(HealthServlet::callHealthCheck) .toList(); - HealthCheckResponse.Status overallStatus = - healthCheckResults.isEmpty() ? emptyResponse : - healthCheckResults.stream() + HealthCheckResponse.Status overallStatus; + if (healthCheckResults.isEmpty()) { + overallStatus = emptyResponse; + } else { + overallStatus = healthCheckResults.stream() .map(HealthCheckResponse::getStatus) .filter(HealthCheckResponse.Status.DOWN::equals) .findFirst() .orElse(HealthCheckResponse.Status.UP); - + } Output output = new Output(overallStatus, healthCheckResults); String json = jsonb.toJson(output); - resp.setStatus(overallStatus == HealthCheckResponse.Status.UP ? - HttpServletResponse.SC_OK : - HttpServletResponse.SC_SERVICE_UNAVAILABLE); + resp.setStatus( + switch (overallStatus) { + case UP -> HttpServletResponse.SC_OK; + case DOWN -> HttpServletResponse.SC_SERVICE_UNAVAILABLE; + } + ); resp.getWriter().println(json); } catch (Exception e) { @@ -94,8 +102,14 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO } - private static Config getConfig() { - // ConfigProvider.getConfig() does not work in the Arquillian deployment - return new MpConfigProviderResolver().getConfig(); + private Optional getValue(String value) { + try { + return ConfigProvider.getConfig(getServletContext().getClassLoader()) + .getOptionalValue(value, String.class) + .map(HealthCheckResponse.Status::valueOf); + } catch (IllegalStateException e) { + // Microprofile Config is not enabled for this application + return Optional.empty(); + } } } From 1ec8dd82eeeecd10728a6997e100cfe52470e9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Mon, 28 Oct 2024 09:34:32 -0300 Subject: [PATCH 06/28] Remove unused system properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- appserver/tests/tck/microprofile/health/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/appserver/tests/tck/microprofile/health/pom.xml b/appserver/tests/tck/microprofile/health/pom.xml index ab3eb856be5..2abf74c9328 100644 --- a/appserver/tests/tck/microprofile/health/pom.xml +++ b/appserver/tests/tck/microprofile/health/pom.xml @@ -71,11 +71,6 @@ tck-suite.xml - - dummy - Tennis - 120 - From f0b52b828329b7ea20db463ce8b4445618fddfc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Mon, 28 Oct 2024 09:35:06 -0300 Subject: [PATCH 07/28] Remove unused method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../microprofile/health/tck/client/LibraryIncluder.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java index fe8bbf8a10e..bc84ace13ac 100644 --- a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java @@ -37,10 +37,4 @@ private static File[] resolveDependency(String coordinates) { .resolve(coordinates).withoutTransitivity() .asFile(); } - - private static File[] resolveDependencyTransitive(String coordinates) { - return Maven.configureResolver().workOffline().loadPomFromFile("pom.xml") - .resolve(coordinates).withTransitivity() - .asFile(); - } } From b2842fe57eeaa3919a0a2adc149eb4b862386777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Mon, 28 Oct 2024 23:10:52 -0300 Subject: [PATCH 08/28] Remove unused Import-Package declarations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- appserver/microprofile/health/pom.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/appserver/microprofile/health/pom.xml b/appserver/microprofile/health/pom.xml index 764eddcd06f..65ca3509173 100644 --- a/appserver/microprofile/health/pom.xml +++ b/appserver/microprofile/health/pom.xml @@ -90,9 +90,6 @@ org.glassfish.microprofile.health; - io.helidon.config; - io.helidon.config.mp; - org.eclipse.microprofile.config.inject; org.eclipse.microprofile.config; org.eclipse.microprofile.health.spi; org.eclipse.microprofile.health; From cfab4421bd156046583e12e1517d66508a083bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Mon, 28 Oct 2024 23:15:35 -0300 Subject: [PATCH 09/28] Fix checkstyle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../glassfish/microprofile/health/HealthServlet.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java index 46791243df9..243b1014ac7 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java @@ -8,6 +8,11 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.health.HealthCheck; import org.eclipse.microprofile.health.HealthCheckResponse; @@ -15,11 +20,6 @@ import org.eclipse.microprofile.health.Readiness; import org.eclipse.microprofile.health.Startup; -import java.io.IOException; -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; - public class HealthServlet extends HttpServlet { private static final String MP_DEFAULT_STARTUP_EMPTY_RESPONSE = "mp.health.default.startup.empty.response"; From 84b51ef6cce051033ea8ec01bfe1f279b77ccd70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 29 Oct 2024 14:17:37 -0300 Subject: [PATCH 10/28] Move config file from META-INF to WEB-INF/classes/META-INF MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../health/tck/ConfigArquillianExtension.java | 2 + ...croProfileConfigPropertiesTransformer.java | 45 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/MicroProfileConfigPropertiesTransformer.java diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java index bf9125ba997..30788c73c7b 100644 --- a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java @@ -20,6 +20,7 @@ import org.glassfish.microprofile.health.tck.client.BeansXmlTransformer; import org.glassfish.microprofile.health.tck.client.ConfigDeploymentExceptionTransformer; import org.glassfish.microprofile.health.tck.client.LibraryIncluder; +import org.glassfish.microprofile.health.tck.client.MicroProfileConfigPropertiesTransformer; import org.jboss.arquillian.container.spi.client.container.DeploymentExceptionTransformer; import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; import org.jboss.arquillian.core.spi.LoadableExtension; @@ -38,6 +39,7 @@ public void register(ExtensionBuilder extensionBuilder) { LOGGER.info("Client Arquillian extension registered"); extensionBuilder.service(ApplicationArchiveProcessor.class, BeansXmlTransformer.class); + extensionBuilder.service(ApplicationArchiveProcessor.class, MicroProfileConfigPropertiesTransformer.class); extensionBuilder.service(ApplicationArchiveProcessor.class, LibraryIncluder.class); extensionBuilder.service(DeploymentExceptionTransformer.class, ConfigDeploymentExceptionTransformer.class); diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/MicroProfileConfigPropertiesTransformer.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/MicroProfileConfigPropertiesTransformer.java new file mode 100644 index 00000000000..1ccb433fecf --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/MicroProfileConfigPropertiesTransformer.java @@ -0,0 +1,45 @@ +package org.glassfish.microprofile.health.tck.client; + +import java.util.logging.Logger; + +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.Node; + +import static java.lang.String.format; +/** + * This class addresses a discrepancy in MicroProfile specifications regarding the location of + * the `microprofile-config.properties` file. Originally, MicroProfile Config specifies that + * `microprofile-config.properties` should be located at `META-INF/` within the `classes` directory + * of a WAR (i.e., `WEB-INF/classes/META-INF/microprofile-config.properties`). However, some implementations + * (such as those supporting MP OpenAPI) also recognize the top-level `META-INF/microprofile-config.properties`. + *

+ * The MicroProfile Health TCK, which does not explicitly require OpenAPI, still expects the file at + * the top-level `META-INF/` location, creating inconsistency in the configuration support across + * implementations. This divergence means implementations supporting only MP Config are restricted + * to `WEB-INF/classes/META-INF`, while those supporting both Config and OpenAPI may support both + * locations. + *

+ * To address this in GlassFish and ensure compatibility with the Health TCK, this class leverages + * an Arquillian `ApplicationArchiveProcessor` to move the file from the unsupported top-level + * `META-INF` to the standard `WEB-INF/classes/META-INF` in the archive, ensuring that the tests + * align with the expected location for all base MP APIs. + */ +public class MicroProfileConfigPropertiesTransformer implements ApplicationArchiveProcessor { + private static final Logger LOGGER = Logger.getLogger(MicroProfileConfigPropertiesTransformer.class.getName()); + private static final String ORIGINAL_META_INF_CONFIG = "/META-INF/microprofile-config.properties"; + private static final String TARGET_META_INF_CONFIG = "/WEB-INF/classes" + ORIGINAL_META_INF_CONFIG; + + @Override + public void process(Archive archive, TestClass testClass) { + Node node = archive.get(ORIGINAL_META_INF_CONFIG); + if (node != null) { + LOGGER.info(() -> format("Moving %s to %s in archive [%s]", ORIGINAL_META_INF_CONFIG, TARGET_META_INF_CONFIG, archive.getName())); + archive.delete(ORIGINAL_META_INF_CONFIG); + archive.add(node.getAsset(), TARGET_META_INF_CONFIG); + } + } + + +} \ No newline at end of file From 6f5fbdf3d4a450c66929361802f4e5d73d3367f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 29 Oct 2024 14:47:45 -0300 Subject: [PATCH 11/28] Remove unused BeansXmlTransformer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../health/tck/ConfigArquillianExtension.java | 5 - .../tck/client/BeansXmlTransformer.java | 110 ------------------ .../health/src/main/resources/beans.xml | 4 - 3 files changed, 119 deletions(-) delete mode 100644 appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java delete mode 100644 appserver/tests/tck/microprofile/health/src/main/resources/beans.xml diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java index 30788c73c7b..fd7e32b4557 100644 --- a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java @@ -17,7 +17,6 @@ import java.util.logging.Logger; -import org.glassfish.microprofile.health.tck.client.BeansXmlTransformer; import org.glassfish.microprofile.health.tck.client.ConfigDeploymentExceptionTransformer; import org.glassfish.microprofile.health.tck.client.LibraryIncluder; import org.glassfish.microprofile.health.tck.client.MicroProfileConfigPropertiesTransformer; @@ -38,12 +37,8 @@ public void register(ExtensionBuilder extensionBuilder) { LOGGER.info("Client Arquillian extension registered"); - extensionBuilder.service(ApplicationArchiveProcessor.class, BeansXmlTransformer.class); extensionBuilder.service(ApplicationArchiveProcessor.class, MicroProfileConfigPropertiesTransformer.class); extensionBuilder.service(ApplicationArchiveProcessor.class, LibraryIncluder.class); extensionBuilder.service(DeploymentExceptionTransformer.class, ConfigDeploymentExceptionTransformer.class); - - // Register this class as an Arquillian event observer - extensionBuilder.observer(BeansXmlTransformer.class); } } diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java deleted file mode 100644 index 3167a1648eb..00000000000 --- a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2022 Contributors to Eclipse Foundation. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0, which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * This Source Code may also be made available under the following Secondary - * Licenses when the conditions for such availability set forth in the - * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, - * version 2 with the GNU Classpath Exception, which is available at - * https://www.gnu.org/software/classpath/license.html. - * - * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 - */ -package org.glassfish.microprofile.health.tck.client; - -import java.net.URL; -import java.util.Optional; -import java.util.function.Consumer; -import java.util.logging.Logger; - -import org.jboss.arquillian.container.spi.event.container.BeforeDeploy; -import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; -import org.jboss.arquillian.core.api.annotation.Observes; -import org.jboss.arquillian.test.spi.TestClass; -import org.jboss.shrinkwrap.api.Archive; -import org.jboss.shrinkwrap.api.ArchivePath; -import org.jboss.shrinkwrap.api.Node; -import org.jboss.shrinkwrap.api.asset.ArchiveAsset; -import org.jboss.shrinkwrap.api.asset.UrlAsset; - -import static java.lang.String.format; - -/** - * This extension replaces beans.xml files with ones declaring the 'all' bean discovery type. - * This is because version 3.0.1 of the TCK still deploys an empty beans.xml due to a faulty assumption that - * CDI < 4 is still defaulting to the 'all' type. - */ -public class BeansXmlTransformer implements ApplicationArchiveProcessor { - - private static final Logger LOGGER = Logger.getLogger(BeansXmlTransformer.class.getName()); - - private static final String LIB_DIR_PATH = format("WEB-INF%slib", ArchivePath.SEPARATOR); - private static final String[] BEANS_XML_PATHS = { - format("/META-INF%sbeans.xml", ArchivePath.SEPARATOR), - format("/WEB-INF%sbeans.xml", ArchivePath.SEPARATOR), - }; - - private final URL beansXmlResource; - - public BeansXmlTransformer() { - this.beansXmlResource = getClass().getClassLoader().getResource("beans.xml"); - if (beansXmlResource == null) { - throw new IllegalStateException("Unable to find beans.xml resource in test dir"); - } - } - - /** - * Listen for and process non-testable deployments. This is required as, by default, ShouldThrowException annotated - * deployments aren't processed by ApplicationArchiveProcessors, but the beans xml may still need fixing. - * @param event - */ - protected void onEvent(@Observes BeforeDeploy event) { - final var deployment = event.getDeployment(); - - if (!deployment.testable()) { - new BeansXmlTransformer().process(deployment.getArchive()); - } - } - - @Override - public void process(Archive archive, TestClass testClass) { - process(archive); - } - - public void process(Archive archive) { - findBeansXml(archive) - .ifPresent(beansXml -> { - LOGGER.info(() -> format("Replacing beans.xml in archive [%s]", archive.getName())); - archive.add(new UrlAsset(beansXmlResource), beansXml.getPath()); - }); - processLibraries(archive, this::process); - } - - private static Optional findBeansXml(Archive archive) { - for (String beansXmlPath : BEANS_XML_PATHS) { - final var node = archive.get(beansXmlPath); - if (node != null) { - LOGGER.info(() -> format("Discovered beans.xml at path [%s]", node.getPath())); - return Optional.of(node); - } - } - return Optional.empty(); - } - - private static void processLibraries(Archive archive, Consumer> consumer) { - final var libDir = archive.get(LIB_DIR_PATH); - - if (libDir != null) { - for (var node : libDir.getChildren()) { - final var asset = node.getAsset(); - if (asset instanceof ArchiveAsset) { - LOGGER.info(() -> format("Processing subarchive [%s]", node.getPath())); - consumer.accept(((ArchiveAsset) asset).getArchive()); - } - } - } - } -} diff --git a/appserver/tests/tck/microprofile/health/src/main/resources/beans.xml b/appserver/tests/tck/microprofile/health/src/main/resources/beans.xml deleted file mode 100644 index eea1bce2d91..00000000000 --- a/appserver/tests/tck/microprofile/health/src/main/resources/beans.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file From c21a583a10fdec3e97f019e8a01782640638d020 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 29 Oct 2024 14:49:39 -0300 Subject: [PATCH 12/28] Improve error handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../microprofile/health/HealthServlet.java | 47 ++++++++++--------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java index 243b1014ac7..bb06d31608e 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java @@ -11,6 +11,8 @@ import java.io.IOException; import java.util.List; import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.stream.Stream; import org.eclipse.microprofile.config.ConfigProvider; @@ -24,24 +26,30 @@ public class HealthServlet extends HttpServlet { private static final String MP_DEFAULT_STARTUP_EMPTY_RESPONSE = "mp.health.default.startup.empty.response"; private static final String MP_DEFAULT_READINESS_EMPTY_RESPONSE = "mp.health.default.readiness.empty.response"; + private static final Logger LOGGER = Logger.getLogger(HealthServlet.class.getName()); private static HealthCheckResponse callHealthCheck(HealthCheck healthCheck) { try { return healthCheck.call(); } catch (RuntimeException e) { - e.printStackTrace(); - return HealthCheckResponse.builder() - .down() - .name(healthCheck.getClass().getName()) - .withData("rootCause", e.getMessage()) - .build(); + LOGGER.log(Level.SEVERE, "Health check failed", e); + return buildHealthCheckResponse(healthCheck.getClass().getName(), e); } } + private static HealthCheckResponse buildHealthCheckResponse(String name, Exception e) { + return HealthCheckResponse.builder() + .down() + .name(name) + .withData("rootCause", e.getMessage()) + .build(); + } + @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - try (Jsonb jsonb = JsonbBuilder.create()) { + Output output; + try { HealthCheckResponse.Status emptyResponse = HealthCheckResponse.Status.UP; Instance select = CDI.current().select(HealthCheck.class); @@ -81,25 +89,22 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO .findFirst() .orElse(HealthCheckResponse.Status.UP); } - Output output = new Output(overallStatus, healthCheckResults); - - String json = jsonb.toJson(output); - - resp.setStatus( - switch (overallStatus) { - case UP -> HttpServletResponse.SC_OK; - case DOWN -> HttpServletResponse.SC_SERVICE_UNAVAILABLE; - } - ); + output = new Output(overallStatus, healthCheckResults); - resp.getWriter().println(json); + int httpStatus = switch (overallStatus) { + case UP -> HttpServletResponse.SC_OK; + case DOWN -> HttpServletResponse.SC_SERVICE_UNAVAILABLE; + }; + resp.setStatus(httpStatus); } catch (Exception e) { - e.printStackTrace(); + LOGGER.log(Level.SEVERE, "Unable to fetch health check status", e); + output = new Output(HealthCheckResponse.Status.DOWN, List.of(buildHealthCheckResponse("error", e))); resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - resp.getWriter().println("Internal server error: "); - e.printStackTrace(resp.getWriter()); } + Jsonb jsonb = JsonbBuilder.create(); + String json = jsonb.toJson(output); + resp.getWriter().println(json); } private Optional getValue(String value) { From 1df0d363490f13328e612f97d502cc797211e57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 29 Oct 2024 14:53:31 -0300 Subject: [PATCH 13/28] Rename Arquillian extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- ...rquillianExtension.java => HealthArquillianExtension.java} | 4 ++-- .../services/org.jboss.arquillian.core.spi.LoadableExtension | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/{ConfigArquillianExtension.java => HealthArquillianExtension.java} (93%) diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java similarity index 93% rename from appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java rename to appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java index fd7e32b4557..86f9232be08 100644 --- a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/ConfigArquillianExtension.java +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java @@ -24,9 +24,9 @@ import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; import org.jboss.arquillian.core.spi.LoadableExtension; -public class ConfigArquillianExtension implements LoadableExtension { +public class HealthArquillianExtension implements LoadableExtension { - private static final Logger LOGGER = Logger.getLogger(ConfigArquillianExtension.class.getName()); + private static final Logger LOGGER = Logger.getLogger(HealthArquillianExtension.class.getName()); /** * Register this object as an Arquillian extension diff --git a/appserver/tests/tck/microprofile/health/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/appserver/tests/tck/microprofile/health/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension index eff3408537c..9df6669abeb 100644 --- a/appserver/tests/tck/microprofile/health/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension +++ b/appserver/tests/tck/microprofile/health/src/main/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension @@ -1 +1 @@ -org.glassfish.microprofile.health.tck.ConfigArquillianExtension \ No newline at end of file +org.glassfish.microprofile.health.tck.HealthArquillianExtension \ No newline at end of file From 7d13b7d7bbfd3b80491204750bc10b4fe95c4abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 29 Oct 2024 14:59:42 -0300 Subject: [PATCH 14/28] Remove unused archive processor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../health/tck/HealthArquillianExtension.java | 2 - .../health/tck/client/LibraryIncluder.java | 40 ------------------- 2 files changed, 42 deletions(-) delete mode 100644 appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java index 86f9232be08..fdf4d2e1f0f 100644 --- a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java @@ -18,7 +18,6 @@ import java.util.logging.Logger; import org.glassfish.microprofile.health.tck.client.ConfigDeploymentExceptionTransformer; -import org.glassfish.microprofile.health.tck.client.LibraryIncluder; import org.glassfish.microprofile.health.tck.client.MicroProfileConfigPropertiesTransformer; import org.jboss.arquillian.container.spi.client.container.DeploymentExceptionTransformer; import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; @@ -38,7 +37,6 @@ public void register(ExtensionBuilder extensionBuilder) { LOGGER.info("Client Arquillian extension registered"); extensionBuilder.service(ApplicationArchiveProcessor.class, MicroProfileConfigPropertiesTransformer.class); - extensionBuilder.service(ApplicationArchiveProcessor.class, LibraryIncluder.class); extensionBuilder.service(DeploymentExceptionTransformer.class, ConfigDeploymentExceptionTransformer.class); } } diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java deleted file mode 100644 index bc84ace13ac..00000000000 --- a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/LibraryIncluder.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.glassfish.microprofile.health.tck.client; - -import java.io.File; -import java.lang.System.Logger; -import java.lang.System.Logger.Level; - -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; - -/** - * This extension adds certain libraries to deployed Arquillian apps. - * - * Libraries added: - * - Hamcrest, to prevent ClassNotFoundExceptions when running hamcrest tests - */ -public class LibraryIncluder implements ApplicationArchiveProcessor { - - private static final Logger LOG = System.getLogger(LibraryIncluder.class.getName()); - - @Override - public void process(Archive archive, TestClass testClass) { - - // Only process web archives - if (!(archive instanceof WebArchive)) { - return; - } - final var webArchive = (WebArchive) archive; - webArchive.addAsLibraries(resolveDependency("org.hamcrest:hamcrest")); - LOG.log(Level.INFO, () -> "webArchive:\n" + webArchive.toString(true)); - } - - private static File[] resolveDependency(String coordinates) { - return Maven.configureResolver().workOffline().loadPomFromFile("pom.xml") - .resolve(coordinates).withoutTransitivity() - .asFile(); - } -} From 2d80b6d6b980953f2b8cd67136f6dfe5036ab96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 29 Oct 2024 15:08:52 -0300 Subject: [PATCH 15/28] Add license MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- appserver/featuresets/glassfish/pom.xml | 2 +- appserver/microprofile/health/pom.xml | 2 +- .../health/HealthCheckResponseBuilderImpl.java | 15 +++++++++++++++ .../health/HealthCheckResponseProviderImpl.java | 15 +++++++++++++++ .../microprofile/health/HealthServlet.java | 15 +++++++++++++++ .../health/HealthServletInitializer.java | 15 +++++++++++++++ .../org/glassfish/microprofile/health/Output.java | 15 +++++++++++++++ appserver/microprofile/pom.xml | 2 +- appserver/tests/tck/microprofile/health/pom.xml | 2 +- .../ConfigDeploymentExceptionTransformer.java | 2 +- .../MicroProfileConfigPropertiesTransformer.java | 15 +++++++++++++++ .../microprofile/health/tck/ContainerSetup.java | 2 +- .../tests/tck/microprofile/health/tck-suite.xml | 2 +- appserver/tests/tck/microprofile/pom.xml | 2 +- 14 files changed, 98 insertions(+), 8 deletions(-) diff --git a/appserver/featuresets/glassfish/pom.xml b/appserver/featuresets/glassfish/pom.xml index bca0d3f1467..a846df269d3 100644 --- a/appserver/featuresets/glassfish/pom.xml +++ b/appserver/featuresets/glassfish/pom.xml @@ -1,6 +1,6 @@ 4.0.1 - 4.1.0 - 2.1 @@ -667,11 +665,6 @@ microprofile-health-api ${microprofile.health-api.version} - - io.helidon.microprofile.health - helidon-microprofile-health - ${helidon-health.version} - From 2b2e6e82e8b4d07b60c6fc5d9d1ae79b3cced215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 5 Nov 2024 09:24:29 -0300 Subject: [PATCH 18/28] Update version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- appserver/microprofile/health/pom.xml | 2 +- appserver/tests/tck/microprofile/health/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/appserver/microprofile/health/pom.xml b/appserver/microprofile/health/pom.xml index 047254d1785..dec858fb5f7 100644 --- a/appserver/microprofile/health/pom.xml +++ b/appserver/microprofile/health/pom.xml @@ -23,7 +23,7 @@ org.glassfish.main.microprofile microprofile-parent - 7.0.19-SNAPSHOT + 7.0.20-SNAPSHOT microprofile-health diff --git a/appserver/tests/tck/microprofile/health/pom.xml b/appserver/tests/tck/microprofile/health/pom.xml index 4c565e42976..59d7e3ceb55 100644 --- a/appserver/tests/tck/microprofile/health/pom.xml +++ b/appserver/tests/tck/microprofile/health/pom.xml @@ -23,7 +23,7 @@ org.glassfish.main.tests.tck glassfish-external-tck-microprofile - 7.0.19-SNAPSHOT + 7.0.20-SNAPSHOT glassfish-external-tck-microprofile-health From 9bea997681f30bd99ea788a63858b5460544cde4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Tue, 5 Nov 2024 11:27:15 -0300 Subject: [PATCH 19/28] CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner From 4f2fc1ed8b4cc99ab56060bd277aba53972e503b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Fri, 8 Nov 2024 16:21:24 -0300 Subject: [PATCH 20/28] Remove unused internal dependencies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- appserver/microprofile/health/pom.xml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/appserver/microprofile/health/pom.xml b/appserver/microprofile/health/pom.xml index dec858fb5f7..bf29c91b3c6 100644 --- a/appserver/microprofile/health/pom.xml +++ b/appserver/microprofile/health/pom.xml @@ -50,23 +50,6 @@ jakarta.json.bind jakarta.json.bind-api - - - - org.glassfish.main.common - glassfish-api - ${project.version} - - - org.glassfish.main.common - internal-api - ${project.version} - - - org.glassfish.main.web - weld-integration - ${project.version} - From 87035d17d119fddfc13194d4926d2eb17e07e3de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Fri, 8 Nov 2024 16:22:37 -0300 Subject: [PATCH 21/28] Avoid Impl suffix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- ...lderImpl.java => GlassFishHealthCheckResponseBuilder.java} | 2 +- ...derImpl.java => GlassFishHealthCheckResponseProvider.java} | 4 ++-- ...clipse.microprofile.health.spi.HealthCheckResponseProvider | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/{HealthCheckResponseBuilderImpl.java => GlassFishHealthCheckResponseBuilder.java} (96%) rename appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/{HealthCheckResponseProviderImpl.java => GlassFishHealthCheckResponseProvider.java} (86%) diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseBuilderImpl.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/GlassFishHealthCheckResponseBuilder.java similarity index 96% rename from appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseBuilderImpl.java rename to appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/GlassFishHealthCheckResponseBuilder.java index 477b4d44d9d..d55b63918a5 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseBuilderImpl.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/GlassFishHealthCheckResponseBuilder.java @@ -22,7 +22,7 @@ import org.eclipse.microprofile.health.HealthCheckResponse; import org.eclipse.microprofile.health.HealthCheckResponseBuilder; -public class HealthCheckResponseBuilderImpl extends HealthCheckResponseBuilder { +public class GlassFishHealthCheckResponseBuilder extends HealthCheckResponseBuilder { private final Map data = new HashMap<>(); private String name; diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseProviderImpl.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/GlassFishHealthCheckResponseProvider.java similarity index 86% rename from appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseProviderImpl.java rename to appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/GlassFishHealthCheckResponseProvider.java index c9070c1ed38..43089bf3959 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthCheckResponseProviderImpl.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/GlassFishHealthCheckResponseProvider.java @@ -18,9 +18,9 @@ import org.eclipse.microprofile.health.HealthCheckResponseBuilder; import org.eclipse.microprofile.health.spi.HealthCheckResponseProvider; -public class HealthCheckResponseProviderImpl implements HealthCheckResponseProvider { +public class GlassFishHealthCheckResponseProvider implements HealthCheckResponseProvider { @Override public HealthCheckResponseBuilder createResponseBuilder() { - return new HealthCheckResponseBuilderImpl(); + return new GlassFishHealthCheckResponseBuilder(); } } diff --git a/appserver/microprofile/health/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider b/appserver/microprofile/health/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider index 5979adc2230..667885a3511 100644 --- a/appserver/microprofile/health/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider +++ b/appserver/microprofile/health/src/main/resources/META-INF/services/org.eclipse.microprofile.health.spi.HealthCheckResponseProvider @@ -1 +1 @@ -org.glassfish.microprofile.health.HealthCheckResponseProviderImpl +org.glassfish.microprofile.health.GlassFishHealthCheckResponseProvider From 35bb75508b3b83e832444fed55587a2678b07c01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Fri, 8 Nov 2024 16:40:53 -0300 Subject: [PATCH 22/28] Add system property to allow disabling the Health servlet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../health/HealthServletInitializer.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java index 2ddfccbd985..4cea963d5e7 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java @@ -19,15 +19,26 @@ import jakarta.servlet.ServletContext; import java.util.Set; +import java.util.logging.Logger; public class HealthServletInitializer implements ServletContainerInitializer { + private static final String MICROPROFILE_HEALTH_SERVLET = "microprofile-health-servlet"; + private static final String MICROPROFILE_HEALTH_ENABLED = "org.glassfish.microprofile.health.enabled"; + private static final Logger LOGGER = Logger.getLogger(HealthServletInitializer.class.getName()); + @Override public void onStartup(Set> set, ServletContext servletContext) { if (servletContext.getContextPath().isEmpty()) { return; } - servletContext.addServlet("health", HealthServlet.class) + + if (!Boolean.parseBoolean(System.getProperty(MICROPROFILE_HEALTH_ENABLED, "true"))) { + LOGGER.info("MicroProfile Health is disabled"); + return; + } + + servletContext.addServlet(MICROPROFILE_HEALTH_SERVLET, HealthServlet.class) .addMapping("/health", "/health/live", "/health/ready", "/health/started"); } } From 96528c961186972099d65ccd9796203508821297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Wed, 4 Dec 2024 12:33:30 -0300 Subject: [PATCH 23/28] Split Health implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- appserver/featuresets/glassfish/pom.xml | 11 ++ .../microprofile/health-glassfish/pom.xml | 89 ++++++++++++ .../impl/CollectHealthChecksExtension.java | 72 ++++++++++ .../microprofile/impl/HealthService.java | 31 +++++ .../microprofile/impl/HealthServlet.java | 72 ++++++++++ .../impl}/HealthServletInitializer.java | 4 +- .../jakarta.enterprise.inject.spi.Extension | 1 + ...akarta.servlet.ServletContainerInitializer | 1 + appserver/microprofile/health/pom.xml | 12 +- .../health/{Output.java => HealthReport.java} | 2 +- ...HealthServlet.java => HealthReporter.java} | 131 ++++++++++-------- ...akarta.servlet.ServletContainerInitializer | 1 - appserver/microprofile/pom.xml | 1 + .../health/tck/HealthArquillianExtension.java | 7 + .../tck/client/BeansXmlTransformer.java | 110 +++++++++++++++ .../tck/client/RootResourceProvider.java | 26 ++++ .../health/src/main/resources/beans.xml | 4 + 17 files changed, 503 insertions(+), 72 deletions(-) create mode 100644 appserver/microprofile/health-glassfish/pom.xml create mode 100644 appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java create mode 100644 appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java create mode 100644 appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServlet.java rename appserver/microprofile/{health/src/main/java/org/glassfish/microprofile/health => health-glassfish/src/main/java/org/glassfish/microprofile/impl}/HealthServletInitializer.java (94%) create mode 100644 appserver/microprofile/health-glassfish/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension create mode 100644 appserver/microprofile/health-glassfish/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer rename appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/{Output.java => HealthReport.java} (89%) rename appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/{HealthServlet.java => HealthReporter.java} (50%) delete mode 100644 appserver/microprofile/health/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer create mode 100644 appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java create mode 100644 appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/RootResourceProvider.java create mode 100644 appserver/tests/tck/microprofile/health/src/main/resources/beans.xml diff --git a/appserver/featuresets/glassfish/pom.xml b/appserver/featuresets/glassfish/pom.xml index b6055b36bbd..f14e8f0a061 100644 --- a/appserver/featuresets/glassfish/pom.xml +++ b/appserver/featuresets/glassfish/pom.xml @@ -862,6 +862,17 @@ + + org.glassfish.main.microprofile + health-glassfish + ${project.version} + + + * + * + + + diff --git a/appserver/microprofile/health-glassfish/pom.xml b/appserver/microprofile/health-glassfish/pom.xml new file mode 100644 index 00000000000..9ca98ade044 --- /dev/null +++ b/appserver/microprofile/health-glassfish/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + + + org.glassfish.main.microprofile + microprofile-parent + 7.0.20-SNAPSHOT + + + health-glassfish + glassfish-jar + + + UTF-8 + 17 + + + + + org.glassfish.main.microprofile + microprofile-health + ${project.version} + provided + + + jakarta.json.bind + jakarta.json.bind-api + provided + + + jakarta.enterprise + jakarta.enterprise.cdi-api + provided + + + + + + + maven-compiler-plugin + + 17 + + + + org.apache.felix + maven-bundle-plugin + + + glassfish-jar + + + + + org.glassfish.microprofile.impl; + + + jakarta.enterprise.context.spi; + jakarta.enterprise.event; + jakarta.enterprise.inject; + jakarta.enterprise.inject.spi; + jakarta.json.bind; + jakarta.servlet; + jakarta.servlet.http; + org.eclipse.microprofile.health; + org.glassfish.internal.api; + org.glassfish.microprofile.health; + org.glassfish.hk2.api; + org.glassfish.hk2.utilities; + + + + + + osgi-bundle + package + + bundle + + + + + + + + \ No newline at end of file diff --git a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java new file mode 100644 index 00000000000..bbfd01ac60d --- /dev/null +++ b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Contributors to Eclipse Foundation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.microprofile.impl; + +import jakarta.enterprise.context.spi.CreationalContext; +import jakarta.enterprise.event.Observes; +import jakarta.enterprise.inject.spi.*; + +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import jakarta.servlet.ServletContext; +import org.eclipse.microprofile.health.HealthCheck; +import org.eclipse.microprofile.health.Liveness; +import org.eclipse.microprofile.health.Readiness; +import org.eclipse.microprofile.health.Startup; +import org.glassfish.hk2.api.MultiException; +import org.glassfish.hk2.api.ServiceLocator; +import org.glassfish.hk2.utilities.ServiceLocatorUtilities; +import org.glassfish.internal.api.Globals; +import org.glassfish.microprofile.health.HealthReporter; + + +public class CollectHealthChecksExtension implements Extension { + + private final HealthReporter service; + private final Set> healthChecks = Collections.newSetFromMap(new ConcurrentHashMap<>()); + + public CollectHealthChecksExtension() { + ServiceLocator defaultBaseServiceLocator = Globals.getDefaultBaseServiceLocator(); + HealthReporter healthReporterService = defaultBaseServiceLocator.getService(HealthReporter.class); + if (healthReporterService == null) { + ServiceLocatorUtilities.addClasses(defaultBaseServiceLocator, true, HealthReporter.class); + healthReporterService = defaultBaseServiceLocator.getService(HealthReporter.class); + } + service = healthReporterService; + } + public void processBeans(@Observes ProcessBean beans) { + Annotated annotated = beans.getAnnotated(); + if (annotated.isAnnotationPresent(Liveness.class) || + annotated.isAnnotationPresent(Readiness.class) || + annotated.isAnnotationPresent(Startup.class)) { + if (beans.getBean().getTypes().contains(HealthCheck.class)) { + healthChecks.add((Bean) beans.getBean()); + } + } + } + + public void afterDeploymentValidation(@Observes AfterDeploymentValidation adv, BeanManager beanManager) { + healthChecks.forEach(bean -> { + CreationalContext creationalContext = beanManager.createCreationalContext(bean); + service.addHealthCheck("", bean.create(creationalContext)); + }); + } + + + +} diff --git a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java new file mode 100644 index 00000000000..10d4a5853f7 --- /dev/null +++ b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java @@ -0,0 +1,31 @@ +package org.glassfish.microprofile.impl; + +import org.apache.catalina.Deployer; +import org.glassfish.api.StartupRunLevel; +import org.glassfish.api.event.EventListener; +import org.glassfish.hk2.runlevel.RunLevel; +import org.glassfish.internal.api.Globals; +import org.glassfish.internal.data.ApplicationInfo; +import org.glassfish.internal.deployment.Deployment; +import org.glassfish.microprofile.health.HealthReporter; +import org.jvnet.hk2.annotations.Service; + +@Service(name = "healthcheck-service") +@RunLevel(StartupRunLevel.VAL) +public class HealthService implements EventListener { + + + @Override + public void event(Event event) { + + HealthReporter service = Globals.getDefaultHabitat().getService(HealthReporter.class); + + if (event.is(Deployment.APPLICATION_UNLOADED) && event.hook() instanceof ApplicationInfo appInfo) { + service.removeAllHealthChecksFrom(appInfo.getName()); + } + + if (event.is(Deployment.APPLICATION_STARTED) && event.hook() instanceof ApplicationInfo appInfo) { + + } + } +} diff --git a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServlet.java b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServlet.java new file mode 100644 index 00000000000..805eb722ddc --- /dev/null +++ b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServlet.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024 Contributors to Eclipse Foundation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.microprofile.impl; + +import jakarta.json.bind.Jsonb; +import jakarta.json.bind.JsonbBuilder; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.eclipse.microprofile.health.HealthCheckResponse; +import org.glassfish.internal.api.Globals; +import org.glassfish.microprofile.health.HealthReport; +import org.glassfish.microprofile.health.HealthReporter; + +public class HealthServlet extends HttpServlet { + + private static final Logger LOGGER = Logger.getLogger(HealthServlet.class.getName()); + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + HealthReport healthReport; + try { + healthReport = Globals.getDefaultHabitat().getService(HealthReporter.class) + .getReport(getReportKind(req.getRequestURI())); + + int httpStatus = switch (healthReport.status()) { + case UP -> HttpServletResponse.SC_OK; + case DOWN -> HttpServletResponse.SC_SERVICE_UNAVAILABLE; + }; + resp.setStatus(httpStatus); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Unable to fetch health check status", e); + healthReport = new HealthReport(HealthCheckResponse.Status.DOWN, List.of()); + resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + + Jsonb jsonb = JsonbBuilder.create(); + String json = jsonb.toJson(healthReport); + resp.getWriter().println(json); + } + + private static HealthReporter.ReportKind getReportKind(String path) { + if (path.endsWith("health/live")) { + return HealthReporter.ReportKind.LIVE; + } else if (path.endsWith("health/ready")) { + return HealthReporter.ReportKind.READY; + } else if (path.endsWith("health/started")) { + return HealthReporter.ReportKind.STARTED; + } else { + return HealthReporter.ReportKind.ALL; + } + } +} diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServletInitializer.java similarity index 94% rename from appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java rename to appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServletInitializer.java index 4cea963d5e7..97512331836 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServletInitializer.java +++ b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServletInitializer.java @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 */ -package org.glassfish.microprofile.health; +package org.glassfish.microprofile.impl; import jakarta.servlet.ServletContainerInitializer; import jakarta.servlet.ServletContext; @@ -29,7 +29,7 @@ public class HealthServletInitializer implements ServletContainerInitializer { @Override public void onStartup(Set> set, ServletContext servletContext) { - if (servletContext.getContextPath().isEmpty()) { + if (!servletContext.getContextPath().isEmpty()) { return; } diff --git a/appserver/microprofile/health-glassfish/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension b/appserver/microprofile/health-glassfish/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension new file mode 100644 index 00000000000..9231f525d1b --- /dev/null +++ b/appserver/microprofile/health-glassfish/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension @@ -0,0 +1 @@ +org.glassfish.microprofile.impl.CollectHealthChecksExtension \ No newline at end of file diff --git a/appserver/microprofile/health-glassfish/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer b/appserver/microprofile/health-glassfish/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer new file mode 100644 index 00000000000..16a5f16529e --- /dev/null +++ b/appserver/microprofile/health-glassfish/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer @@ -0,0 +1 @@ +org.glassfish.microprofile.impl.HealthServletInitializer diff --git a/appserver/microprofile/health/pom.xml b/appserver/microprofile/health/pom.xml index bf29c91b3c6..73109947b93 100644 --- a/appserver/microprofile/health/pom.xml +++ b/appserver/microprofile/health/pom.xml @@ -45,10 +45,7 @@ jakarta.enterprise jakarta.enterprise.cdi-api - - - jakarta.json.bind - jakarta.json.bind-api + provided @@ -76,13 +73,10 @@ org.eclipse.microprofile.config; org.eclipse.microprofile.health.spi; org.eclipse.microprofile.health; - jakarta.enterprise.util; + jakarta.inject; + jakarta.enterprise.context; jakarta.enterprise.inject; jakarta.enterprise.inject.spi; - jakarta.servlet.http; - jakarta.servlet; - jakarta.json.bind; - jakarta.inject; diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReport.java similarity index 89% rename from appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java rename to appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReport.java index 0c861a647ba..b8c8f82242d 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/Output.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReport.java @@ -19,5 +19,5 @@ import org.eclipse.microprofile.health.HealthCheckResponse; -public record Output(HealthCheckResponse.Status status, List checks) { +public record HealthReport(HealthCheckResponse.Status status, List checks) { } diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReporter.java similarity index 50% rename from appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java rename to appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReporter.java index 0a035f78692..98100d44000 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthServlet.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReporter.java @@ -17,19 +17,18 @@ import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.spi.CDI; -import jakarta.json.bind.Jsonb; -import jakarta.json.bind.JsonbBuilder; -import jakarta.servlet.http.HttpServlet; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import java.io.IOException; +import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Stream; +import jakarta.inject.Singleton; import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.health.HealthCheck; import org.eclipse.microprofile.health.HealthCheckResponse; @@ -37,11 +36,14 @@ import org.eclipse.microprofile.health.Readiness; import org.eclipse.microprofile.health.Startup; -public class HealthServlet extends HttpServlet { +@Singleton +public class HealthReporter { private static final String MP_DEFAULT_STARTUP_EMPTY_RESPONSE = "mp.health.default.startup.empty.response"; private static final String MP_DEFAULT_READINESS_EMPTY_RESPONSE = "mp.health.default.readiness.empty.response"; - private static final Logger LOGGER = Logger.getLogger(HealthServlet.class.getName()); + private static final Logger LOGGER = Logger.getLogger(HealthReporter.class.getName()); + + private final Map> applicationHealthChecks = new ConcurrentHashMap<>(); private static HealthCheckResponse callHealthCheck(HealthCheck healthCheck) { try { @@ -60,71 +62,81 @@ private static HealthCheckResponse buildHealthCheckResponse(String name, Excepti .build(); } - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { - Output output; - - try { - HealthCheckResponse.Status emptyResponse = HealthCheckResponse.Status.UP; + public enum ReportKind { + LIVE, + READY, + STARTED, + ALL; + private Stream healthChecks() { Instance select = CDI.current().select(HealthCheck.class); - Stream healthChecks; - String requestURI = req.getRequestURI(); - if (requestURI.endsWith("health/live")) { - healthChecks = select.select(Liveness.Literal.INSTANCE).stream(); - } else if (requestURI.endsWith("health/ready")) { - healthChecks = select.select(Readiness.Literal.INSTANCE).stream(); - emptyResponse = getValue(MP_DEFAULT_READINESS_EMPTY_RESPONSE) - .orElse(HealthCheckResponse.Status.DOWN); - - } else if (requestURI.endsWith("health/started")) { - healthChecks = select.select(Startup.Literal.INSTANCE).stream(); - emptyResponse = getValue(MP_DEFAULT_STARTUP_EMPTY_RESPONSE) - .orElse(HealthCheckResponse.Status.DOWN); - } else { - healthChecks = Stream.of( + return switch (this) { + case LIVE -> select.select(Liveness.Literal.INSTANCE).stream(); + case READY -> select.select(Readiness.Literal.INSTANCE).stream(); + case STARTED -> select.select(Startup.Literal.INSTANCE).stream(); + case ALL -> Stream.of( select.select(Liveness.Literal.INSTANCE).stream(), select.select(Readiness.Literal.INSTANCE).stream(), select.select(Startup.Literal.INSTANCE).stream() ).flatMap(s -> s); - } - - - List healthCheckResults = healthChecks - .map(HealthServlet::callHealthCheck) - .toList(); + }; + } - HealthCheckResponse.Status overallStatus; - if (healthCheckResults.isEmpty()) { - overallStatus = emptyResponse; - } else { - overallStatus = healthCheckResults.stream() - .map(HealthCheckResponse::getStatus) - .filter(HealthCheckResponse.Status.DOWN::equals) - .findFirst() + private HealthCheckResponse.Status getEmptyResponse() { + return switch (this) { + case LIVE -> getValue(MP_DEFAULT_STARTUP_EMPTY_RESPONSE) .orElse(HealthCheckResponse.Status.UP); - } - output = new Output(overallStatus, healthCheckResults); - - int httpStatus = switch (overallStatus) { - case UP -> HttpServletResponse.SC_OK; - case DOWN -> HttpServletResponse.SC_SERVICE_UNAVAILABLE; + case READY -> getValue(MP_DEFAULT_READINESS_EMPTY_RESPONSE) + .orElse(HealthCheckResponse.Status.UP); + case STARTED, ALL -> HealthCheckResponse.Status.UP; }; - resp.setStatus(httpStatus); - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Unable to fetch health check status", e); - output = new Output(HealthCheckResponse.Status.DOWN, List.of(buildHealthCheckResponse("error", e))); - resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } + } + + public HealthReport getReport(ReportKind reportKind) { + HealthCheckResponse.Status emptyResponse = HealthCheckResponse.Status.UP; + + Stream healthChecks = applicationHealthChecks.values() + .stream() + .flatMap(Collection::stream); +// Stream.concat(reportKind.healthChecks(), applicationHealthChecks.stream()); + + List healthCheckResults = healthChecks + .map(HealthReporter::callHealthCheck) + .toList(); + + HealthCheckResponse.Status overallStatus; + if (healthCheckResults.isEmpty()) { + overallStatus = emptyResponse; + } else { + overallStatus = healthCheckResults.stream() + .map(HealthCheckResponse::getStatus) + .filter(HealthCheckResponse.Status.DOWN::equals) + .findFirst() + .orElse(HealthCheckResponse.Status.UP); + } + return new HealthReport(overallStatus, healthCheckResults); + + } + - Jsonb jsonb = JsonbBuilder.create(); - String json = jsonb.toJson(output); - resp.getWriter().println(json); + public void addHealthCheck(String contextPath, HealthCheck healthCheck) { + applicationHealthChecks.computeIfAbsent(contextPath, k -> new CopyOnWriteArrayList<>()) + .add(healthCheck); +// applicationHealthChecks.add(healthCheck); } - private Optional getValue(String value) { + public void removeHealthCheck(String contextPath, HealthCheck healthCheck) { + applicationHealthChecks.get(contextPath).remove(healthCheck); + } + + public void removeAllHealthChecksFrom(String contextPath) { + applicationHealthChecks.remove(contextPath); + } + + private static Optional getValue(String value) { try { - return ConfigProvider.getConfig(getServletContext().getClassLoader()) + return ConfigProvider.getConfig() .getOptionalValue(value, String.class) .map(HealthCheckResponse.Status::valueOf); } catch (IllegalStateException e) { @@ -132,4 +144,5 @@ private Optional getValue(String value) { return Optional.empty(); } } + } diff --git a/appserver/microprofile/health/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer b/appserver/microprofile/health/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer deleted file mode 100644 index 3ee851e806c..00000000000 --- a/appserver/microprofile/health/src/main/resources/META-INF/services/jakarta.servlet.ServletContainerInitializer +++ /dev/null @@ -1 +0,0 @@ -org.glassfish.microprofile.health.HealthServletInitializer diff --git a/appserver/microprofile/pom.xml b/appserver/microprofile/pom.xml index 56711589963..0b37dd9f1d5 100644 --- a/appserver/microprofile/pom.xml +++ b/appserver/microprofile/pom.xml @@ -35,6 +35,7 @@ config health + health-glassfish connectors diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java index fdf4d2e1f0f..93cfa62f457 100644 --- a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/HealthArquillianExtension.java @@ -15,13 +15,18 @@ */ package org.glassfish.microprofile.health.tck; +import java.net.URI; import java.util.logging.Logger; +import org.glassfish.microprofile.health.tck.client.BeansXmlTransformer; import org.glassfish.microprofile.health.tck.client.ConfigDeploymentExceptionTransformer; import org.glassfish.microprofile.health.tck.client.MicroProfileConfigPropertiesTransformer; +import org.glassfish.microprofile.health.tck.client.RootResourceProvider; import org.jboss.arquillian.container.spi.client.container.DeploymentExceptionTransformer; +import org.jboss.arquillian.container.test.impl.enricher.resource.URIResourceProvider; import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; import org.jboss.arquillian.core.spi.LoadableExtension; +import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider; public class HealthArquillianExtension implements LoadableExtension { @@ -36,7 +41,9 @@ public void register(ExtensionBuilder extensionBuilder) { LOGGER.info("Client Arquillian extension registered"); + extensionBuilder.service(ApplicationArchiveProcessor.class, BeansXmlTransformer.class); extensionBuilder.service(ApplicationArchiveProcessor.class, MicroProfileConfigPropertiesTransformer.class); extensionBuilder.service(DeploymentExceptionTransformer.class, ConfigDeploymentExceptionTransformer.class); + extensionBuilder.override(ResourceProvider.class, URIResourceProvider.class, RootResourceProvider.class); } } diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java new file mode 100644 index 00000000000..a6624d7c4ce --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/BeansXmlTransformer.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2022 Contributors to Eclipse Foundation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0, which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception, which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + */ +package org.glassfish.microprofile.health.tck.client; + +import org.jboss.arquillian.container.spi.event.container.BeforeDeploy; +import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; +import org.jboss.arquillian.core.api.annotation.Observes; +import org.jboss.arquillian.test.spi.TestClass; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ArchivePath; +import org.jboss.shrinkwrap.api.Node; +import org.jboss.shrinkwrap.api.asset.ArchiveAsset; +import org.jboss.shrinkwrap.api.asset.UrlAsset; + +import java.net.URL; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.logging.Logger; + +import static java.lang.String.format; + +/** + * This extension replaces beans.xml files with ones declaring the 'all' bean discovery type. + * This is because version 3.0.1 of the TCK still deploys an empty beans.xml due to a faulty assumption that + * CDI < 4 is still defaulting to the 'all' type. + */ +public class BeansXmlTransformer implements ApplicationArchiveProcessor { + + private static final Logger LOGGER = Logger.getLogger(BeansXmlTransformer.class.getName()); + + private static final String LIB_DIR_PATH = format("WEB-INF%slib", ArchivePath.SEPARATOR); + private static final String[] BEANS_XML_PATHS = { + format("/META-INF%sbeans.xml", ArchivePath.SEPARATOR), + format("/WEB-INF%sbeans.xml", ArchivePath.SEPARATOR), + }; + + private final URL beansXmlResource; + + public BeansXmlTransformer() { + this.beansXmlResource = getClass().getClassLoader().getResource("beans.xml"); + if (beansXmlResource == null) { + throw new IllegalStateException("Unable to find beans.xml resource in test dir"); + } + } + + /** + * Listen for and process non-testable deployments. This is required as, by default, ShouldThrowException annotated + * deployments aren't processed by ApplicationArchiveProcessors, but the beans xml may still need fixing. + * @param event + */ + protected void onEvent(@Observes BeforeDeploy event) { + final var deployment = event.getDeployment(); + + if (!deployment.testable()) { + new BeansXmlTransformer().process(deployment.getArchive()); + } + } + + @Override + public void process(Archive archive, TestClass testClass) { + process(archive); + } + + public void process(Archive archive) { + findBeansXml(archive) + .ifPresent(beansXml -> { + LOGGER.info(() -> format("Replacing beans.xml in archive [%s]", archive.getName())); + archive.add(new UrlAsset(beansXmlResource), beansXml.getPath()); + }); + processLibraries(archive, this::process); + } + + private static Optional findBeansXml(Archive archive) { + for (String beansXmlPath : BEANS_XML_PATHS) { + final var node = archive.get(beansXmlPath); + if (node != null) { + LOGGER.info(() -> format("Discovered beans.xml at path [%s]", node.getPath())); + return Optional.of(node); + } + } + return Optional.empty(); + } + + private static void processLibraries(Archive archive, Consumer> consumer) { + final var libDir = archive.get(LIB_DIR_PATH); + + if (libDir != null) { + for (var node : libDir.getChildren()) { + final var asset = node.getAsset(); + if (asset instanceof ArchiveAsset) { + LOGGER.info(() -> format("Processing subarchive [%s]", node.getPath())); + consumer.accept(((ArchiveAsset) asset).getArchive()); + } + } + } + } +} diff --git a/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/RootResourceProvider.java b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/RootResourceProvider.java new file mode 100644 index 00000000000..54fb7d3d819 --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/java/org/glassfish/microprofile/health/tck/client/RootResourceProvider.java @@ -0,0 +1,26 @@ +package org.glassfish.microprofile.health.tck.client; + +import org.jboss.arquillian.container.test.impl.enricher.resource.URIResourceProvider; +import org.jboss.arquillian.test.api.ArquillianResource; + +import java.lang.annotation.Annotation; +import java.net.URI; +import java.net.URISyntaxException; + +public class RootResourceProvider extends URIResourceProvider { + + @Override + public Object lookup(ArquillianResource arquillianResource, Annotation... annotations) { + Object lookup = super.lookup(arquillianResource, annotations); + // remove the context path from the URI + if (lookup instanceof URI) { + URI uri = (URI) lookup; + try { + return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(), "", uri.getQuery(), uri.getFragment()); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + return null; + } +} diff --git a/appserver/tests/tck/microprofile/health/src/main/resources/beans.xml b/appserver/tests/tck/microprofile/health/src/main/resources/beans.xml new file mode 100644 index 00000000000..eea1bce2d91 --- /dev/null +++ b/appserver/tests/tck/microprofile/health/src/main/resources/beans.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file From c1355d9ab31e7b5bed461345ed544a7368a8577e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Thu, 5 Dec 2024 08:47:52 -0300 Subject: [PATCH 24/28] Update version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- appserver/microprofile/health-glassfish/pom.xml | 2 +- appserver/microprofile/health/pom.xml | 2 +- appserver/tests/tck/microprofile/health/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/appserver/microprofile/health-glassfish/pom.xml b/appserver/microprofile/health-glassfish/pom.xml index 9ca98ade044..c52dd917137 100644 --- a/appserver/microprofile/health-glassfish/pom.xml +++ b/appserver/microprofile/health-glassfish/pom.xml @@ -7,7 +7,7 @@ org.glassfish.main.microprofile microprofile-parent - 7.0.20-SNAPSHOT + 7.0.21-SNAPSHOT health-glassfish diff --git a/appserver/microprofile/health/pom.xml b/appserver/microprofile/health/pom.xml index 73109947b93..4967748940a 100644 --- a/appserver/microprofile/health/pom.xml +++ b/appserver/microprofile/health/pom.xml @@ -23,7 +23,7 @@ org.glassfish.main.microprofile microprofile-parent - 7.0.20-SNAPSHOT + 7.0.21-SNAPSHOT microprofile-health diff --git a/appserver/tests/tck/microprofile/health/pom.xml b/appserver/tests/tck/microprofile/health/pom.xml index 59d7e3ceb55..8196030ec3b 100644 --- a/appserver/tests/tck/microprofile/health/pom.xml +++ b/appserver/tests/tck/microprofile/health/pom.xml @@ -23,7 +23,7 @@ org.glassfish.main.tests.tck glassfish-external-tck-microprofile - 7.0.20-SNAPSHOT + 7.0.21-SNAPSHOT glassfish-external-tck-microprofile-health From 67e74ef70f0aa8b6df25df41f40398096e10b235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Sat, 28 Dec 2024 16:58:38 -0300 Subject: [PATCH 25/28] Fix imports --- .../java/org/glassfish/microprofile/health/HealthReporter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReporter.java b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReporter.java index 98100d44000..388b491eb77 100644 --- a/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReporter.java +++ b/appserver/microprofile/health/src/main/java/org/glassfish/microprofile/health/HealthReporter.java @@ -17,6 +17,7 @@ import jakarta.enterprise.inject.Instance; import jakarta.enterprise.inject.spi.CDI; +import jakarta.inject.Singleton; import java.util.Collection; import java.util.List; @@ -28,7 +29,6 @@ import java.util.logging.Logger; import java.util.stream.Stream; -import jakarta.inject.Singleton; import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.health.HealthCheck; import org.eclipse.microprofile.health.HealthCheckResponse; From f629daaf2e9517a6a170df716d6240887c2939c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Sat, 28 Dec 2024 17:19:26 -0300 Subject: [PATCH 26/28] Fix imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../impl/CollectHealthChecksExtension.java | 10 +++++++--- .../org/glassfish/microprofile/impl/HealthService.java | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java index bbfd01ac60d..b7524b22911 100644 --- a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java +++ b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java @@ -17,18 +17,22 @@ import jakarta.enterprise.context.spi.CreationalContext; import jakarta.enterprise.event.Observes; -import jakarta.enterprise.inject.spi.*; +import jakarta.enterprise.inject.spi.AfterDeploymentValidation; +import jakarta.enterprise.inject.spi.Annotated; +import jakarta.enterprise.inject.spi.Bean; +import jakarta.enterprise.inject.spi.BeanManager; +import jakarta.enterprise.inject.spi.Extension; +import jakarta.enterprise.inject.spi.ProcessBean; import java.util.Collections; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import jakarta.servlet.ServletContext; import org.eclipse.microprofile.health.HealthCheck; import org.eclipse.microprofile.health.Liveness; import org.eclipse.microprofile.health.Readiness; import org.eclipse.microprofile.health.Startup; -import org.glassfish.hk2.api.MultiException; + import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.utilities.ServiceLocatorUtilities; import org.glassfish.internal.api.Globals; diff --git a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java index 10d4a5853f7..5f4b885f43a 100644 --- a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java +++ b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java @@ -1,6 +1,6 @@ package org.glassfish.microprofile.impl; -import org.apache.catalina.Deployer; + import org.glassfish.api.StartupRunLevel; import org.glassfish.api.event.EventListener; import org.glassfish.hk2.runlevel.RunLevel; @@ -8,6 +8,7 @@ import org.glassfish.internal.data.ApplicationInfo; import org.glassfish.internal.deployment.Deployment; import org.glassfish.microprofile.health.HealthReporter; + import org.jvnet.hk2.annotations.Service; @Service(name = "healthcheck-service") From f3052c6d43bf4b5304d842d4325e8ca51d520f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thiago=20Henrique=20H=C3=BCpner?= Date: Sat, 28 Dec 2024 17:56:44 -0300 Subject: [PATCH 27/28] Fix imports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Thiago Henrique Hüpner --- .../microprofile/impl/CollectHealthChecksExtension.java | 1 - .../main/java/org/glassfish/microprofile/impl/HealthService.java | 1 - 2 files changed, 2 deletions(-) diff --git a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java index b7524b22911..7c95b2f2453 100644 --- a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java +++ b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/CollectHealthChecksExtension.java @@ -32,7 +32,6 @@ import org.eclipse.microprofile.health.Liveness; import org.eclipse.microprofile.health.Readiness; import org.eclipse.microprofile.health.Startup; - import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.utilities.ServiceLocatorUtilities; import org.glassfish.internal.api.Globals; diff --git a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java index 5f4b885f43a..355d2c02f1d 100644 --- a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java +++ b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthService.java @@ -8,7 +8,6 @@ import org.glassfish.internal.data.ApplicationInfo; import org.glassfish.internal.deployment.Deployment; import org.glassfish.microprofile.health.HealthReporter; - import org.jvnet.hk2.annotations.Service; @Service(name = "healthcheck-service") From eb5af304929074ffd70c4c61c6ae1979c850c741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ondro=20Mih=C3=A1lyi?= Date: Wed, 1 Jan 2025 00:54:19 +0100 Subject: [PATCH 28/28] Set content type and encoding for health response body --- .../java/org/glassfish/microprofile/impl/HealthServlet.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServlet.java b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServlet.java index 805eb722ddc..d3c3a533714 100644 --- a/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServlet.java +++ b/appserver/microprofile/health-glassfish/src/main/java/org/glassfish/microprofile/impl/HealthServlet.java @@ -55,6 +55,8 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IO Jsonb jsonb = JsonbBuilder.create(); String json = jsonb.toJson(healthReport); + resp.setCharacterEncoding("UTF-8"); + resp.setContentType("application/json"); resp.getWriter().println(json); }