aboutsummaryrefslogtreecommitdiff
path: root/connector/src/main/java
diff options
context:
space:
mode:
authorThomas Lenz <thomas.lenz@egiz.gv.at>2021-01-07 20:03:54 +0100
committerThomas Lenz <thomas.lenz@egiz.gv.at>2021-01-07 20:03:54 +0100
commit278c8a6d1f0518dc9d0875dbec84614b19800d5d (patch)
treebc5d3ad07afec52610f8549b911d5dc03479248e /connector/src/main/java
parentb4e9b8810eb3020b7a013d323974f2de99de9b77 (diff)
downloadNational_eIDAS_Gateway-278c8a6d1f0518dc9d0875dbec84614b19800d5d.tar.gz
National_eIDAS_Gateway-278c8a6d1f0518dc9d0875dbec84614b19800d5d.tar.bz2
National_eIDAS_Gateway-278c8a6d1f0518dc9d0875dbec84614b19800d5d.zip
switch from custom monitoring to Spring-Actuator healthchecks
Diffstat (limited to 'connector/src/main/java')
-rw-r--r--connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java279
-rw-r--r--connector/src/main/java/at/asitplus/eidas/specific/connector/health/EidasNodeMetadataHealthIndicator.java69
-rw-r--r--connector/src/main/java/at/asitplus/eidas/specific/connector/health/Saml2MetadataHealthIndicator.java44
-rw-r--r--connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java11
-rw-r--r--connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java32
5 files changed, 144 insertions, 291 deletions
diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java
deleted file mode 100644
index f2d9fc8c..00000000
--- a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/MonitoringController.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright 2018 A-SIT Plus GmbH
- * AT-specific eIDAS Connector has been developed in a cooperation between EGIZ,
- * A-SIT Plus GmbH, A-SIT, and Graz University of Technology.
- *
- * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
- * the European Commission - subsequent versions of the EUPL (the "License");
- * You may not use this work except in compliance with the License.
- * You may obtain a copy of the License at:
- * https://joinup.ec.europa.eu/news/understanding-eupl-v12
- *
- * 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.
- *
- * This product combines work with different licenses. See the "NOTICE" text
- * file for details on the various modules and licenses.
- * The "NOTICE" text file is part of the distribution. Any derivative works
- * that you distribute must include a readable copy of the "NOTICE" text file.
-*/
-
-package at.asitplus.eidas.specific.connector.controller;
-
-import java.io.IOException;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.text.StringEscapeUtils;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.utils.URIBuilder;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-import at.asitplus.eidas.specific.connector.MsEidasNodeConstants;
-import at.gv.egiz.eaaf.core.api.data.EaafConstants;
-import at.gv.egiz.eaaf.core.api.idp.IConfigurationWithSP;
-import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
-import at.gv.egiz.eaaf.core.exceptions.EaafException;
-import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory;
-import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
-import at.gv.egiz.eaaf.core.impl.utils.Random;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration;
-import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory;
-import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder;
-import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
-
-@Controller
-public class MonitoringController {
- private static final Logger log = LoggerFactory.getLogger(MonitoringController.class);
-
- private static final String MESSAGE_OK = "OK";
- private static final String MESSAGE_ERROR = "ERROR";
- private static final String MESSAGE_SKIPPED = "SKIPPED";
-
- private static final String TEST_STORAGE = "Storage: ";
- private static final String TEST_CONFIG = "Config: ";
- private static final String TEST_PVPMETADATA = "PVP_metadata: ";
- private static final String TEST_EIDASNODEMETADATA = "eIDASNode_metadata: ";
-
- @Autowired
- private ITransactionStorage storage;
- @Autowired
- private IConfigurationWithSP config;
-
- @Autowired private IHttpClientFactory httpClientFactory;
-
- @Autowired
- private PvpMetadataBuilder metadatabuilder;
- @Autowired
- private IPvpMetadataConfigurationFactory configFactory;
- private AbstractCredentialProvider pvpIdpCredentials;
-
- /**
- * Sets a specific credential provider for PVP S-Profile IDP component.
- *
- * @param pvpIdpCredentials credential provider
- */
- public void setPvpIdpCredentials(AbstractCredentialProvider pvpIdpCredentials) {
- this.pvpIdpCredentials = pvpIdpCredentials;
-
- }
-
- /**
- * Generic exception handling that wrote an error-message to html response.
- *
- * @param resp Http response object
- * @param exception Error
- * @throws IOException In case of a html response error.
- */
- @ExceptionHandler({ Throwable.class })
- public void genericExceptionHandler(HttpServletResponse resp, Exception exception) throws IOException {
- log.error("Monitoring Servlet receives an error.", exception);
- resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8);
- resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- resp.getWriter().write("Reason: "
- + StringEscapeUtils.escapeHtml4(StringEscapeUtils.escapeEcmaScript(exception.getMessage())));
-
- }
-
- /**
- * MS-Connector status-monitoring end-point.
- *
- * @param req http request
- * @param resp http response
- * @throws IOException In case of a general processing error
- */
- @RequestMapping(value = { MsEidasNodeConstants.ENDPOINT_MONITORING_MONITOR },
- method = { RequestMethod.GET })
- public void startFullTest(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8);
-
- try {
- testConfig();
- testStorage();
- testPvpMetadata();
- testEidasNodeMetadata();
- resp.setStatus(HttpServletResponse.SC_OK);
- resp.getWriter().write(MESSAGE_OK);
-
- } catch (final Exception e) {
- resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- resp.getWriter().write(MESSAGE_ERROR);
-
- }
-
- }
-
- /**
- * MS-Connector internal verify monitoring end-point.
- *
- * @param req http request object
- * @param resp http response object
- * @throws IOException In case of an internal processing error
- */
- @RequestMapping(value = { MsEidasNodeConstants.ENDPOINT_MONITORING_VERIFY },
- method = { RequestMethod.GET })
-
- public void startSingleTests(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- String result = StringUtils.EMPTY;
- try {
- result += testConfig() + "<br>";
- } catch (final Exception e) {
- result += e.getMessage() + "<br>";
- }
-
- try {
- result += testStorage() + "<br>";
- } catch (final Exception e) {
- result += e.getMessage() + "<br>";
- }
-
- try {
- result += testPvpMetadata() + "<br>";
- } catch (final Exception e) {
- result += e.getMessage() + "<br>";
- }
-
- try {
- result += testEidasNodeMetadata() + "<br>";
- } catch (final Exception e) {
- result += e.getMessage() + "<br>";
- }
-
- resp.setContentType(EaafConstants.CONTENTTYPE_HTML_UTF8);
- resp.setStatus(HttpServletResponse.SC_OK);
- resp.getWriter().write(result);
-
- }
-
- private String testStorage() throws Exception {
- try {
- final String key = Random.nextHexRandom16();
- final String value = Random.nextHexRandom16();
-
- storage.put(key, value, -1);
- final String result = storage.get(key, String.class);
- storage.remove(key);
-
- if (result != null && result.equals(value)) {
- return TEST_STORAGE + MESSAGE_OK;
- } else {
- log.warn("Montioring: TestValue: " + value + " does NOT match in Storage test");
- }
-
- } catch (final EaafException e) {
- log.warn("Montioring: Can not read/write to storage.", e);
-
- }
-
- throw new Exception(TEST_STORAGE + MESSAGE_ERROR);
-
- }
-
- private String testConfig() throws Exception {
- try {
- if (config.getBasicConfigurationWithPrefix(MsEidasNodeConstants.PROP_CONFIG_SP_LIST_PREFIX) != null
- && config.getBasicConfigurationWithPrefix(MsEidasNodeConstants.PROP_CONFIG_SP_LIST_PREFIX)
- .size() > 0) {
- return TEST_CONFIG + MESSAGE_OK;
- } else {
- log.warn("Montioring: Can not read from configuration file.");
- }
-
- } catch (final Exception e) {
- log.warn("Montioring: Can not read from configuration file.", e);
- }
-
- throw new Exception(TEST_CONFIG + MESSAGE_ERROR);
-
- }
-
- private String testPvpMetadata() throws Exception {
- try {
- // build metadata
- final IPvpMetadataBuilderConfiguration metadataConfig =
- configFactory.generateMetadataBuilderConfiguration(
- "http://localhost/monitoring",
- pvpIdpCredentials);
- metadatabuilder.buildPvpMetadata(metadataConfig);
- return TEST_PVPMETADATA + MESSAGE_OK;
-
- } catch (Exception | TransformerFactoryConfigurationError e) {
- log.warn("Monitoring: Has an error in '" + TEST_PVPMETADATA + "': " + e.getMessage(), e);
- throw new Exception(TEST_PVPMETADATA + MESSAGE_ERROR, e);
-
- }
-
- }
-
- private String testEidasNodeMetadata() throws Exception {
- try {
- final String urlString = config.getBasicConfiguration(
- MsEidasNodeConstants.PROP_CONFIG_MONITORING_EIDASNODE_METADATAURL);
- if (StringUtils.isEmpty(urlString)) {
- log.debug("No eIDASNode metadata URL. Skipping test ... ");
- return TEST_EIDASNODEMETADATA + MESSAGE_SKIPPED;
-
- }
-
- // create HTTP client
- CloseableHttpClient httpClient = httpClientFactory.getHttpClient();
- URIBuilder uriBuilder = new URIBuilder(urlString);
- HttpUriRequest request = new HttpGet(uriBuilder.build());
-
- final CloseableHttpResponse respCode = httpClient.execute(request);
- if (respCode.getStatusLine().getStatusCode() != 200) {
- log.warn("Monitoring: Has an error in '" + TEST_EIDASNODEMETADATA + "': " + " HTTP responsecode: "
- + respCode);
- throw new Exception(TEST_EIDASNODEMETADATA + MESSAGE_ERROR);
-
- }
-
- // parse metadata
- DomUtils.parseXmlNonValidating(respCode.getEntity().getContent());
-
- return TEST_EIDASNODEMETADATA + MESSAGE_OK;
-
- } catch (Exception | TransformerFactoryConfigurationError e) {
- log.warn("Monitoring: Has an error in '" + TEST_EIDASNODEMETADATA + "': " + e.getMessage(), e);
- throw new Exception(TEST_EIDASNODEMETADATA + MESSAGE_ERROR, e);
-
- }
-
- }
-
-}
diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/health/EidasNodeMetadataHealthIndicator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/EidasNodeMetadataHealthIndicator.java
new file mode 100644
index 00000000..f160916c
--- /dev/null
+++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/EidasNodeMetadataHealthIndicator.java
@@ -0,0 +1,69 @@
+package at.asitplus.eidas.specific.connector.health;
+
+import java.io.ByteArrayInputStream;
+
+import javax.xml.transform.TransformerFactoryConfigurationError;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.StatusLine;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.http.entity.ContentType;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.HealthIndicator;
+
+import at.asitplus.eidas.specific.connector.MsEidasNodeConstants;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import at.gv.egiz.eaaf.core.impl.data.Triple;
+import at.gv.egiz.eaaf.core.impl.http.HttpUtils;
+import at.gv.egiz.eaaf.core.impl.http.IHttpClientFactory;
+import at.gv.egiz.eaaf.core.impl.utils.DomUtils;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class EidasNodeMetadataHealthIndicator implements HealthIndicator {
+
+ @Autowired IConfiguration config;
+ @Autowired IHttpClientFactory httpClientFactory;
+
+ @Override
+ public Health health() {
+ try {
+ final String urlString = config.getBasicConfiguration(
+ MsEidasNodeConstants.PROP_CONFIG_MONITORING_EIDASNODE_METADATAURL);
+ if (StringUtils.isEmpty(urlString)) {
+ log.trace("No eIDASNode metadata URL. Skipping test ... ");
+ return Health.unknown().build();
+
+ }
+
+ // create HTTP client
+ CloseableHttpClient httpClient = httpClientFactory.getHttpClient();
+ URIBuilder uriBuilder = new URIBuilder(urlString);
+ HttpUriRequest request = new HttpGet(uriBuilder.build());
+
+ final Triple<StatusLine, ByteArrayInputStream, ContentType> respCode = httpClient.execute(request,
+ HttpUtils.bodyStatusCodeResponseHandler());
+ if (respCode.getFirst().getStatusCode() != 200) {
+ log.warn("Monitoring: Get http StatusCode: {} from eIDAS-Node Metadata endpoint",
+ respCode.getFirst().getStatusCode());
+ return Health.down().withDetail("http StatusCode", respCode.getFirst().getStatusCode()).build();
+
+ }
+
+ // parse metadata
+ DomUtils.parseXmlNonValidating(respCode.getSecond());
+
+ return Health.up().build();
+
+ } catch (Exception | TransformerFactoryConfigurationError e) {
+ log.warn("Monitoring: Can not read SAML2 metadata from eIDAS-Node", e);
+ return Health.down().down(e).build();
+
+ }
+ }
+
+}
diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/health/Saml2MetadataHealthIndicator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/Saml2MetadataHealthIndicator.java
new file mode 100644
index 00000000..592231b0
--- /dev/null
+++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/health/Saml2MetadataHealthIndicator.java
@@ -0,0 +1,44 @@
+package at.asitplus.eidas.specific.connector.health;
+
+import javax.xml.transform.TransformerFactoryConfigurationError;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.HealthIndicator;
+
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataBuilderConfiguration;
+import at.gv.egiz.eaaf.modules.pvp2.api.metadata.IPvpMetadataConfigurationFactory;
+import at.gv.egiz.eaaf.modules.pvp2.impl.builder.PvpMetadataBuilder;
+import at.gv.egiz.eaaf.modules.pvp2.impl.utils.AbstractCredentialProvider;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class Saml2MetadataHealthIndicator implements HealthIndicator {
+
+ @Autowired
+ private PvpMetadataBuilder metadatabuilder;
+ @Autowired
+ private IPvpMetadataConfigurationFactory configFactory;
+
+ @Setter
+ private AbstractCredentialProvider pvpIdpCredentials;
+
+ @Override
+ public Health health() {
+ try {
+ // build metadata
+ final IPvpMetadataBuilderConfiguration metadataConfig =
+ configFactory.generateMetadataBuilderConfiguration(
+ "http://localhost/monitoring",
+ pvpIdpCredentials);
+ metadatabuilder.buildPvpMetadata(metadataConfig);
+ return Health.up().build();
+
+ } catch (Exception | TransformerFactoryConfigurationError e) {
+ return Health.down().down(e).build();
+
+ }
+ }
+
+}
diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java
index 86808f01..d3b8116a 100644
--- a/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java
+++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/processes/tasks/GenerateCountrySelectionFrameTask.java
@@ -26,8 +26,6 @@ package at.asitplus.eidas.specific.connector.processes.tasks;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -39,7 +37,6 @@ import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder;
import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
import at.gv.egiz.eaaf.core.api.idp.process.ExecutionContext;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
-import at.gv.egiz.eaaf.core.exceptions.GuiBuildException;
import at.gv.egiz.eaaf.core.exceptions.TaskExecutionException;
import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
@@ -51,7 +48,6 @@ import at.gv.egiz.eaaf.core.impl.idp.auth.modules.AbstractAuthServletTask;
*/
@Component("GenerateCountrySelectionFrameTask")
public class GenerateCountrySelectionFrameTask extends AbstractAuthServletTask {
- private static final Logger log = LoggerFactory.getLogger(GenerateCountrySelectionFrameTask.class);
@Autowired
ISpringMvcGuiFormBuilder guiBuilder;
@@ -77,16 +73,11 @@ public class GenerateCountrySelectionFrameTask extends AbstractAuthServletTask {
guiBuilder.build(request, response, config, "BKU-Selection form");
- } catch (final GuiBuildException e) {
- log.warn("Can not build GUI:'BKU-Selection'. Msg:" + e.getMessage());
+ } catch (final Exception e) {
throw new TaskExecutionException(pendingReq,
"Can not build GUI. Msg:" + e.getMessage(),
new EaafException("gui.00", new Object[] { e.getMessage() }, e));
- } catch (final Exception e) {
- log.warn("FinalizeAuthenticationTask has an internal error", e);
- throw new TaskExecutionException(pendingReq, e.getMessage(), e);
-
}
}
diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java
index 557e245a..1ea5a280 100644
--- a/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java
+++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/storage/EidasCacheTransactionStoreDecorator.java
@@ -30,18 +30,47 @@ import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.HealthIndicator;
import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage;
import at.gv.egiz.eaaf.core.exceptions.EaafException;
import at.gv.egiz.eaaf.core.exceptions.EaafStorageException;
+import at.gv.egiz.eaaf.core.impl.utils.Random;
-public class EidasCacheTransactionStoreDecorator implements ITransactionStorage {
+public class EidasCacheTransactionStoreDecorator implements ITransactionStorage, HealthIndicator {
private static final Logger log = LoggerFactory.getLogger(EidasCacheTransactionStoreDecorator.class);
@Autowired(required = true)
private CacheWithEidasBackend storage;
@Override
+ public Health health() {
+ try {
+ final String key = Random.nextHexRandom16();
+ final String value = Random.nextHexRandom16();
+
+ this.put(key, value, -1);
+ final String result = this.get(key, String.class);
+ this.remove(key);
+
+ if (result != null && result.equals(value)) {
+ return Health.up().build();
+
+ } else {
+ log.warn("Montioring: TestValue: " + value + " does NOT match in Storage test");
+ return Health.down().build();
+
+ }
+
+ } catch (final EaafException e) {
+ log.warn("Montioring: Can not read/write to storage.", e);
+ return Health.down().down(e).build();
+
+ }
+ }
+
+ @Override
public void changeKey(String oldKey, String newKey, Object value) throws EaafException {
if (containsKey(oldKey)) {
final TransactionStoreElement el = storage.get(oldKey);
@@ -148,5 +177,4 @@ public class EidasCacheTransactionStoreDecorator implements ITransactionStorage
}
}
-
}