From f6dca225fe987f0be4f3d8062835cba5923807c7 Mon Sep 17 00:00:00 2001 From: Felix Dittrich Date: Fri, 11 Feb 2022 18:01:42 +0100 Subject: [PATCH] Add Error Status for Download Connector --- .../connector/DgcGatewayConnectorUtils.java | 28 ++++++--- .../DgcGatewayDownloadConnector.java | 59 +++++++++++-------- ...atewayValidationRuleDownloadConnector.java | 49 ++++++++------- .../connector/dto/CertificateTypeDto.java | 3 +- 4 files changed, 83 insertions(+), 56 deletions(-) diff --git a/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayConnectorUtils.java b/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayConnectorUtils.java index ccd3b18..57f95b8 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayConnectorUtils.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayConnectorUtils.java @@ -40,9 +40,9 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.stream.Collectors; import javax.annotation.PostConstruct; +import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -123,27 +123,27 @@ public boolean trustListItemSignedByCa(TrustListItemDto certificate, X509Certifi } public boolean trustListItemSignedByCa(TrustListItemDto certificate, Map> caMap) { + List> caMap) { X509CertificateHolder dcs; try { dcs = new X509CertificateHolder(Base64.getDecoder().decode(certificate.getRawData())); } catch (IOException e) { log.error("Could not parse certificate. KID: {}, Country: {}", - certificate.getKid(), certificate.getCountry()); + certificate.getKid(), certificate.getCountry()); return false; } List caList = caMap.get(dcs.getIssuer().toString()); if (caList == null) { log.error("Failed to find issuer certificate from cert. KID: {}, Country: {}", - certificate.getKid(), certificate.getCountry()); + certificate.getKid(), certificate.getCountry()); return false; } return caList - .stream() - .anyMatch(ca -> trustListItemSignedByCa(certificate, ca)); + .stream() + .anyMatch(ca -> trustListItemSignedByCa(certificate, ca)); } boolean checkTrustAnchorSignature(TrustListItemDto trustListItem, List trustAnchors) { @@ -174,19 +174,22 @@ X509CertificateHolder getCertificateFromTrustListItem(TrustListItem trustListIte } } - public List fetchCertificatesAndVerifyByTrustAnchor(CertificateTypeDto type) { + public List fetchCertificatesAndVerifyByTrustAnchor(CertificateTypeDto type) + throws DgcGatewayConnectorException { ResponseEntity> downloadedCertificates; try { downloadedCertificates = dgcGatewayConnectorRestClient.getTrustedCertificates(type); } catch (FeignException e) { log.error("Failed to Download certificates from DGC Gateway. Type: {}, status code: {}", type, e.status()); - return Collections.emptyList(); + throw new DgcGatewayConnectorException( + e.status(), "Failed to Download certificates from DGC Gateway of type: " + type.toString()); } if (downloadedCertificates.getStatusCode() != HttpStatus.OK || downloadedCertificates.getBody() == null) { log.error("Failed to Download certificates from DGC Gateway, Type: {}, Status Code: {}", type, downloadedCertificates.getStatusCodeValue()); - return Collections.emptyList(); + throw new DgcGatewayConnectorException(downloadedCertificates.getStatusCodeValue(), + "Failed to Download certificates from DGC Gateway of type: " + type.toString()); } return downloadedCertificates.getBody().stream() @@ -207,4 +210,11 @@ private boolean checkThumbprintIntegrity(TrustListItemDto trustListItem) { return false; } } + + @RequiredArgsConstructor + @Getter + public static class DgcGatewayConnectorException extends Exception { + private final int httpStatusCode; + private final String message; + } } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayDownloadConnector.java b/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayDownloadConnector.java index 1e57f9b..e24332a 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayDownloadConnector.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayDownloadConnector.java @@ -69,6 +69,9 @@ public class DgcGatewayDownloadConnector { private final TrustListMapper trustListMapper; + @Getter + private String status = null; + @Getter private LocalDateTime lastUpdated = null; @@ -126,48 +129,52 @@ private synchronized void updateIfRequired() { log.info("Maximum age of cache reached. Fetching new TrustList from DGCG."); // Fetching CSCA Certs - trustedCscaTrustList = connectorUtils.fetchCertificatesAndVerifyByTrustAnchor(CertificateTypeDto.CSCA); - trustedCscaCertificates = trustedCscaTrustList.stream() - .map(connectorUtils::getCertificateFromTrustListItem) - .collect(Collectors.toList()); - log.info("CSCA TrustStore contains {} trusted certificates.", trustedCscaCertificates.size()); - trustedCscaCertificateMap = trustedCscaCertificates.stream() - .collect(Collectors.groupingBy((ca) -> ca.getSubject().toString(), - Collectors.mapping((ca) -> ca, Collectors.toList()))); - - // Fetching Upload Certs - trustedUploadCertificateTrustList = - connectorUtils.fetchCertificatesAndVerifyByTrustAnchor(CertificateTypeDto.UPLOAD); - trustedUploadCertificates = trustedUploadCertificateTrustList.stream() - .map(connectorUtils::getCertificateFromTrustListItem) - .collect(Collectors.toList()); - log.info("Upload TrustStore contains {} trusted certificates.", trustedUploadCertificates.size()); - - fetchTrustListAndVerifyByCscaAndUpload(); - log.info("DSC TrustStore contains {} trusted certificates.", trustedCertificates.size()); + try { + trustedCscaTrustList = connectorUtils.fetchCertificatesAndVerifyByTrustAnchor(CertificateTypeDto.CSCA); + trustedCscaCertificates = trustedCscaTrustList.stream() + .map(connectorUtils::getCertificateFromTrustListItem) + .collect(Collectors.toList()); + log.info("CSCA TrustStore contains {} trusted certificates.", trustedCscaCertificates.size()); + trustedCscaCertificateMap = trustedCscaCertificates.stream() + .collect(Collectors.groupingBy((ca) -> ca.getSubject().toString(), + Collectors.mapping((ca) -> ca, Collectors.toList()))); + + // Fetching Upload Certs + trustedUploadCertificateTrustList = + connectorUtils.fetchCertificatesAndVerifyByTrustAnchor(CertificateTypeDto.UPLOAD); + trustedUploadCertificates = trustedUploadCertificateTrustList.stream() + .map(connectorUtils::getCertificateFromTrustListItem) + .collect(Collectors.toList()); + log.info("Upload TrustStore contains {} trusted certificates.", trustedUploadCertificates.size()); + + fetchTrustListAndVerifyByCscaAndUpload(); + log.info("DSC TrustStore contains {} trusted certificates.", trustedCertificates.size()); + status = null; + } catch (DgcGatewayConnectorUtils.DgcGatewayConnectorException e) { + log.error("Failed to Download Trusted Certificates: {} - {}", e.getHttpStatusCode(), e.getMessage()); + status = "Download Failed: " + e.getHttpStatusCode() + " - " + e.getMessage(); + } } else { log.debug("Cache needs no refresh."); } } - private void fetchTrustListAndVerifyByCscaAndUpload() { + private void fetchTrustListAndVerifyByCscaAndUpload() throws DgcGatewayConnectorUtils.DgcGatewayConnectorException { log.info("Fetching TrustList from DGCG"); ResponseEntity> responseEntity; try { responseEntity = dgcGatewayConnectorRestClient.getTrustedCertificates(CertificateTypeDto.DSC); } catch (FeignException e) { - log.error("Download of TrustListItems failed. DGCG responded with status code: {}", - e.status()); - return; + throw new DgcGatewayConnectorUtils.DgcGatewayConnectorException( + e.status(), "Download of TrustListItems failed."); } List downloadedDcs = responseEntity.getBody(); if (responseEntity.getStatusCode() != HttpStatus.OK || downloadedDcs == null) { - log.error("Download of TrustListItems failed. DGCG responded with status code: {}", - responseEntity.getStatusCode()); - return; + throw new DgcGatewayConnectorUtils.DgcGatewayConnectorException( + responseEntity.getStatusCodeValue(), "Download of TrustListItems failed."); } else { log.info("Got Response from DGCG, Downloaded Certificates: {}", downloadedDcs.size()); } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayValidationRuleDownloadConnector.java b/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayValidationRuleDownloadConnector.java index 082fc72..6fc4374 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayValidationRuleDownloadConnector.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/connector/DgcGatewayValidationRuleDownloadConnector.java @@ -71,6 +71,9 @@ public class DgcGatewayValidationRuleDownloadConnector { private final ObjectMapper objectMapper; + @Getter + private String status = null; + @Getter private LocalDateTime lastUpdated = null; @@ -95,42 +98,48 @@ private synchronized void updateIfRequired() { || ChronoUnit.SECONDS.between(lastUpdated, LocalDateTime.now()) >= properties.getMaxCacheAge()) { log.info("Maximum age of cache reached. Fetching new TrustList from DGCG."); - validationRules = new ValidationRulesByCountry(); - - trustedUploadCertificates = - connectorUtils.fetchCertificatesAndVerifyByTrustAnchor(CertificateTypeDto.UPLOAD).stream() - .map(connectorUtils::getCertificateFromTrustListItem) - .collect(Collectors.toList()); - log.info("Upload TrustStore contains {} trusted certificates.", trustedUploadCertificates.size()); - - List countryCodes = countryListDownloadConnector.getCountryList(); - log.info("Downloaded Countrylist"); - - countryCodes.forEach(this::fetchValidationRulesAndVerify); - log.info("ValidationRule Cache contains {} ValidationRules.", validationRules.size()); + try { + validationRules = new ValidationRulesByCountry(); + + trustedUploadCertificates = + connectorUtils.fetchCertificatesAndVerifyByTrustAnchor(CertificateTypeDto.UPLOAD).stream() + .map(connectorUtils::getCertificateFromTrustListItem) + .collect(Collectors.toList()); + log.info("Upload TrustStore contains {} trusted certificates.", trustedUploadCertificates.size()); + + List countryCodes = countryListDownloadConnector.getCountryList(); + log.info("Downloaded Countrylist"); + + for (String countryCode : countryCodes) { + fetchValidationRulesAndVerify(countryCode); + } + log.info("ValidationRule Cache contains {} ValidationRules.", validationRules.size()); + } catch (DgcGatewayConnectorUtils.DgcGatewayConnectorException e) { + log.error("Failed to Download Validation Rules: {} - {}", e.getHttpStatusCode(), e.getMessage()); + status = "Download Failed: " + e.getHttpStatusCode() + " - " + e.getMessage(); + } } else { log.debug("Cache needs no refresh."); } } - private void fetchValidationRulesAndVerify(String countryCode) { + private void fetchValidationRulesAndVerify(String countryCode) + throws DgcGatewayConnectorUtils.DgcGatewayConnectorException { log.info("Fetching ValidationRules from DGCG for Country {}", countryCode); ResponseEntity>> responseEntity; try { responseEntity = dgcGatewayConnectorRestClient.downloadValidationRule(countryCode); } catch (FeignException e) { - log.error("Download of ValidationRules for country {} failed. DGCG responded with status code: {}", - countryCode, e.status()); - return; + throw new DgcGatewayConnectorUtils.DgcGatewayConnectorException( + e.status(), "Download of ValidationRules failed."); } Map> downloadedValidationRules = responseEntity.getBody(); if (responseEntity.getStatusCode() != HttpStatus.OK || downloadedValidationRules == null) { - log.error("Download of ValidationRules for country {} failed. DGCG responded with status code: {}", - countryCode, responseEntity.getStatusCode()); - return; + throw new DgcGatewayConnectorUtils.DgcGatewayConnectorException( + responseEntity.getStatusCodeValue(), "Download of TrustListItems failed."); } else { log.info("Got Response from DGCG, Downloaded ValidationRules: {}", downloadedValidationRules.size()); } diff --git a/src/main/java/eu/europa/ec/dgc/gateway/connector/dto/CertificateTypeDto.java b/src/main/java/eu/europa/ec/dgc/gateway/connector/dto/CertificateTypeDto.java index 0fdd9b2..f2ebc40 100644 --- a/src/main/java/eu/europa/ec/dgc/gateway/connector/dto/CertificateTypeDto.java +++ b/src/main/java/eu/europa/ec/dgc/gateway/connector/dto/CertificateTypeDto.java @@ -24,5 +24,6 @@ public enum CertificateTypeDto { AUTHENTICATION, UPLOAD, CSCA, - DSC + DSC, + TRUSTANCHOR }