-
Notifications
You must be signed in to change notification settings - Fork 129
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[UNOMI-854] Add a HealthCheck Endpoint (#698)
* UNOMI-854: Add a healthcheck extension * UNOMI-854: Add configuration to healthcheck * UNOMI-854: Integrate authentication for servlet using JAAS and realm config * UNOMI-854: Add documentation (javadoc and adoc) for the healthcheck extension * UNOMI-854: Include Integration Test * UNOMI-854: Change log level to debug for some unrelevant runtime logs, add timeout default response, add exception details in logs. * UNOMI-853: Avoid using 2 testsuite because of conflict. * UNOMI-854: Add a healthcheck extension * UNOMI-854: Add configuration to healthcheck * UNOMI-854: Integrate authentication for servlet using JAAS and realm config * UNOMI-854: Include Integration Test * UNOMI-854: Update config capabilities, use code 206 when all checks are not LIVE, fix order of checks. * UNOMI-854: Include small value cache to ensure better memory consumption and avoid DoS. * UNOMI-854: Missed test suite removal.
- Loading branch information
Showing
23 changed files
with
1,730 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
# Health Check Extension | ||
|
||
The Health Check extension provides a simple health check endpoint that can be used to determine if the server is up and running. | ||
The health check endpoint is available at | ||
|
||
``` | ||
/health/check | ||
``` | ||
and returns a simple JSON response that includes all health check provider responses. | ||
|
||
Basic Http Authentication is enabled by default for the health check endpoint. The user needs to have the role `health` to access the endpoint. Users and roles can be configured in the etc/users.properties file. By default a user health/health is configured. | ||
|
||
The healthcheck is available even if unomi is not started. It gives health information about : | ||
- Karaf (as soon as the karaf container is started) | ||
- Elasticsearch (connection to elasticsearch cluster and its health) | ||
- Unomi (unomi bundles status) | ||
- Persistence (unomi to elasticsearch binding) | ||
- Cluster health (unomi cluster status and nodes information) | ||
|
||
All healthcheck can have a status : | ||
- DOWN (service is not available) | ||
- UP (service is up but does not respond to request (starting or misconfigured)) | ||
- LIVE (service is ready to serve request) | ||
- ERROR (an error occurred during service health check) | ||
|
||
Any subsystem health check have a timeout of 500ms where check is cancelled and will be returned as error. | ||
|
||
Typical response to /health/check when unomi NOT started is : | ||
|
||
```json | ||
[ | ||
{ | ||
"name":"karaf", | ||
"status":"LIVE", | ||
"collectingTime":0 | ||
}, | ||
{ | ||
"name":"cluster", | ||
"status":"DOWN", | ||
"collectingTime":0 | ||
}, | ||
{ | ||
"name":"elasticsearch", | ||
"status":"LIVE", | ||
"collectingTime":6 | ||
}, | ||
{ | ||
"name":"persistence", | ||
"status":"DOWN", | ||
"collectingTime":0 | ||
}, | ||
{ | ||
"name":"unomi", | ||
"status":"DOWN", | ||
"collectingTime":0 | ||
} | ||
] | ||
``` | ||
|
||
## Configuration | ||
|
||
Configuration is located in the file etc/org.apache.unomi.healthcheck.cfg | ||
|
||
Extension can be disabled by setting the property `enabled` to `false`. An environment variable can be used to set this property : UNOMI_HEALTHCHECK_ENABLED | ||
|
||
By default, all healthcheck providers are included but the list of those included providers can be customized by setting the property `providers` with a comma separated list of provider names. An environment variable can be used to set this property : UNOMI_HEALTHCHECK_PROVIDERS | ||
|
||
The timeout used for each health check can be set by setting the property `timeout` to the desired value in milliseconds. An environment variable can be used to set this property : UNOMI_HEALTHCHECK_TIMEOUT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
~ Licensed to the Apache Software Foundation (ASF) under one or more | ||
~ contributor license agreements. See the NOTICE file distributed with | ||
~ this work for additional information regarding copyright ownership. | ||
~ The ASF licenses this file to You under the Apache License, Version 2.0 | ||
~ (the "License"); you may not use this file except in compliance with | ||
~ the License. You may obtain a copy of the License at | ||
~ | ||
~ http://www.apache.org/licenses/LICENSE-2.0 | ||
~ | ||
~ Unless required by applicable law or agreed to in writing, software | ||
~ distributed under the License is distributed on an "AS IS" BASIS, | ||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
~ See the License for the specific language governing permissions and | ||
~ limitations under the License. | ||
--> | ||
|
||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>org.apache.unomi</groupId> | ||
<artifactId>unomi-extensions</artifactId> | ||
<version>2.6.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>healthcheck</artifactId> | ||
<name>Apache Unomi :: Extensions :: HealthCheck</name> | ||
<description>Apache Unomi HealthCheck extension that provide liveliness information about unomi</description> | ||
<packaging>bundle</packaging> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.apache.unomi</groupId> | ||
<artifactId>unomi-api</artifactId> | ||
<version>${project.version}</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.unomi</groupId> | ||
<artifactId>unomi-lifecycle-watcher</artifactId> | ||
<version>${project.version}</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.unomi</groupId> | ||
<artifactId>unomi-persistence-spi</artifactId> | ||
<version>${project.version}</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.unomi</groupId> | ||
<artifactId>shell-commands</artifactId> | ||
<version>${project.version}</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>javax.servlet</groupId> | ||
<artifactId>javax.servlet-api</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.osgi</groupId> | ||
<artifactId>osgi.cmpn</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.httpcomponents</groupId> | ||
<artifactId>httpclient-osgi</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.httpcomponents</groupId> | ||
<artifactId>httpcore-osgi</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.fasterxml.jackson.jaxrs</groupId> | ||
<artifactId>jackson-jaxrs-json-provider</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.karaf.jaas</groupId> | ||
<artifactId>org.apache.karaf.jaas.boot</artifactId> | ||
<version>${karaf.version}</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.felix</groupId> | ||
<artifactId>maven-bundle-plugin</artifactId> | ||
<extensions>true</extensions> | ||
<configuration> | ||
<instructions> | ||
<Embed-Dependency>*;scope=compile|runtime</Embed-Dependency> | ||
<Import-Package> | ||
sun.misc;resolution:=optional, | ||
* | ||
</Import-Package> | ||
<Export-Package> | ||
org.apache.unomi.healthcheck;version=${project.version}, | ||
org.osgi.service.useradmin;version=1.1.0 | ||
</Export-Package> | ||
<_dsannotations> | ||
org.apache.unomi.healthcheck.*, | ||
org.apache.unomi.healthcheck.provider.*, | ||
org.apache.unomi.healthcheck.servlet.*, | ||
</_dsannotations> | ||
</instructions> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>org.codehaus.mojo</groupId> | ||
<artifactId>build-helper-maven-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<id>attach-artifacts</id> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>attach-artifact</goal> | ||
</goals> | ||
<configuration> | ||
<artifacts> | ||
<artifact> | ||
<file> | ||
src/main/resources/org.apache.unomi.healthcheck.cfg | ||
</file> | ||
<type>cfg</type> | ||
<classifier>healthcheck</classifier> | ||
</artifact> | ||
</artifacts> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
95 changes: 95 additions & 0 deletions
95
extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/HealthCheckConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.apache.unomi.healthcheck; | ||
|
||
import org.osgi.service.component.annotations.Activate; | ||
import org.osgi.service.component.annotations.Component; | ||
import org.osgi.service.component.annotations.Modified; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
/** | ||
* Health check configuration. | ||
*/ | ||
@Component(immediate = true, service = HealthCheckConfig.class, configurationPid = {"org.apache.unomi.healthcheck"}) | ||
public class HealthCheckConfig { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(HealthCheckConfig.class.getName()); | ||
|
||
public static final String CONFIG_ES_ADDRESSES = "esAddresses"; | ||
public static final String CONFIG_ES_SSL_ENABLED = "esSSLEnabled"; | ||
public static final String CONFIG_ES_LOGIN = "esLogin"; | ||
public static final String CONFIG_ES_PASSWORD = "esPassword"; | ||
public static final String CONFIG_TRUST_ALL_CERTIFICATES = "httpClient.trustAllCertificates"; | ||
public static final String CONFIG_AUTH_REALM = "authentication.realm"; | ||
public static final String ENABLED = "healthcheck.enabled"; | ||
public static final String PROVIDERS = "healthcheck.providers"; | ||
public static final String TIMEOUT = "healthcheck.timeout"; | ||
|
||
private Map<String, String> config = new HashMap<>(); | ||
private boolean enabled = true; | ||
private List<String> enabledProviders = new ArrayList<>(); | ||
private int timeout = 400; | ||
|
||
@Activate | ||
@Modified | ||
public void modified(Map<String, String> config) { | ||
LOGGER.info("Updating healthcheck configuration, config size: {}", config.size()); | ||
this.setConfig(config); | ||
this.setEnabled(config.getOrDefault(ENABLED, "true").equalsIgnoreCase("true")); | ||
this.setEnabledProviders(config.getOrDefault(PROVIDERS, "").isEmpty() ? new ArrayList<>() : List.of(config.get(PROVIDERS).split(","))); | ||
this.setTimeout(Integer.parseInt(config.getOrDefault(TIMEOUT, "400"))); | ||
} | ||
|
||
public String get(String configKey) { | ||
return this.config.get(configKey); | ||
} | ||
|
||
public boolean isEnabled() { | ||
return enabled; | ||
} | ||
|
||
public List<String> getEnabledProviders() { | ||
return enabledProviders; | ||
} | ||
|
||
public int getTimeout() { | ||
return timeout; | ||
} | ||
|
||
public void setConfig(Map<String, String> config) { | ||
this.config = config; | ||
} | ||
|
||
public void setEnabled(boolean enabled) { | ||
this.enabled = enabled; | ||
} | ||
|
||
public void setEnabledProviders(List<String> enabledProviders) { | ||
this.enabledProviders = enabledProviders; | ||
} | ||
|
||
public void setTimeout(int timeout) { | ||
this.timeout = timeout; | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
extensions/healthcheck/src/main/java/org/apache/unomi/healthcheck/HealthCheckProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Licensed to the Apache Software Foundation (ASF) under one or more | ||
* contributor license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright ownership. | ||
* The ASF licenses this file to You under the Apache License, Version 2.0 | ||
* (the "License"); you may not use this file except in compliance with | ||
* the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.apache.unomi.healthcheck; | ||
|
||
public interface HealthCheckProvider { | ||
|
||
String name(); | ||
|
||
HealthCheckResponse execute(); | ||
|
||
default HealthCheckResponse timeout() { | ||
return new HealthCheckResponse.Builder().name(name()).withData("error.cause", "timeout").error().build(); | ||
} | ||
|
||
} |
Oops, something went wrong.