From 128e116285831750de51fe7b67202165c9c779e2 Mon Sep 17 00:00:00 2001
From: slaurenz <82034561+slaurenz@users.noreply.github.com>
Date: Fri, 25 Jun 2021 15:42:34 +0200
Subject: [PATCH 1/2] Feat/download data (#14)
* Added functionality for value sets
* Added local storage functionality for business rules
* Updated Value Set handling and api description
* Updated country list handling and api description
* Updated business rule handling and api description
* Added `X-VERSION` Header as optional
* Added Licence Text
* Added download of business rules, value set and country list using the dgc-lib
* Add simple sanity check for downloaded data.
* Update DGC-Lib to 1.1.1
Co-authored-by: Felix Dittrich <31076102+f11h@users.noreply.github.com>
---
pom.xml | 8 +-
.../DgcBusinessRuleServiceApplication.java | 2 +-
.../config/DgcConfigProperties.java | 12 +-
.../dgc/businessrule/config/ErrorHandler.java | 2 +-
.../businessrule/config/OpenApiConfig.java | 20 +
.../businessrule/config/SchedulerConfig.java | 2 +-
.../businessrule/config/ShedLockConfig.java | 2 +-
.../entity/BusinessRuleEntity.java | 22 +-
.../entity/CountryListEntity.java | 20 +
.../businessrule/entity/ShedlockEntity.java | 2 +-
.../businessrule/entity/ValueSetEntity.java | 20 +
.../DgcaBusinessRulesResponseException.java | 20 +
.../businessrule/model/BusinessRuleItem.java | 19 +
.../dgc/businessrule/model/ValueSetItem.java | 15 +
.../repository/BusinessRuleRepository.java | 22 ++
.../repository/CountryListRepository.java | 20 +
.../repository/ValueSetRepository.java | 22 ++
.../controller/BusinessRuleController.java | 47 ++-
.../controller/CountryListController.java | 16 +-
.../controller/ValueSetController.java | 29 +-
.../restapi/dto/BusinessRuleListItemDto.java | 20 +
.../restapi/dto/ProblemReportDto.java | 2 +-
.../restapi/dto/ValueSetListItemDto.java | 20 +
.../service/BusinessRuleService.java | 124 +++++--
.../service/CountryListService.java | 42 ++-
.../service/GatewayDataDownloadService.java | 40 ++
.../GatewayDataDownloadServiceImpl.java | 131 +++++++
.../businessrule/service/ValueSetService.java | 111 ++++--
.../utils/BusinessRulesUtils.java | 20 +
src/main/resources/application-btp.yml | 6 +
src/main/resources/application.yml | 33 +-
.../static/valuesets/country-2-codes.json | 2 +-
.../ec/dgc/businessrule/OpenApiTest.java | 31 ++
...BusinessRuleControllerIntegrationTest.java | 351 ++++++++++++++++++
.../CountryListControllerIntegrationTest.java | 33 ++
.../ValueSetControllerIntegrationTest.java | 161 ++++++++
.../service/BusinessRuleServiceTest.java | 176 +++++++++
.../service/CountryListServiceTest.java | 77 ++++
.../service/ValueSetServiceTest.java | 146 ++++++++
.../testdata/BusinessRulesTestHelper.java | 187 ++++++++++
src/test/resources/application.yml | 14 +-
templates/file-header.txt | 2 +-
42 files changed, 1948 insertions(+), 103 deletions(-)
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/model/BusinessRuleItem.java
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/model/ValueSetItem.java
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadService.java
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadServiceImpl.java
create mode 100644 src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/BusinessRuleControllerIntegrationTest.java
create mode 100644 src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/ValueSetControllerIntegrationTest.java
create mode 100644 src/test/java/eu/europa/ec/dgc/businessrule/service/BusinessRuleServiceTest.java
create mode 100644 src/test/java/eu/europa/ec/dgc/businessrule/service/CountryListServiceTest.java
create mode 100644 src/test/java/eu/europa/ec/dgc/businessrule/service/ValueSetServiceTest.java
create mode 100644 src/test/java/eu/europa/ec/dgc/businessrule/testdata/BusinessRulesTestHelper.java
diff --git a/pom.xml b/pom.xml
index c60ff56..8ea59dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,7 +38,7 @@
1.68
4.9.1
4.23.0
- 0.5.0
+ 1.1.1
3.1.2
3.6.1.1688
@@ -133,7 +133,11 @@
-
+
+ eu.europa.ec.dgc
+ dgc-lib
+ ${dgc.lib.version}
+
org.springframework.boot
spring-boot-starter
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/DgcBusinessRuleServiceApplication.java b/src/main/java/eu/europa/ec/dgc/businessrule/DgcBusinessRuleServiceApplication.java
index a2e4103..3f32e62 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/DgcBusinessRuleServiceApplication.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/DgcBusinessRuleServiceApplication.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/config/DgcConfigProperties.java b/src/main/java/eu/europa/ec/dgc/businessrule/config/DgcConfigProperties.java
index 9a8b12e..962da8a 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/config/DgcConfigProperties.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/config/DgcConfigProperties.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
@@ -29,12 +29,18 @@
@ConfigurationProperties("dgc")
public class DgcConfigProperties {
- private final CertificatesDownloader certificatesDownloader = new CertificatesDownloader();
+ private final GatewayDownload businessRulesDownload = new GatewayDownload();
+
+ private final GatewayDownload valueSetsDownload = new GatewayDownload();
+
+ private final GatewayDownload countryListDownload = new GatewayDownload();
@Getter
@Setter
- public static class CertificatesDownloader {
+ public static class GatewayDownload {
private Integer timeInterval;
private Integer lockLimit;
}
+
+
}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/config/ErrorHandler.java b/src/main/java/eu/europa/ec/dgc/businessrule/config/ErrorHandler.java
index f3e0e78..0fd7dab 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/config/ErrorHandler.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/config/ErrorHandler.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/config/OpenApiConfig.java b/src/main/java/eu/europa/ec/dgc/businessrule/config/OpenApiConfig.java
index 2252e59..98fe27e 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/config/OpenApiConfig.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/config/OpenApiConfig.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.config;
import io.swagger.v3.oas.models.OpenAPI;
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/config/SchedulerConfig.java b/src/main/java/eu/europa/ec/dgc/businessrule/config/SchedulerConfig.java
index c1ddb8f..c475149 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/config/SchedulerConfig.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/config/SchedulerConfig.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/config/ShedLockConfig.java b/src/main/java/eu/europa/ec/dgc/businessrule/config/ShedLockConfig.java
index 765295f..8e7415f 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/config/ShedLockConfig.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/config/ShedLockConfig.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/entity/BusinessRuleEntity.java b/src/main/java/eu/europa/ec/dgc/businessrule/entity/BusinessRuleEntity.java
index bf931d2..b6cc511 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/entity/BusinessRuleEntity.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/entity/BusinessRuleEntity.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.entity;
import javax.persistence.Column;
@@ -31,7 +51,7 @@ public class BusinessRuleEntity {
private String identifier;
@Column(name = "version", nullable = false)
- String version = "1.0.0";
+ String version;
@Column(name = "country_code", nullable = false, length = 2)
String country;
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/entity/CountryListEntity.java b/src/main/java/eu/europa/ec/dgc/businessrule/entity/CountryListEntity.java
index d4b3b97..62e1c3a 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/entity/CountryListEntity.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/entity/CountryListEntity.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.entity;
import javax.persistence.Column;
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/entity/ShedlockEntity.java b/src/main/java/eu/europa/ec/dgc/businessrule/entity/ShedlockEntity.java
index 926548f..750af02 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/entity/ShedlockEntity.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/entity/ShedlockEntity.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/entity/ValueSetEntity.java b/src/main/java/eu/europa/ec/dgc/businessrule/entity/ValueSetEntity.java
index c137094..409f727 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/entity/ValueSetEntity.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/entity/ValueSetEntity.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.entity;
import javax.persistence.Column;
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/exception/DgcaBusinessRulesResponseException.java b/src/main/java/eu/europa/ec/dgc/businessrule/exception/DgcaBusinessRulesResponseException.java
index 05e1242..af583aa 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/exception/DgcaBusinessRulesResponseException.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/exception/DgcaBusinessRulesResponseException.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.exception;
import lombok.Getter;
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/model/BusinessRuleItem.java b/src/main/java/eu/europa/ec/dgc/businessrule/model/BusinessRuleItem.java
new file mode 100644
index 0000000..4ba9f75
--- /dev/null
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/model/BusinessRuleItem.java
@@ -0,0 +1,19 @@
+package eu.europa.ec.dgc.businessrule.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class BusinessRuleItem {
+
+ private String hash;
+
+ private String identifier;
+
+ private String version;
+
+ private String country;
+
+ private String rawData;
+}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/model/ValueSetItem.java b/src/main/java/eu/europa/ec/dgc/businessrule/model/ValueSetItem.java
new file mode 100644
index 0000000..a665c3a
--- /dev/null
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/model/ValueSetItem.java
@@ -0,0 +1,15 @@
+package eu.europa.ec.dgc.businessrule.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class ValueSetItem {
+
+ private String hash;
+
+ private String id;
+
+ private String rawData;
+}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/repository/BusinessRuleRepository.java b/src/main/java/eu/europa/ec/dgc/businessrule/repository/BusinessRuleRepository.java
index f39828d..98bbd05 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/repository/BusinessRuleRepository.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/repository/BusinessRuleRepository.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.repository;
import eu.europa.ec.dgc.businessrule.entity.BusinessRuleEntity;
@@ -14,4 +34,6 @@ public interface BusinessRuleRepository extends JpaRepository findAllByCountryOrderByIdentifierAsc(String country);
BusinessRuleEntity findOneByCountryAndHash(String country, String hash);
+
+ void deleteByHashNotIn(List hashes);
}
\ No newline at end of file
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/repository/CountryListRepository.java b/src/main/java/eu/europa/ec/dgc/businessrule/repository/CountryListRepository.java
index 9b3d14e..bcaba7e 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/repository/CountryListRepository.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/repository/CountryListRepository.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.repository;
import eu.europa.ec.dgc.businessrule.entity.CountryListEntity;
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/repository/ValueSetRepository.java b/src/main/java/eu/europa/ec/dgc/businessrule/repository/ValueSetRepository.java
index 65e9f3b..0c358e2 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/repository/ValueSetRepository.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/repository/ValueSetRepository.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.repository;
import eu.europa.ec.dgc.businessrule.entity.ValueSetEntity;
@@ -10,4 +30,6 @@ public interface ValueSetRepository extends JpaRepository findAllByOrderByIdAsc();
ValueSetEntity findOneByHash(String hash);
+
+ void deleteByHashNotIn(List hashes);
}
\ No newline at end of file
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/BusinessRuleController.java b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/BusinessRuleController.java
index 254570f..5d9789d 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/BusinessRuleController.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/BusinessRuleController.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
@@ -22,9 +22,11 @@
import eu.europa.ec.dgc.businessrule.entity.BusinessRuleEntity;
import eu.europa.ec.dgc.businessrule.exception.DgcaBusinessRulesResponseException;
+import eu.europa.ec.dgc.businessrule.model.BusinessRuleItem;
import eu.europa.ec.dgc.businessrule.restapi.dto.BusinessRuleListItemDto;
import eu.europa.ec.dgc.businessrule.restapi.dto.ProblemReportDto;
import eu.europa.ec.dgc.businessrule.service.BusinessRuleService;
+import eu.europa.ec.dgc.businessrule.utils.BusinessRulesUtils;
import io.swagger.v3.oas.annotations.Hidden;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -35,6 +37,7 @@
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Locale;
import javax.validation.Valid;
@@ -58,10 +61,14 @@
@RequiredArgsConstructor
public class BusinessRuleController {
- private final BusinessRuleService businessRuleService;
+ private static final String API_VERSION_HEADER = "X-VERSION";
private static final String X_SIGNATURE_HEADER = "X-SIGNATURE";
+ private final BusinessRuleService businessRuleService;
+
+ private final BusinessRulesUtils businessRulesUtils;
+
/**
* Http Method for getting the business rules list.
*/
@@ -84,17 +91,14 @@ public class BusinessRuleController {
@ApiResponse(
responseCode = "200",
description = "Returns a list of all business rule ids country codes and hash values.",
- headers = {
- @Header(
- name = "X-SIGNATURE",
- description = "ECDSA signature of the returned value, if configured.")
- },
content = @Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
array = @ArraySchema(schema = @Schema(implementation = BusinessRuleListItemDto.class))))
}
)
- public ResponseEntity> getRules() {
+ public ResponseEntity> getRules(
+ @RequestHeader(value = API_VERSION_HEADER, required = false) String apiVersion
+ ) {
return ResponseEntity.ok(businessRuleService.getBusinessRulesList());
}
@@ -123,11 +127,6 @@ public ResponseEntity> getRules() {
@ApiResponse(
responseCode = "200",
description = "Returns a list of all business rule ids country codes and hash values for a country.",
- headers = {
- @Header(
- name = "X-SIGNATURE",
- description = "ECDSA signature of the returned value, if configured.")
- },
content = @Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
array = @ArraySchema(schema = @Schema(implementation = BusinessRuleListItemDto.class)))),
@@ -140,6 +139,7 @@ public ResponseEntity> getRules() {
}
)
public ResponseEntity> getRulesForCountry(
+ @RequestHeader(value = API_VERSION_HEADER, required = false) String apiVersion,
@Valid @PathVariable("country") String country
) {
validateCountryParameter(country);
@@ -220,7 +220,8 @@ public ResponseEntity> getRulesForCountry(
mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(implementation = ProblemReportDto.class)))
})
- public ResponseEntity getRuleByHash(
+ public ResponseEntity getRuleByCountryAndHash(
+ @RequestHeader(value = API_VERSION_HEADER, required = false) String apiVersion,
@Valid @PathVariable("country") String country,
@Valid @PathVariable("hash") String hash
) {
@@ -247,15 +248,31 @@ public ResponseEntity getRuleByHash(
public ResponseEntity createRule(
@RequestHeader(value = "X_COUNTRY") String country,
@RequestHeader(value = "X_ID") String id,
+ @RequestHeader(value = "X_VER") String version,
@RequestBody String ruleData) {
+ String hash;
validateCountryParameter(country);
if (id == null || id.isBlank()) {
throw new DgcaBusinessRulesResponseException(HttpStatus.BAD_REQUEST, "0x003", "Possible reasons: "
+ "The id of the rule is not set.", id,"");
}
- businessRuleService.saveBusinessRule(id, country.toUpperCase(Locale.ROOT), ruleData);
+
+ try {
+ hash = businessRulesUtils.calculateHash(ruleData);
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Calculation of hash failed:", e);
+ throw new DgcaBusinessRulesResponseException(HttpStatus.INTERNAL_SERVER_ERROR, "0x500",
+ "Internal Server Error","","");
+ }
+ BusinessRuleItem bri = new BusinessRuleItem();
+ bri.setHash(hash);
+ bri.setIdentifier(id);
+ bri. setCountry(country);
+ bri.setVersion(version);
+ bri.setRawData(ruleData);
+ businessRuleService.saveBusinessRule(bri);
return ResponseEntity.ok("Upload: OK");
}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/CountryListController.java b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/CountryListController.java
index a654c54..0361dc1 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/CountryListController.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/CountryListController.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
@@ -38,6 +38,7 @@
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -48,6 +49,8 @@
@RequiredArgsConstructor
public class CountryListController {
+ private static final String API_VERSION_HEADER = "X-VERSION";
+
private final CountryListService countryListService;
/**
@@ -70,11 +73,6 @@ public class CountryListController {
@ApiResponse(
responseCode = "200",
description = "Returns a JSON list, with all onboarded member states as country code.",
- headers = {
- @Header(
- name = "X-SIGNATURE",
- description = "ECDSA signature of the returned value, if configured.")
- },
content = @Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
array = @ArraySchema(schema = @Schema(implementation = String.class)),
@@ -86,7 +84,9 @@ public class CountryListController {
}))
}
)
- public ResponseEntity getCountryList() {
+ public ResponseEntity getCountryList(
+ @RequestHeader(value = API_VERSION_HEADER, required = false) String apiVersion
+ ) {
return ResponseEntity.ok(countryListService.getCountryList());
}
@@ -95,7 +95,7 @@ public ResponseEntity getCountryList() {
*/
@PostMapping(path = "", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Hidden
- public ResponseEntity createRule(
+ public ResponseEntity createCountryList(
@RequestBody String countryListData) {
countryListService.saveCountryList(countryListData);
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/ValueSetController.java b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/ValueSetController.java
index 3f7d585..8d0f962 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/ValueSetController.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/controller/ValueSetController.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
@@ -53,6 +53,7 @@
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -62,6 +63,8 @@
@RequiredArgsConstructor
public class ValueSetController {
+ private static final String API_VERSION_HEADER = "X-VERSION";
+
private final BusinessRulesUtils businessRulesUtils;
private final ValueSetService valueSetService;
@@ -89,11 +92,6 @@ public class ValueSetController {
@ApiResponse(
responseCode = "200",
description = "Returns a list of all value set ids and there hash values.",
- headers = {
- @Header(
- name = "X-SIGNATURE",
- description = "ECDSA signature of the returned value, if configured.")
- },
content = @Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
array = @ArraySchema(schema = @Schema(implementation = ValueSetListItemDto.class)),
@@ -135,8 +133,9 @@ public class ValueSetController {
}))
}
)
- public ResponseEntity> getValueSetList() {
-
+ public ResponseEntity> getValueSetList(
+ @RequestHeader(value = API_VERSION_HEADER, required = false) String apiVersion
+ ) {
return ResponseEntity.ok(valueSetService.getValueSetsList());
}
@@ -194,6 +193,7 @@ public ResponseEntity> getValueSetList() {
))
})
public ResponseEntity getValueSet(
+ @RequestHeader(value = API_VERSION_HEADER, required = false) String apiVersion,
@Valid @PathVariable("hash") String hash
) {
ValueSetEntity vse = valueSetService.getValueSetByHash(hash);
@@ -226,12 +226,21 @@ public ResponseEntity loadDummyData() {
private void loadValuesetFile(String filename, String valueSetName) {
Resource resource = new ClassPathResource(filename);
+ String rawData;
+ String hash;
try {
- valueSetService.saveValueSet(valueSetName,
- IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8));
+ rawData = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8);
+ hash = businessRulesUtils.calculateHash(rawData);
+
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Calculation of hash failed:", e);
+ return;
} catch (IOException e) {
log.error("Could not read file: " + valueSetName);
+ return;
}
+
+ valueSetService.saveValueSet(hash, valueSetName, rawData);
}
}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/BusinessRuleListItemDto.java b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/BusinessRuleListItemDto.java
index 6ab6f2c..6d38830 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/BusinessRuleListItemDto.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/BusinessRuleListItemDto.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.restapi.dto;
import io.swagger.v3.oas.annotations.media.Schema;
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/ProblemReportDto.java b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/ProblemReportDto.java
index 836c219..b0db429 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/ProblemReportDto.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/ProblemReportDto.java
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/ValueSetListItemDto.java b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/ValueSetListItemDto.java
index 705356a..e9cc7d5 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/ValueSetListItemDto.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/restapi/dto/ValueSetListItemDto.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.restapi.dto;
import io.swagger.v3.oas.annotations.media.Schema;
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/service/BusinessRuleService.java b/src/main/java/eu/europa/ec/dgc/businessrule/service/BusinessRuleService.java
index 23fdf5d..9319c82 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/service/BusinessRuleService.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/service/BusinessRuleService.java
@@ -1,12 +1,36 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.service;
import eu.europa.ec.dgc.businessrule.entity.BusinessRuleEntity;
+import eu.europa.ec.dgc.businessrule.model.BusinessRuleItem;
import eu.europa.ec.dgc.businessrule.repository.BusinessRuleRepository;
import eu.europa.ec.dgc.businessrule.restapi.dto.BusinessRuleListItemDto;
import eu.europa.ec.dgc.businessrule.utils.BusinessRulesUtils;
+import eu.europa.ec.dgc.gateway.connector.model.ValidationRule;
import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -18,35 +42,13 @@
@Service
public class BusinessRuleService {
- private final BusinessRulesUtils businessRulesUtils;
-
private final BusinessRuleRepository businessRuleRepository;
- /**
- * Saves a Business rule.
- *
- */
- @Transactional
- public void saveBusinessRule(String ruleId, String ruleCountry, String ruleData) {
- String hash;
- try {
- hash = businessRulesUtils.calculateHash(ruleData);
- } catch (NoSuchAlgorithmException e) {
- log.error("Calculation of hash failed:", e);
- return;
- }
-
- BusinessRuleEntity bre = new BusinessRuleEntity();
- bre.setIdentifier(ruleId);
- bre.setCountry(ruleCountry);
- bre.setRawData(ruleData.toUpperCase(Locale.ROOT));
- bre.setHash(hash);
-
- businessRuleRepository.save(bre);
- }
+ private final BusinessRulesUtils businessRulesUtils;
/**
* Gets list of all business rules ids and hashes.
+ *
*/
public List getBusinessRulesList() {
@@ -64,7 +66,6 @@ public List getBusinessRulesListForCountry(String count
return rulesItems;
}
-
/**f
* Gets a business rule by hash.
*/
@@ -73,4 +74,77 @@ public BusinessRuleEntity getBusinessRuleByCountryAndHash(String country, String
return businessRuleRepository.findOneByCountryAndHash(country, hash);
}
+
+ /**
+ * Updates the list of business rules.
+ * @param businessRules list of actual value sets
+ */
+ @Transactional
+ public void updateBusinesRules(List businessRules) {
+ List ruleHashes =
+ businessRules.stream().map(BusinessRuleItem::getHash).collect(Collectors.toList());
+ List alreadyStoredRules = getBusinessRulesHashList();
+
+ if (ruleHashes.isEmpty()) {
+ businessRuleRepository.deleteAll();
+ } else {
+ businessRuleRepository.deleteByHashNotIn(ruleHashes);
+ }
+
+ for (BusinessRuleItem rule : businessRules) {
+ if (!alreadyStoredRules.contains(rule.getHash())) {
+ saveBusinessRule(rule);
+ }
+ }
+
+ }
+
+ /**
+ * Saves a Business rule.
+ * @param rule The rule to be saved.
+ */
+ @Transactional
+ public void saveBusinessRule(BusinessRuleItem rule) {
+ BusinessRuleEntity bre = new BusinessRuleEntity();
+ bre.setHash(rule.getHash());
+ bre.setIdentifier(rule.getIdentifier());
+ bre.setCountry(rule.getCountry().toUpperCase(Locale.ROOT));
+ bre.setVersion(rule.getVersion());
+ bre.setRawData(rule.getRawData());
+
+ businessRuleRepository.save(bre);
+ }
+
+ /**
+ * Creates a List of business rule items from a list of validation rules.
+ * @param validationRules the list containing the validation rules.
+ * @return List of BusinessRuleItems.
+ */
+ public List createBusinessRuleItemList(List validationRules)
+ throws NoSuchAlgorithmException {
+ List businessRuleItems = new ArrayList<>();
+
+ for (ValidationRule validationRule: validationRules) {
+ BusinessRuleItem businessRuleItem = new BusinessRuleItem();
+
+ businessRuleItem.setHash(businessRulesUtils.calculateHash(validationRule.getRawJson()));
+ businessRuleItem.setIdentifier(validationRule.getIdentifier());
+ businessRuleItem.setCountry(validationRule.getCountry());
+ businessRuleItem.setVersion(validationRule.getVersion());
+ businessRuleItem.setRawData(validationRule.getRawJson());
+
+ businessRuleItems.add(businessRuleItem);
+ }
+
+ return businessRuleItems;
+ }
+
+
+ /**
+ * Gets a list of hash values of all stored business rules.
+ * @return List of hash values
+ */
+ private List getBusinessRulesHashList() {
+ return getBusinessRulesList().stream().map(BusinessRuleListItemDto::getHash).collect(Collectors.toList());
+ }
}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/service/CountryListService.java b/src/main/java/eu/europa/ec/dgc/businessrule/service/CountryListService.java
index 94d3ed6..2b99a83 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/service/CountryListService.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/service/CountryListService.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.service;
import eu.europa.ec.dgc.businessrule.entity.CountryListEntity;
@@ -17,7 +37,8 @@ public class CountryListService {
private final CountryListRepository countryListRepository;
/**
- * returns the country list.
+ * Gets the actual country list.
+ * @return the country list.
*/
@Transactional
public String getCountryList() {
@@ -29,8 +50,23 @@ public String getCountryList() {
}
}
+
/**
- * Saves a country list by replacing an old one.
+ * Updates a country List, if it is different from the old one.
+ * @param newCountryListData new country list data
+ */
+ @Transactional
+ public void updateCountryList(String newCountryListData) {
+ String oldList = getCountryList();
+ if (!newCountryListData.equals(oldList)) {
+ saveCountryList(newCountryListData);
+ }
+ }
+
+
+ /**
+ * Saves a country list by replacing an old one.
+ * @param listData the country list to be saved.
*/
@Transactional
@@ -40,4 +76,6 @@ public void saveCountryList(String listData) {
}
+
+
}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadService.java b/src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadService.java
new file mode 100644
index 0000000..ad5c868
--- /dev/null
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadService.java
@@ -0,0 +1,40 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package eu.europa.ec.dgc.businessrule.service;
+
+public interface GatewayDataDownloadService {
+
+ /**
+ * Synchronises the business rules with the gateway.
+ */
+ void downloadBusinessRules();
+
+ /**
+ * Synchronises the value sets with the gateway.
+ */
+ void downloadValueSets();
+
+ /**
+ * Synchronises the country list with the gateway.
+ */
+ void downloadCountryList();
+
+}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadServiceImpl.java b/src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadServiceImpl.java
new file mode 100644
index 0000000..af62673
--- /dev/null
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadServiceImpl.java
@@ -0,0 +1,131 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package eu.europa.ec.dgc.businessrule.service;
+
+import eu.europa.ec.dgc.businessrule.model.BusinessRuleItem;
+import eu.europa.ec.dgc.businessrule.model.ValueSetItem;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValueSetDownloadConnector;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
+import net.minidev.json.JSONArray;
+import org.springframework.context.annotation.Profile;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * A service to download the valuesets, business rules and country list from the digital covid certificate gateway.
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Component
+@Profile("!btp")
+public class GatewayDataDownloadServiceImpl implements GatewayDataDownloadService {
+
+ private final DgcGatewayValidationRuleDownloadConnector dgcRuleConnector;
+
+ private final DgcGatewayValueSetDownloadConnector dgcValueSetConnector;
+
+ private final DgcGatewayCountryListDownloadConnector dgcCountryListConnector;
+
+ private final BusinessRuleService businessRuleService;
+
+ private final ValueSetService valueSetService;
+
+ private final CountryListService countryListService;
+
+ @Override
+ @Scheduled(fixedDelayString = "${dgc.businessRulesDownload.timeInterval}")
+ @SchedulerLock(name = "GatewayDataDownloadService_downloadBusinessRules", lockAtLeastFor = "PT0S",
+ lockAtMostFor = "${dgc.businessRulesDownload.lockLimit}")
+ public void downloadBusinessRules() {
+ List ruleItems;
+
+ log.info("Business rules download started");
+
+ try {
+ ruleItems = businessRuleService.createBusinessRuleItemList(dgcRuleConnector.getValidationRules().flat());
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to hash business rules on download.",e);
+ return;
+ }
+
+ if (!ruleItems.isEmpty()) {
+ businessRuleService.updateBusinesRules(ruleItems);
+ } else {
+ log.warn("The download of the business rules seems to fail, as the download connector "
+ + "returns an empty business rules list.-> No data was changed.");
+ }
+
+ log.info("Business rules finished");
+ }
+
+ @Override
+ @Scheduled(fixedDelayString = "${dgc.valueSetsDownload.timeInterval}")
+ @SchedulerLock(name = "GatewayDataDownloadService_downloadValueSets", lockAtLeastFor = "PT0S",
+ lockAtMostFor = "${dgc.valueSetsDownload.lockLimit}")
+ public void downloadValueSets() {
+ List valueSetItems;
+ log.info("Valuesets download started");
+
+ try {
+ valueSetItems = valueSetService.createValueSetItemListFromMap(dgcValueSetConnector.getValueSets());
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to hash business rules on download.",e);
+ return;
+ }
+
+ if (!valueSetItems.isEmpty()) {
+ valueSetService.updateValueSets(valueSetItems);
+ } else {
+ log.warn("The download of the value sets seems to fail, as the download connector "
+ + "returns an empty value sets list.-> No data was changed.");
+ }
+
+ log.info("Valuesets download finished");
+ }
+
+ @Override
+ @Scheduled(fixedDelayString = "${dgc.countryListDownload.timeInterval}")
+ @SchedulerLock(name = "GatewayDataDownloadService_downloadCountryList", lockAtLeastFor = "PT0S",
+ lockAtMostFor = "${dgc.countryListDownload.lockLimit}")
+ public void downloadCountryList() {
+ log.info("Country list download started");
+
+ List countryList = dgcCountryListConnector.getCountryList();
+
+ if (!countryList.isEmpty()) {
+ String countryListJsonStr = JSONArray.toJSONString(countryList);
+ countryListService.updateCountryList(countryListJsonStr);
+ } else {
+ log.warn("The download of the country list seems to fail, as the download connector "
+ + "returns an empty country list.-> No data was changed.");
+ }
+
+ log.info("Country list download finished");
+ }
+
+}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/service/ValueSetService.java b/src/main/java/eu/europa/ec/dgc/businessrule/service/ValueSetService.java
index e996287..ceace91 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/service/ValueSetService.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/service/ValueSetService.java
@@ -1,15 +1,37 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.service;
import eu.europa.ec.dgc.businessrule.entity.ValueSetEntity;
+import eu.europa.ec.dgc.businessrule.model.ValueSetItem;
import eu.europa.ec.dgc.businessrule.repository.ValueSetRepository;
import eu.europa.ec.dgc.businessrule.restapi.dto.ValueSetListItemDto;
import eu.europa.ec.dgc.businessrule.utils.BusinessRulesUtils;
-import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -22,45 +44,92 @@ public class ValueSetService {
private final ValueSetRepository valueSetRepository;
+
+ /**
+ * Gets list of all value set ids and hashes.
+ */
+ public List getValueSetsList() {
+
+ List valueSetItems = valueSetRepository.findAllByOrderByIdAsc();
+ return valueSetItems;
+ }
+
+
+ /**
+ * Gets a value set by its hash value.
+ */
+ @Transactional
+ public ValueSetEntity getValueSetByHash(String hash) {
+
+ return valueSetRepository.findOneByHash(hash);
+ }
+
/**
- * Saves a valueset.
- *
+ * Updates the list of value sets.
+ * @param valueSets list of actual value sets
*/
@Transactional
- public void saveValueSet(String valueSetName, String valueSetData) {
- String hash;
- try {
- hash = businessRulesUtils.calculateHash(valueSetData);
- } catch (NoSuchAlgorithmException e) {
- log.error("Calculation of hash failed:", e);
- return;
+ public void updateValueSets(List valueSets) {
+ List valueSetsHashes = valueSets.stream().map(ValueSetItem::getHash).collect(Collectors.toList());
+ List alreadyStoredValueSets = getValueSetsHashList();
+
+ if (valueSetsHashes.isEmpty()) {
+ valueSetRepository.deleteAll();
+ } else {
+ valueSetRepository.deleteByHashNotIn(valueSetsHashes);
}
+ for (ValueSetItem valueSet : valueSets) {
+ if (!alreadyStoredValueSets.contains(valueSet.getHash())) {
+ saveValueSet(valueSet.getHash(), valueSet.getId(), valueSet.getRawData());
+ }
+ }
+
+ }
+
+ /**
+ * Saves a value set.
+ * @param hash The hash value of the value set data.
+ * @param valueSetName The name of the value set.
+ * @param valueSetData The raw value set data.
+ */
+ @Transactional
+ public void saveValueSet(String hash, String valueSetName, String valueSetData) {
+
ValueSetEntity vse = new ValueSetEntity();
+ vse.setHash(hash);
vse.setId(valueSetName);
vse.setRawData(valueSetData);
- vse.setHash(hash);
valueSetRepository.save(vse);
}
/**
- * gets list of all valueset ids and hashes.
+ * Creates a List of value set items from a map of value sets without hashes.
+ * @param valueSetMap the map containing the row value sets.
+ * @return List of ValueSetItems
*/
- public List getValueSetsList() {
+ public List createValueSetItemListFromMap(Map valueSetMap)
+ throws NoSuchAlgorithmException {
+ List valueSetItems = new ArrayList<>();
+
+ for (Map.Entry vse: valueSetMap.entrySet()) {
+ ValueSetItem valueSetItem = new ValueSetItem();
+ valueSetItem.setHash(businessRulesUtils.calculateHash(vse.getValue()));
+ valueSetItem.setId(vse.getKey());
+ valueSetItem.setRawData(vse.getValue());
+ valueSetItems.add(valueSetItem);
+ }
- List valueSetItems = valueSetRepository.findAllByOrderByIdAsc();
return valueSetItems;
}
-
/**
- * Gets valueset by hash.
+ * Gets a list of hash values of all stored value sets.
+ * @return List of hash values
*/
- @Transactional
- public ValueSetEntity getValueSetByHash(String hash) {
-
- return valueSetRepository.findOneByHash(hash);
+ private List getValueSetsHashList() {
+ return getValueSetsList().stream().map(ValueSetListItemDto::getHash).collect(Collectors.toList());
}
}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/utils/BusinessRulesUtils.java b/src/main/java/eu/europa/ec/dgc/businessrule/utils/BusinessRulesUtils.java
index fb4f367..fa00da5 100644
--- a/src/main/java/eu/europa/ec/dgc/businessrule/utils/BusinessRulesUtils.java
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/utils/BusinessRulesUtils.java
@@ -1,3 +1,23 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.utils;
import java.math.BigInteger;
diff --git a/src/main/resources/application-btp.yml b/src/main/resources/application-btp.yml
index aadec68..133216a 100644
--- a/src/main/resources/application-btp.yml
+++ b/src/main/resources/application-btp.yml
@@ -2,3 +2,9 @@ dgc:
gateway:
connector:
enabled: false
+ tls-trust-store:
+ path: false
+ tls-key-store:
+ path: false
+ trust-anchor:
+ path: false
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index a3c5cce..a9e0409 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -2,7 +2,7 @@ server:
port: 8080
spring:
application:
- name: dgca-verifier-service
+ name: dgca-businessrule-service
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:dgc;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;
@@ -46,7 +46,32 @@ springdoc:
swagger-ui:
path: /swagger
dgc:
- certificatesDownloader:
- timeInterval: 60000
- lockLimit: 1800000
+ businessRulesDownload:
+ timeInterval: 1800000
+ lockLimit: 3600000
+ valueSetsDownload:
+ timeInterval: 1800000
+ lockLimit: 3600000
+ countryListDownload:
+ timeInterval: 1800000
+ lockLimit: 3600000
+ gateway:
+ connector:
+ enabled: true
+ endpoint: https://dgc-gateway.example.com
+ proxy:
+ enabled: false
+ max-cache-age: 300
+ tls-trust-store:
+ password: dgcg-p4ssw0rd
+ path: classpath:tls_trust_store.p12
+ tls-key-store:
+ alias: 1
+ password: dgcg-p4ssw0rd
+ path: classpath:tls_key_store.p12
+ trust-anchor:
+ alias: ta
+ password: dgcg-p4ssw0rd
+ path: classpath:trust_anchor.jks
+
diff --git a/src/main/resources/static/valuesets/country-2-codes.json b/src/main/resources/static/valuesets/country-2-codes.json
index 7fd5aa6..50edfcd 100644
--- a/src/main/resources/static/valuesets/country-2-codes.json
+++ b/src/main/resources/static/valuesets/country-2-codes.json
@@ -1746,4 +1746,4 @@
"version": ""
}
}
-}
+}
\ No newline at end of file
diff --git a/src/test/java/eu/europa/ec/dgc/businessrule/OpenApiTest.java b/src/test/java/eu/europa/ec/dgc/businessrule/OpenApiTest.java
index 43f845d..11b9538 100644
--- a/src/test/java/eu/europa/ec/dgc/businessrule/OpenApiTest.java
+++ b/src/test/java/eu/europa/ec/dgc/businessrule/OpenApiTest.java
@@ -1,6 +1,29 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValueSetDownloadConnector;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.net.URL;
@@ -21,6 +44,14 @@
)
class OpenApiTest {
+ @MockBean
+ DgcGatewayValidationRuleDownloadConnector dgcGatewayValidationRuleDownloadConnector;
+
+ @MockBean
+ DgcGatewayValueSetDownloadConnector dgcGatewayValueSetDownloadConnector;
+
+ @MockBean
+ DgcGatewayCountryListDownloadConnector dgcGatewayCountryListDownloadConnector;
@Test
void apiDocs() {
diff --git a/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/BusinessRuleControllerIntegrationTest.java b/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/BusinessRuleControllerIntegrationTest.java
new file mode 100644
index 0000000..5b6bf54
--- /dev/null
+++ b/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/BusinessRuleControllerIntegrationTest.java
@@ -0,0 +1,351 @@
+package eu.europa.ec.dgc.businessrule.restapi.controller;
+
+import eu.europa.ec.dgc.businessrule.repository.BusinessRuleRepository;
+import eu.europa.ec.dgc.businessrule.testdata.BusinessRulesTestHelper;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValueSetDownloadConnector;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class BusinessRuleControllerIntegrationTest {
+
+ private static final String API_VERSION_HEADER = "X-VERSION";
+
+ @MockBean
+ DgcGatewayValidationRuleDownloadConnector dgcGatewayValidationRuleDownloadConnector;
+
+ @MockBean
+ DgcGatewayValueSetDownloadConnector dgcGatewayValueSetDownloadConnector;
+
+ @MockBean
+ DgcGatewayCountryListDownloadConnector dgcGatewayCountryListDownloadConnector;
+
+ @Autowired
+ BusinessRuleRepository businessRuleRepository;
+
+ @Autowired
+ BusinessRulesTestHelper businessRulesTestHelper;
+
+ @Autowired
+ private MockMvc mockMvc;
+
+
+ @BeforeEach
+ void clearRepositoryData() {
+ businessRuleRepository.deleteAll();
+ }
+
+ @Test
+ void getEmptyRulesList() throws Exception {
+ mockMvc.perform(get("/rules").header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json("[]"));
+ }
+
+ @Test
+ void getRulesList() throws Exception {
+ String expectedJson = "[{\"identifier\":\"VR-DE-1\",\"version\":\"1.0.0\",\"country\":\"DE\",\"hash\":"
+ + "\"ce50e623fd57e482ad9edf63eae7c898d639056e716aeb7f9975a3471bf3e59c\"},{\"identifier\":\"VR-DE-2\","
+ + "\"version\":\"1.0.0\",\"country\":\"DE\",\"hash\":"
+ + "\"edd69d42d52a7b52059cfbea379e647039fc16117b75bf3dfec68c965552a2fd\"},{\"identifier\":\"VR-EU-1\","
+ + "\"version\":\"1.0.0\",\"country\":\"EU\",\"hash\":"
+ + "\"7bbffe1ac60dc201cf4a1303de4b8ba25ffa5ab714d882a7e4e80dfbb2c08fe7\"}]";
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_2,
+ BusinessRulesTestHelper.BR_IDENTIFIER_2, BusinessRulesTestHelper.BR_COUNTRY_2,
+ BusinessRulesTestHelper.BR_VERSION_2, BusinessRulesTestHelper.BR_DATA_2);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_3,
+ BusinessRulesTestHelper.BR_IDENTIFIER_3, BusinessRulesTestHelper.BR_COUNTRY_3,
+ BusinessRulesTestHelper.BR_VERSION_3, BusinessRulesTestHelper.BR_DATA_3);
+
+ mockMvc.perform(get("/rules").header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+ }
+
+ @Test
+ void getRulesListSameRuleWithDiffrentVersions() throws Exception {
+ String expectedJson = "[{\"identifier\":\"VR-DE-1\",\"version\":\"1.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"ce50e623fd57e482ad9edf63eae7c898d639056e716aeb7f9975a3471bf3e59c\"},"
+ + "{\"identifier\":\"VR-DE-1\",\"version\":\"2.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"1706b888b9abc095e78ab1ebf32f2445a36c6a263b72634ae56476ecac5c89de\"},"
+ + "{\"identifier\":\"VR-DE-2\",\"version\":\"1.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"edd69d42d52a7b52059cfbea379e647039fc16117b75bf3dfec68c965552a2fd\"},"
+ + "{\"identifier\":\"VR-EU-1\",\"version\":\"1.0.0\",\"country\":\"EU\","
+ + "\"hash\":\"7bbffe1ac60dc201cf4a1303de4b8ba25ffa5ab714d882a7e4e80dfbb2c08fe7\"}]";
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_2,
+ BusinessRulesTestHelper.BR_IDENTIFIER_2, BusinessRulesTestHelper.BR_COUNTRY_2,
+ BusinessRulesTestHelper.BR_VERSION_2, BusinessRulesTestHelper.BR_DATA_2);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_3,
+ BusinessRulesTestHelper.BR_IDENTIFIER_3, BusinessRulesTestHelper.BR_COUNTRY_3,
+ BusinessRulesTestHelper.BR_VERSION_3, BusinessRulesTestHelper.BR_DATA_3);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_4,
+ BusinessRulesTestHelper.BR_IDENTIFIER_4, BusinessRulesTestHelper.BR_COUNTRY_4,
+ BusinessRulesTestHelper.BR_VERSION_4, BusinessRulesTestHelper.BR_DATA_4);
+
+
+ mockMvc.perform(get("/rules").header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+ }
+
+ @Test
+ void getEmptyRulesListForCountry() throws Exception {
+ mockMvc.perform(get("/rules/" + BusinessRulesTestHelper.BR_COUNTRY_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json("[]"));
+ }
+
+ @Test
+ void getRulesListForCountry() throws Exception {
+ String expectedJson = "[{\"identifier\":\"VR-DE-1\",\"version\":\"1.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"ce50e623fd57e482ad9edf63eae7c898d639056e716aeb7f9975a3471bf3e59c\"},"
+ + "{\"identifier\":\"VR-DE-2\",\"version\":\"1.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"edd69d42d52a7b52059cfbea379e647039fc16117b75bf3dfec68c965552a2fd\"}]";
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_2,
+ BusinessRulesTestHelper.BR_IDENTIFIER_2, BusinessRulesTestHelper.BR_COUNTRY_2,
+ BusinessRulesTestHelper.BR_VERSION_2, BusinessRulesTestHelper.BR_DATA_2);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_3,
+ BusinessRulesTestHelper.BR_IDENTIFIER_3, BusinessRulesTestHelper.BR_COUNTRY_3,
+ BusinessRulesTestHelper.BR_VERSION_3, BusinessRulesTestHelper.BR_DATA_3);
+
+ mockMvc.perform(get("/rules/" + BusinessRulesTestHelper.BR_COUNTRY_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+ }
+
+ @Test
+ void getRulesListForCountryRuleWithDiffrentVersions() throws Exception {
+ String expectedJson = "[{\"identifier\":\"VR-DE-1\",\"version\":\"1.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"ce50e623fd57e482ad9edf63eae7c898d639056e716aeb7f9975a3471bf3e59c\"},"
+ + "{\"identifier\":\"VR-DE-1\",\"version\":\"2.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"1706b888b9abc095e78ab1ebf32f2445a36c6a263b72634ae56476ecac5c89de\"},"
+ + "{\"identifier\":\"VR-DE-2\",\"version\":\"1.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"edd69d42d52a7b52059cfbea379e647039fc16117b75bf3dfec68c965552a2fd\"}]";
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_2,
+ BusinessRulesTestHelper.BR_IDENTIFIER_2, BusinessRulesTestHelper.BR_COUNTRY_2,
+ BusinessRulesTestHelper.BR_VERSION_2, BusinessRulesTestHelper.BR_DATA_2);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_3,
+ BusinessRulesTestHelper.BR_IDENTIFIER_3, BusinessRulesTestHelper.BR_COUNTRY_3,
+ BusinessRulesTestHelper.BR_VERSION_3, BusinessRulesTestHelper.BR_DATA_3);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_4,
+ BusinessRulesTestHelper.BR_IDENTIFIER_4, BusinessRulesTestHelper.BR_COUNTRY_4,
+ BusinessRulesTestHelper.BR_VERSION_4, BusinessRulesTestHelper.BR_DATA_4);
+
+ mockMvc.perform(get("/rules/" + BusinessRulesTestHelper.BR_COUNTRY_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+ }
+
+ @Test
+ void getRulesListForCountryWrongCountryFormat() throws Exception {
+ String expectedJson = "{\"code\":\"0x004\",\"problem\":\"Possible reasons: The Country Code has a wrong format."
+ + " Should be 2 char format.\",\"sendValue\":\"EUR\",\"details\":\"\"}";
+
+ mockMvc.perform(get("/rules/EUR")
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isBadRequest())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+
+ expectedJson = "{\"code\":\"0x004\",\"problem\":\"Possible reasons: The Country Code has a wrong format."
+ + " Should be 2 char format.\",\"sendValue\":\"E\",\"details\":\"\"}";
+
+ mockMvc.perform(get("/rules/E")
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isBadRequest())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+
+ expectedJson = "{\"code\":\"0x004\",\"problem\":\"Possible reasons: The Country Code has a wrong format."
+ + " Should be 2 char format.\",\"sendValue\":\"22\",\"details\":\"\"}";
+
+ mockMvc.perform(get("/rules/22")
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isBadRequest())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+ }
+
+ @Test
+ void getRuleByCountryAndHash() throws Exception {
+ String expectedJson = "[{\"identifier\":\"VR-DE-1\",\"version\":\"1.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"ce50e623fd57e482ad9edf63eae7c898d639056e716aeb7f9975a3471bf3e59c\"},"
+ + "{\"identifier\":\"VR-DE-1\",\"version\":\"2.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"1706b888b9abc095e78ab1ebf32f2445a36c6a263b72634ae56476ecac5c89de\"},"
+ + "{\"identifier\":\"VR-DE-2\",\"version\":\"1.0.0\",\"country\":\"DE\","
+ + "\"hash\":\"edd69d42d52a7b52059cfbea379e647039fc16117b75bf3dfec68c965552a2fd\"}]";
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_2,
+ BusinessRulesTestHelper.BR_IDENTIFIER_2, BusinessRulesTestHelper.BR_COUNTRY_2,
+ BusinessRulesTestHelper.BR_VERSION_2, BusinessRulesTestHelper.BR_DATA_2);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_3,
+ BusinessRulesTestHelper.BR_IDENTIFIER_3, BusinessRulesTestHelper.BR_COUNTRY_3,
+ BusinessRulesTestHelper.BR_VERSION_3, BusinessRulesTestHelper.BR_DATA_3);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_4,
+ BusinessRulesTestHelper.BR_IDENTIFIER_4, BusinessRulesTestHelper.BR_COUNTRY_4,
+ BusinessRulesTestHelper.BR_VERSION_4, BusinessRulesTestHelper.BR_DATA_4);
+
+ mockMvc.perform(get("/rules/" + BusinessRulesTestHelper.BR_COUNTRY_1 + "/"
+ + BusinessRulesTestHelper.BR_HASH_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(BusinessRulesTestHelper.BR_DATA_1));
+ }
+
+ @Test
+ void getRuleByCountryAndHashWrongCountryFormat() throws Exception {
+ String expectedJson = "{\"code\":\"0x004\",\"problem\":\"Possible reasons: The Country Code has a wrong format."
+ + " Should be 2 char format.\",\"sendValue\":\"EUR\",\"details\":\"\"}";
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_2,
+ BusinessRulesTestHelper.BR_IDENTIFIER_2, BusinessRulesTestHelper.BR_COUNTRY_2,
+ BusinessRulesTestHelper.BR_VERSION_2, BusinessRulesTestHelper.BR_DATA_2);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_3,
+ BusinessRulesTestHelper.BR_IDENTIFIER_3, BusinessRulesTestHelper.BR_COUNTRY_3,
+ BusinessRulesTestHelper.BR_VERSION_3, BusinessRulesTestHelper.BR_DATA_3);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_4,
+ BusinessRulesTestHelper.BR_IDENTIFIER_4, BusinessRulesTestHelper.BR_COUNTRY_4,
+ BusinessRulesTestHelper.BR_VERSION_4, BusinessRulesTestHelper.BR_DATA_4);
+
+ mockMvc.perform(get("/rules/EUR/" + BusinessRulesTestHelper.BR_HASH_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isBadRequest())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+
+ expectedJson = "{\"code\":\"0x004\",\"problem\":\"Possible reasons: The Country Code has a wrong format."
+ + " Should be 2 char format.\",\"sendValue\":\"E\",\"details\":\"\"}";
+
+ mockMvc.perform(get("/rules/E/" + BusinessRulesTestHelper.BR_HASH_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isBadRequest())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+
+ expectedJson = "{\"code\":\"0x004\",\"problem\":\"Possible reasons: The Country Code has a wrong format."
+ + " Should be 2 char format.\",\"sendValue\":\"23\",\"details\":\"\"}";
+
+ mockMvc.perform(get("/rules/23/" + BusinessRulesTestHelper.BR_HASH_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isBadRequest())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+ }
+
+ @Test
+ void getRuleByCountryAndHashWrongCountryHashCombination() throws Exception {
+ String expectedJson = "{\"code\":\"0x006\",\"problem\":\"Possible reasons: The provided hash or country may "
+ + "not be correct.\",\"sendValue\":\"country: EU, "
+ + "hash: ce50e623fd57e482ad9edf63eae7c898d639056e716aeb7f9975a3471bf3e59c\",\"details\":\"\"}";
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_2,
+ BusinessRulesTestHelper.BR_IDENTIFIER_2, BusinessRulesTestHelper.BR_COUNTRY_2,
+ BusinessRulesTestHelper.BR_VERSION_2, BusinessRulesTestHelper.BR_DATA_2);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_3,
+ BusinessRulesTestHelper.BR_IDENTIFIER_3, BusinessRulesTestHelper.BR_COUNTRY_3,
+ BusinessRulesTestHelper.BR_VERSION_3, BusinessRulesTestHelper.BR_DATA_3);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_4,
+ BusinessRulesTestHelper.BR_IDENTIFIER_4, BusinessRulesTestHelper.BR_COUNTRY_4,
+ BusinessRulesTestHelper.BR_VERSION_4, BusinessRulesTestHelper.BR_DATA_4);
+
+ mockMvc.perform(get("/rules/" + BusinessRulesTestHelper.BR_COUNTRY_3
+ + "/" + BusinessRulesTestHelper.BR_HASH_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isNotFound())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+ }
+
+ @Test
+ void getRuleByCountryAndHashNotExist() throws Exception {
+ String expectedJson = "{\"code\":\"0x006\",\"problem\":\"Possible reasons: The provided hash or country may "
+ + "not be correct.\",\"sendValue\":\"country: DE, "
+ + "hash: ce50e623fd57e482ad9edf63eae7c898d639056e716aeb7f9975a3471bf3e59c\",\"details\":\"\"}";
+
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_2,
+ BusinessRulesTestHelper.BR_IDENTIFIER_2, BusinessRulesTestHelper.BR_COUNTRY_2,
+ BusinessRulesTestHelper.BR_VERSION_2, BusinessRulesTestHelper.BR_DATA_2);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_3,
+ BusinessRulesTestHelper.BR_IDENTIFIER_3, BusinessRulesTestHelper.BR_COUNTRY_3,
+ BusinessRulesTestHelper.BR_VERSION_3, BusinessRulesTestHelper.BR_DATA_3);
+
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_4,
+ BusinessRulesTestHelper.BR_IDENTIFIER_4, BusinessRulesTestHelper.BR_COUNTRY_4,
+ BusinessRulesTestHelper.BR_VERSION_4, BusinessRulesTestHelper.BR_DATA_4);
+
+ mockMvc.perform(get("/rules/" + BusinessRulesTestHelper.BR_COUNTRY_1
+ + "/" + BusinessRulesTestHelper.BR_HASH_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isNotFound())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/CountryListControllerIntegrationTest.java b/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/CountryListControllerIntegrationTest.java
index d1aa0f8..b169ada 100644
--- a/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/CountryListControllerIntegrationTest.java
+++ b/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/CountryListControllerIntegrationTest.java
@@ -1,12 +1,36 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
package eu.europa.ec.dgc.businessrule.restapi.controller;
import eu.europa.ec.dgc.businessrule.entity.CountryListEntity;
import eu.europa.ec.dgc.businessrule.repository.CountryListRepository;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValueSetDownloadConnector;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -23,6 +47,15 @@ class CountryListControllerIntegrationTest {
+ "\"CZ\", \"FR\", \"HU\", \"SI\", \"DK\", \"HR\", \"MT\", \"SK\", \"DE\", \"IT\", \"NL\", \"FI\", \"EE\", "
+ "\"CY\", \"AT\", \"SE\", \"IE\", \"LV\", \"PL\"]";
+ @MockBean
+ DgcGatewayValidationRuleDownloadConnector dgcGatewayValidationRuleDownloadConnector;
+
+ @MockBean
+ DgcGatewayValueSetDownloadConnector dgcGatewayValueSetDownloadConnector;
+
+ @MockBean
+ DgcGatewayCountryListDownloadConnector dgcGatewayCountryListDownloadConnector;
+
@Autowired
CountryListRepository countryListRepository;
diff --git a/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/ValueSetControllerIntegrationTest.java b/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/ValueSetControllerIntegrationTest.java
new file mode 100644
index 0000000..c134c59
--- /dev/null
+++ b/src/test/java/eu/europa/ec/dgc/businessrule/restapi/controller/ValueSetControllerIntegrationTest.java
@@ -0,0 +1,161 @@
+/*-
+ * ---license-start
+ * eu-digital-green-certificates / dgca-businessrule-service
+ * ---
+ * Copyright (C) 2021 T-Systems International GmbH and all other contributors
+ * ---
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ---license-end
+ */
+
+package eu.europa.ec.dgc.businessrule.restapi.controller;
+
+import eu.europa.ec.dgc.businessrule.repository.ValueSetRepository;
+import eu.europa.ec.dgc.businessrule.testdata.BusinessRulesTestHelper;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValueSetDownloadConnector;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class ValueSetControllerIntegrationTest {
+
+ private static final String API_VERSION_HEADER = "X-VERSION";
+
+ @MockBean
+ DgcGatewayValidationRuleDownloadConnector dgcGatewayValidationRuleDownloadConnector;
+
+ @MockBean
+ DgcGatewayValueSetDownloadConnector dgcGatewayValueSetDownloadConnector;
+
+ @MockBean
+ DgcGatewayCountryListDownloadConnector dgcGatewayCountryListDownloadConnector;
+
+
+ @Autowired
+ ValueSetRepository valueSetRepository;
+
+ @Autowired
+ BusinessRulesTestHelper businessRulesTestHelper;
+
+ @Autowired
+ private MockMvc mockMvc;
+
+
+
+ @BeforeEach
+ void clearRepositoryData() {
+ valueSetRepository.deleteAll();
+ }
+
+ @Test
+ void getEmptyValueSetList() throws Exception {
+ mockMvc.perform(get("/valuesets").header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json("[]"));
+ }
+
+
+
+ @Test
+ void getValueSetList() throws Exception {
+
+ String expectedJson = "[{\"id\":\""+BusinessRulesTestHelper.VALUESET_IDENTIFIER_1 +"\","
+ + "\"hash\":\""+BusinessRulesTestHelper.VALUESET_HASH_1+"\"},"
+ + "{\"id\":\""+BusinessRulesTestHelper.VALUESET_IDENTIFIER_2 +"\","
+ + "\"hash\":\""+BusinessRulesTestHelper.VALUESET_HASH_2+"\"}]";
+
+ businessRulesTestHelper.insertValueSet(BusinessRulesTestHelper.VALUESET_HASH_1,
+ BusinessRulesTestHelper.VALUESET_IDENTIFIER_1,
+ BusinessRulesTestHelper.VALUESET_DATA_1);
+
+ businessRulesTestHelper.insertValueSet(BusinessRulesTestHelper.VALUESET_HASH_2,
+ BusinessRulesTestHelper.VALUESET_IDENTIFIER_2,
+ BusinessRulesTestHelper.VALUESET_DATA_2);
+
+ mockMvc.perform(get("/valuesets").header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+ }
+
+
+ @Test
+ void getValueSet() throws Exception {
+ businessRulesTestHelper.insertValueSet(BusinessRulesTestHelper.VALUESET_HASH_1,
+ BusinessRulesTestHelper.VALUESET_IDENTIFIER_1,
+ BusinessRulesTestHelper.VALUESET_DATA_1);
+
+ businessRulesTestHelper.insertValueSet(BusinessRulesTestHelper.VALUESET_HASH_2,
+ BusinessRulesTestHelper.VALUESET_IDENTIFIER_2,
+ BusinessRulesTestHelper.VALUESET_DATA_2);
+
+ mockMvc.perform(get("/valuesets/" + BusinessRulesTestHelper.VALUESET_HASH_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(BusinessRulesTestHelper.VALUESET_DATA_1));
+
+ mockMvc.perform(get("/valuesets/" + BusinessRulesTestHelper.VALUESET_HASH_2)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(BusinessRulesTestHelper.VALUESET_DATA_2));
+
+ }
+
+ @Test
+ void getValueSetNotExist() throws Exception {
+
+ String expectedJson = "{\"code\":\"0x001\",\"problem\":\"Possible reasons: The provided hash value is "
+ + "not correct\",\"sendValue\":\""+BusinessRulesTestHelper.VALUESET_HASH_1+"\",\"details\":\"\"}";
+
+
+ mockMvc.perform(get("/valuesets/" + BusinessRulesTestHelper.VALUESET_HASH_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isNotFound())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+
+ businessRulesTestHelper.insertValueSet(BusinessRulesTestHelper.VALUESET_HASH_2,
+ BusinessRulesTestHelper.VALUESET_IDENTIFIER_2,
+ BusinessRulesTestHelper.VALUESET_DATA_2);
+
+ mockMvc.perform(get("/valuesets/" + BusinessRulesTestHelper.VALUESET_HASH_2)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(BusinessRulesTestHelper.VALUESET_DATA_2));
+
+ mockMvc.perform(get("/valuesets/" + BusinessRulesTestHelper.VALUESET_HASH_1)
+ .header(API_VERSION_HEADER, "1.0"))
+ .andExpect(status().isNotFound())
+ .andExpect(content().contentType(MediaType.APPLICATION_JSON))
+ .andExpect(content().json(expectedJson));
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/test/java/eu/europa/ec/dgc/businessrule/service/BusinessRuleServiceTest.java b/src/test/java/eu/europa/ec/dgc/businessrule/service/BusinessRuleServiceTest.java
new file mode 100644
index 0000000..22fcde8
--- /dev/null
+++ b/src/test/java/eu/europa/ec/dgc/businessrule/service/BusinessRuleServiceTest.java
@@ -0,0 +1,176 @@
+package eu.europa.ec.dgc.businessrule.service;
+
+import eu.europa.ec.dgc.businessrule.entity.BusinessRuleEntity;
+import eu.europa.ec.dgc.businessrule.model.BusinessRuleItem;
+import eu.europa.ec.dgc.businessrule.repository.BusinessRuleRepository;
+import eu.europa.ec.dgc.businessrule.testdata.BusinessRulesTestHelper;
+import eu.europa.ec.dgc.businessrule.utils.BusinessRulesUtils;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValueSetDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.model.ValidationRule;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class BusinessRuleServiceTest {
+
+ @MockBean
+ DgcGatewayValidationRuleDownloadConnector dgcGatewayValidationRuleDownloadConnector;
+
+ @MockBean
+ DgcGatewayValueSetDownloadConnector dgcGatewayValueSetDownloadConnector;
+
+ @MockBean
+ DgcGatewayCountryListDownloadConnector dgcGatewayCountryListDownloadConnector;
+
+ @Autowired
+ BusinessRuleService businessRuleService;
+
+ @Autowired
+ BusinessRuleRepository businessRuleRepository;
+
+ @Autowired
+ BusinessRulesTestHelper businessRulesTestHelper;
+
+ @Autowired
+ BusinessRulesUtils businessRulesUtils;
+
+ @BeforeEach
+ void clearRepositoryData() {
+ businessRuleRepository.deleteAll();
+ }
+
+ @Test
+ void updateBusinessRulesWithExisting() throws Exception {
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ List businessRuleItems = new ArrayList<>();
+
+ BusinessRuleItem businessRuleItem = new BusinessRuleItem();
+
+ businessRuleItem.setHash(businessRulesUtils.calculateHash(BusinessRulesTestHelper.BR_DATA_1));
+ businessRuleItem.setIdentifier(BusinessRulesTestHelper.BR_IDENTIFIER_1);
+ businessRuleItem.setCountry(BusinessRulesTestHelper.BR_COUNTRY_1);
+ businessRuleItem.setVersion(BusinessRulesTestHelper.BR_VERSION_1);
+ businessRuleItem.setRawData(BusinessRulesTestHelper.BR_DATA_1);
+ businessRuleItems.add(businessRuleItem);
+
+ businessRuleService.updateBusinesRules(businessRuleItems);
+
+ Assertions.assertEquals(1, businessRuleRepository.count());
+ }
+
+ @Test
+ void updateBusinessRulesWithEmptyList() {
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ List businessRuleItems = new ArrayList<>();
+
+ businessRuleService.updateBusinesRules(businessRuleItems);
+
+ Assertions.assertEquals(0, businessRuleRepository.count());
+ }
+
+ @Test
+ void updateBusinessRule() throws Exception {
+ businessRulesTestHelper.insertBusinessRule(BusinessRulesTestHelper.BR_HASH_1,
+ BusinessRulesTestHelper.BR_IDENTIFIER_1, BusinessRulesTestHelper.BR_COUNTRY_1,
+ BusinessRulesTestHelper.BR_VERSION_1, BusinessRulesTestHelper.BR_DATA_1);
+
+ List businessRuleItems = new ArrayList<>();
+
+ BusinessRuleItem businessRuleItem = new BusinessRuleItem();
+
+ businessRuleItem.setHash(businessRulesUtils.calculateHash(BusinessRulesTestHelper.BR_DATA_1));
+ businessRuleItem.setIdentifier(BusinessRulesTestHelper.BR_IDENTIFIER_1);
+ businessRuleItem.setCountry(BusinessRulesTestHelper.BR_COUNTRY_1);
+ businessRuleItem.setVersion(BusinessRulesTestHelper.BR_VERSION_1);
+ businessRuleItem.setRawData(BusinessRulesTestHelper.BR_DATA_1);
+ businessRuleItems.add(businessRuleItem);
+
+ BusinessRuleItem Item2 = new BusinessRuleItem();
+
+ Item2.setHash(businessRulesUtils.calculateHash(BusinessRulesTestHelper.BR_DATA_2));
+ Item2.setIdentifier(BusinessRulesTestHelper.BR_IDENTIFIER_2);
+ Item2.setCountry(BusinessRulesTestHelper.BR_COUNTRY_2);
+ Item2.setVersion(BusinessRulesTestHelper.BR_VERSION_2);
+ Item2.setRawData(BusinessRulesTestHelper.BR_DATA_2);
+ businessRuleItems.add(Item2);
+
+ businessRuleService.updateBusinesRules(businessRuleItems);
+
+ Assertions.assertEquals(2, businessRuleRepository.count());
+
+ businessRuleItems.remove(0);
+
+ businessRuleService.updateBusinesRules(businessRuleItems);
+
+ List result = businessRuleRepository.findAll();
+ Assertions.assertEquals(1, result.size());
+
+ BusinessRuleEntity resultEntity = result.get(0);
+ Assertions.assertEquals(businessRulesUtils.calculateHash(BusinessRulesTestHelper.BR_DATA_2),
+ resultEntity.getHash());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_IDENTIFIER_2, resultEntity.getIdentifier());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_COUNTRY_2, resultEntity.getCountry());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_VERSION_2, resultEntity.getVersion());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_DATA_2, resultEntity.getRawData());
+ }
+
+
+ @Test
+ void createBusinessRuleItemList() throws Exception{
+ List validationRules = new ArrayList<>();
+ List businessRuleItems;
+
+ ValidationRule item1 = new ValidationRule();
+ item1.setIdentifier(BusinessRulesTestHelper.BR_IDENTIFIER_1);
+ item1.setVersion(BusinessRulesTestHelper.BR_VERSION_1);
+ item1.setCountry(BusinessRulesTestHelper.BR_COUNTRY_1);
+ item1.setRawJson(BusinessRulesTestHelper.BR_DATA_1);
+
+ validationRules.add(item1);
+
+ ValidationRule item2 = new ValidationRule();
+ item2.setIdentifier(BusinessRulesTestHelper.BR_IDENTIFIER_3);
+ item2.setVersion(BusinessRulesTestHelper.BR_VERSION_3);
+ item2.setCountry(BusinessRulesTestHelper.BR_COUNTRY_3);
+ item2.setRawJson(BusinessRulesTestHelper.BR_DATA_3);
+
+ validationRules.add(item2);
+
+ businessRuleItems = businessRuleService.createBusinessRuleItemList(validationRules);
+
+ Assertions.assertEquals(2, businessRuleItems.size());
+
+ BusinessRuleItem resultItem1 = businessRuleItems.get(0);
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_HASH_1, resultItem1.getHash());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_IDENTIFIER_1, resultItem1.getIdentifier());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_VERSION_1, resultItem1.getVersion());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_COUNTRY_1, resultItem1.getCountry());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_DATA_1, resultItem1.getRawData());
+
+ BusinessRuleItem resultItem2 = businessRuleItems.get(1);
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_HASH_3, resultItem2.getHash());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_IDENTIFIER_3, resultItem2.getIdentifier());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_VERSION_3, resultItem2.getVersion());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_COUNTRY_3, resultItem2.getCountry());
+ Assertions.assertEquals(BusinessRulesTestHelper.BR_DATA_3, resultItem2.getRawData());
+
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/eu/europa/ec/dgc/businessrule/service/CountryListServiceTest.java b/src/test/java/eu/europa/ec/dgc/businessrule/service/CountryListServiceTest.java
new file mode 100644
index 0000000..92c035d
--- /dev/null
+++ b/src/test/java/eu/europa/ec/dgc/businessrule/service/CountryListServiceTest.java
@@ -0,0 +1,77 @@
+package eu.europa.ec.dgc.businessrule.service;
+
+import eu.europa.ec.dgc.businessrule.entity.CountryListEntity;
+import eu.europa.ec.dgc.businessrule.repository.CountryListRepository;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValueSetDownloadConnector;
+import java.util.List;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class CountryListServiceTest {
+
+ @MockBean
+ DgcGatewayValidationRuleDownloadConnector dgcGatewayValidationRuleDownloadConnector;
+
+ @MockBean
+ DgcGatewayValueSetDownloadConnector dgcGatewayValueSetDownloadConnector;
+
+ @MockBean
+ DgcGatewayCountryListDownloadConnector dgcGatewayCountryListDownloadConnector;
+
+ @Autowired
+ CountryListService countryListService;
+
+ @Autowired
+ CountryListRepository countryListRepository;
+
+ @BeforeEach
+ void clearRepositoryData() {
+ countryListRepository.deleteAll();
+ }
+
+
+ @Test
+ void updateCountryList() {
+ String countryList_1 = "[\"BE\", \"EL\", \"LT\", \"PT\", \"BG\"]";
+ String countryList_2 = "[\"SE\", \"DE\", \"EU\", \"CZ\", \"DK\"]";
+
+ countryListService.updateCountryList(countryList_1);
+
+ List cl = countryListRepository.findAll();
+ Assertions.assertEquals(1, cl.size());
+ CountryListEntity cle = cl.get(0);
+ Assertions.assertEquals(countryList_1, cle.getRawData());
+
+ countryListService.updateCountryList(countryList_2);
+
+ cl = countryListRepository.findAll();
+ Assertions.assertEquals(1, cl.size());
+ cle = cl.get(0);
+ Assertions.assertEquals(countryList_2, cle.getRawData());
+
+ countryListService.updateCountryList(countryList_2);
+
+ cl = countryListRepository.findAll();
+ Assertions.assertEquals(1, cl.size());
+ cle = cl.get(0);
+ Assertions.assertEquals(countryList_2, cle.getRawData());
+
+ countryListService.updateCountryList(countryList_1);
+
+ cl = countryListRepository.findAll();
+ Assertions.assertEquals(1, cl.size());
+ cle = cl.get(0);
+ Assertions.assertEquals(countryList_1, cle.getRawData());
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/eu/europa/ec/dgc/businessrule/service/ValueSetServiceTest.java b/src/test/java/eu/europa/ec/dgc/businessrule/service/ValueSetServiceTest.java
new file mode 100644
index 0000000..71929fb
--- /dev/null
+++ b/src/test/java/eu/europa/ec/dgc/businessrule/service/ValueSetServiceTest.java
@@ -0,0 +1,146 @@
+package eu.europa.ec.dgc.businessrule.service;
+
+import eu.europa.ec.dgc.businessrule.entity.ValueSetEntity;
+import eu.europa.ec.dgc.businessrule.model.ValueSetItem;
+import eu.europa.ec.dgc.businessrule.repository.ValueSetRepository;
+import eu.europa.ec.dgc.businessrule.testdata.BusinessRulesTestHelper;
+import eu.europa.ec.dgc.businessrule.utils.BusinessRulesUtils;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayCountryListDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValidationRuleDownloadConnector;
+import eu.europa.ec.dgc.gateway.connector.DgcGatewayValueSetDownloadConnector;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+
+
+@SpringBootTest
+@AutoConfigureMockMvc
+class ValueSetServiceTest {
+
+ @MockBean
+ DgcGatewayValidationRuleDownloadConnector dgcGatewayValidationRuleDownloadConnector;
+
+ @MockBean
+ DgcGatewayValueSetDownloadConnector dgcGatewayValueSetDownloadConnector;
+
+ @MockBean
+ DgcGatewayCountryListDownloadConnector dgcGatewayCountryListDownloadConnector;
+
+ @Autowired
+ ValueSetService valueSetService;
+
+ @Autowired
+ ValueSetRepository valueSetRepository;
+
+ @Autowired
+ BusinessRulesTestHelper businessRulesTestHelper;
+
+ @Autowired
+ BusinessRulesUtils businessRulesUtils;
+
+ @BeforeEach
+ void clearRepositoryData() {
+ valueSetRepository.deleteAll();
+ }
+
+ @Test
+ void updateValueSetsWithExisting() {
+ businessRulesTestHelper.insertValueSet(BusinessRulesTestHelper.VALUESET_HASH_1,
+ BusinessRulesTestHelper.VALUESET_IDENTIFIER_1, BusinessRulesTestHelper.VALUESET_DATA_1);
+
+ List items = new ArrayList<>();
+
+ ValueSetItem item = new ValueSetItem();
+ item.setHash(BusinessRulesTestHelper.VALUESET_HASH_1);
+ item.setId(BusinessRulesTestHelper.VALUESET_IDENTIFIER_1);
+ item.setRawData(BusinessRulesTestHelper.VALUESET_DATA_1);
+
+ items.add(item);
+
+ valueSetService.updateValueSets(items);
+
+ Assertions.assertEquals(1, valueSetRepository.count());
+ }
+
+ @Test
+ void updateValueSetsWithEmptyList() {
+ businessRulesTestHelper.insertValueSet(BusinessRulesTestHelper.VALUESET_HASH_1,
+ BusinessRulesTestHelper.VALUESET_IDENTIFIER_1, BusinessRulesTestHelper.VALUESET_DATA_1);
+
+ List items = new ArrayList<>();
+
+ valueSetService.updateValueSets(items);
+
+ Assertions.assertEquals(0, valueSetRepository.count());
+ }
+
+ @Test
+ void updateValueSets() {
+ businessRulesTestHelper.insertValueSet(BusinessRulesTestHelper.VALUESET_HASH_1,
+ BusinessRulesTestHelper.VALUESET_IDENTIFIER_1, BusinessRulesTestHelper.VALUESET_DATA_1);
+
+ List items = new ArrayList<>();
+
+ ValueSetItem item = new ValueSetItem();
+ item.setHash(BusinessRulesTestHelper.VALUESET_HASH_1);
+ item.setId(BusinessRulesTestHelper.VALUESET_IDENTIFIER_1);
+ item.setRawData(BusinessRulesTestHelper.VALUESET_DATA_1);
+
+ items.add(item);
+
+ ValueSetItem item2 = new ValueSetItem();
+ item2.setHash(BusinessRulesTestHelper.VALUESET_HASH_2);
+ item2.setId(BusinessRulesTestHelper.VALUESET_IDENTIFIER_2);
+ item2.setRawData(BusinessRulesTestHelper.VALUESET_DATA_2);
+
+ items.add(item2);
+
+ valueSetService.updateValueSets(items);
+
+ Assertions.assertEquals(2, valueSetRepository.count());
+
+ items.remove(0);
+
+ valueSetService.updateValueSets(items);
+
+ List result = valueSetRepository.findAll();
+ Assertions.assertEquals(1, result.size());
+
+ ValueSetEntity resultEntity = result.get(0);
+ Assertions.assertEquals(BusinessRulesTestHelper.VALUESET_HASH_2, resultEntity.getHash());
+ Assertions.assertEquals(BusinessRulesTestHelper.VALUESET_IDENTIFIER_2, resultEntity.getId());
+ Assertions.assertEquals(BusinessRulesTestHelper.VALUESET_DATA_2, resultEntity.getRawData());
+ }
+
+
+ @Test
+ void createValueSetItemListFromMap() throws Exception{
+ Map map = new HashMap<>();
+ map.put(BusinessRulesTestHelper.VALUESET_IDENTIFIER_1, BusinessRulesTestHelper.VALUESET_DATA_1);
+ map.put(BusinessRulesTestHelper.VALUESET_IDENTIFIER_2, BusinessRulesTestHelper.VALUESET_DATA_2);
+
+ List list = valueSetService.createValueSetItemListFromMap(map);
+
+
+ Assertions.assertEquals(2, list.size());
+
+ ValueSetItem resultItem1 = list.get(0);
+ Assertions.assertEquals(BusinessRulesTestHelper.VALUESET_HASH_1, resultItem1.getHash());
+ Assertions.assertEquals(BusinessRulesTestHelper.VALUESET_IDENTIFIER_1, resultItem1.getId());
+ Assertions.assertEquals(BusinessRulesTestHelper.VALUESET_DATA_1, resultItem1.getRawData());
+
+ ValueSetItem resultItem2 = list.get(1);
+ Assertions.assertEquals(BusinessRulesTestHelper.VALUESET_HASH_2, resultItem2.getHash());
+ Assertions.assertEquals(BusinessRulesTestHelper.VALUESET_IDENTIFIER_2, resultItem2.getId());
+ Assertions.assertEquals(BusinessRulesTestHelper.VALUESET_DATA_2, resultItem2.getRawData());
+
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/eu/europa/ec/dgc/businessrule/testdata/BusinessRulesTestHelper.java b/src/test/java/eu/europa/ec/dgc/businessrule/testdata/BusinessRulesTestHelper.java
new file mode 100644
index 0000000..f041d8e
--- /dev/null
+++ b/src/test/java/eu/europa/ec/dgc/businessrule/testdata/BusinessRulesTestHelper.java
@@ -0,0 +1,187 @@
+package eu.europa.ec.dgc.businessrule.testdata;
+
+import eu.europa.ec.dgc.businessrule.entity.BusinessRuleEntity;
+import eu.europa.ec.dgc.businessrule.entity.ValueSetEntity;
+import eu.europa.ec.dgc.businessrule.repository.BusinessRuleRepository;
+import eu.europa.ec.dgc.businessrule.repository.ValueSetRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class BusinessRulesTestHelper {
+
+ public static final String BR_IDENTIFIER_1 = "VR-DE-1";
+ public static final String BR_HASH_1 = "ce50e623fd57e482ad9edf63eae7c898d639056e716aeb7f9975a3471bf3e59c";
+ public static final String BR_COUNTRY_1 = "DE";
+ public static final String BR_VERSION_1 = "1.0.0";
+ public static final String BR_DATA_1 = "{\n"
+ + " \"Identifier\": \"VR-DE-1\",\n"
+ + " \"Version\": \"1.0.0\",\n"
+ + " \"SchemaVersion\":\"1.0.0\",\n"
+ + " \"Engine\":\"CERTLOGIC\",\n"
+ + " \"EngineVersion\":\"1.0.0\",\n"
+ + " \"Type\":\"Acceptance\",\n"
+ + " \"Country\":\"DE\",\n"
+ + " \"CertificateType\":\"Vaccination\",\n"
+ + " \"Description\":[{\"lang\":\"en\",\"desc\":\"Vaccination must be from June and doses must be 2\"}],\n"
+ + " \"ValidFrom\":\"2021-06-27T07:46:40Z\",\n"
+ + " \"ValidTo\":\"2021-08-01T07:46:40Z\",\n"
+ + " \"AffectedFields\":[\"dt\",\"dn\"],\n"
+ + " \"Logic\":{\n"
+ + " \"and\": [\n"
+ + " {\">=\":[ {\"var\":\"dt\"}, \"2021-06-01T00:00:00Z\" ]},\n"
+ + " {\">=\":[ {\"var\":\"dn\"}, 2 ]}\n"
+ + " ]\n"
+ + " }\n"
+ + "}";
+
+ public static final String BR_IDENTIFIER_2 = "VR-DE-2";
+ public static final String BR_HASH_2 = "edd69d42d52a7b52059cfbea379e647039fc16117b75bf3dfec68c965552a2fd";
+ public static final String BR_COUNTRY_2 = "DE";
+ public static final String BR_VERSION_2 = "1.0.0";
+ public static final String BR_DATA_2 = "{\n"
+ + " \"Identifier\":\"VR-DE-2\",\n"
+ + " \"Type\":\"Acceptance\",\n"
+ + " \"Country\":\"DE\",\n"
+ + " \"Version\":\"1.0.0\",\n"
+ + " \"SchemaVersion\":\"1.0.0\",\n"
+ + " \"Engine\":\"CERTLOGIC\",\n"
+ + " \"EngineVersion\":\"1.0.0\",\n"
+ + " \"CertificateType\":\"Vaccination\",\n"
+ + " \"Description\":[\n"
+ + " {\n"
+ + " \"lang\":\"en\",\n"
+ + " \"desc\":\"Just the following vaccines are valid: Moderna,AstraZeneca,Biontech, J&J\"\n"
+ + " }\n"
+ + " ],\n"
+ + " \"ValidFrom\":\"2021-05-27T07:46:40Z\",\n"
+ + " \"ValidTo\":\"2030-06-01T07:46:40Z\",\n"
+ + " \"AffectedFields\":[\n"
+ + " \"v.0.mp\"\n"
+ + " ],\n"
+ + " \"Logic\":{\n"
+ + " \"in\":[\n"
+ + " {\n"
+ + " \"var\":\"payload.v.0.mp\"\n"
+ + " },\n"
+ + " [\n"
+ + " \"EU/1/20/1528\",\n"
+ + " \"EU/1/20/1507\",\n"
+ + " \"EU/1/21/1529\",\n"
+ + " \"EU/1/20/1525\"\n"
+ + " ]\n"
+ + " ]\n"
+ + " }\n"
+ + "}";
+
+ public static final String BR_IDENTIFIER_3 = "VR-EU-1";
+ public static final String BR_HASH_3 = "7bbffe1ac60dc201cf4a1303de4b8ba25ffa5ab714d882a7e4e80dfbb2c08fe7";
+ public static final String BR_COUNTRY_3 = "EU";
+ public static final String BR_VERSION_3 = "1.0.0";
+ public static final String BR_DATA_3 = "{\n"
+ + " \"Identifier\": \"VR-EU-1\",\n"
+ + " \"Version\": \"1.0.0\",\n"
+ + " \"SchemaVersion\":\"1.0.0\",\n"
+ + " \"Engine\":\"CERTLOGIC\",\n"
+ + " \"EngineVersion\":\"1.0.0\",\n"
+ + " \"Type\":\"Acceptance\",\n"
+ + " \"Country\":\"DE\",\n"
+ + " \"CertificateType\":\"Vaccination\",\n"
+ + " \"Description\":[{\"lang\":\"en\",\"desc\":\"Vaccination must be from June and doses must be 2\"}],\n"
+ + " \"ValidFrom\":\"2021-06-27T07:46:40Z\",\n"
+ + " \"ValidTo\":\"2021-08-01T07:46:40Z\",\n"
+ + " \"AffectedFields\":[\"dt\",\"dn\"],\n"
+ + " \"Logic\":{\n"
+ + " \"and\": [\n"
+ + " {\">=\":[ {\"var\":\"dt\"}, \"2021-06-01T00:00:00Z\" ]},\n"
+ + " {\">=\":[ {\"var\":\"dn\"}, 2 ]}\n"
+ + " ]\n"
+ + " }\n"
+ + "}";
+
+ public static final String BR_IDENTIFIER_4 = "VR-DE-1";
+ public static final String BR_HASH_4 = "1706b888b9abc095e78ab1ebf32f2445a36c6a263b72634ae56476ecac5c89de";
+ public static final String BR_COUNTRY_4 = "DE";
+ public static final String BR_VERSION_4 = "2.0.0";
+ public static final String BR_DATA_4 = "{\n"
+ + " \"Identifier\": \"VR-DE-1\",\n"
+ + " \"Version\": \"2.0.0\",\n"
+ + " \"SchemaVersion\":\"1.0.0\",\n"
+ + " \"Engine\":\"CERTLOGIC\",\n"
+ + " \"EngineVersion\":\"1.0.0\",\n"
+ + " \"Type\":\"Acceptance\",\n"
+ + " \"Country\":\"DE\",\n"
+ + " \"CertificateType\":\"Vaccination\",\n"
+ + " \"Description\":[{\"lang\":\"en\",\"desc\":\"Vaccination must be from June and doses must be 2\"}],\n"
+ + " \"ValidFrom\":\"2021-06-27T07:46:40Z\",\n"
+ + " \"ValidTo\":\"2021-09-01T07:46:40Z\",\n"
+ + " \"AffectedFields\":[\"dt\",\"dn\"],\n"
+ + " \"Logic\":{\n"
+ + " \"and\": [\n"
+ + " {\">=\":[ {\"var\":\"dt\"}, \"2021-06-01T00:00:00Z\" ]},\n"
+ + " {\">=\":[ {\"var\":\"dn\"}, 2 ]}\n"
+ + " ]\n"
+ + " }\n"
+ + "}";
+
+
+ public static final String VALUESET_DATA_1 = "{\n"
+ + " \"valueSetId\": \"sct-vaccines-covid-19\",\n"
+ + " \"valueSetDate\": \"2021-04-27\",\n"
+ + " \"valueSetValues\": {\n"
+ + " \"1119349007\": {\n"
+ + " \"display\": \"SARS-CoV-2 mRNA vaccine\",\n"
+ + " \"lang\": \"en\",\n"
+ + " \"active\": true,\n"
+ + " \"version\": \"http://snomed.info/sct/900000000000207008/version/20210131\",\n"
+ + " \"system\": \"http://snomed.info/sct\"\n"
+ + " }}}";
+
+ public static final String VALUESET_HASH_1 = "7d8a9a79caa9ccc5373209d85eb91c3f6beec6762fa06ddacf0172ec819cd058";
+
+ public static final String VALUESET_IDENTIFIER_1 = "sct-vaccines-covid-19";
+
+ public static final String VALUESET_DATA_2 = "{\n"
+ + " \"valueSetId\": \"vaccines-covid-19-names\",\n"
+ + " \"valueSetDate\": \"2021-04-27\",\n"
+ + " \"valueSetValues\": {\n"
+ + " \"EU/1/20/1528\": {\n"
+ + " \"display\": \"Comirnaty\",\n"
+ + " \"lang\": \"en\",\n"
+ + " \"active\": true,\n"
+ + " \"system\": \"https://ec.europa.eu/health/documents/community-register/html/\",\n"
+ + " \"version\": \"\"\n"
+ + " }}}";
+
+ public static final String VALUESET_HASH_2 = "d2c03840b0e771b02967170bfc7b633702e0932b09f643a6edcd079df1ea096d";
+
+ public static final String VALUESET_IDENTIFIER_2 = "vaccines-covid-19-names";
+
+
+ private final ValueSetRepository valueSetRepository;
+
+ private final BusinessRuleRepository businessRuleRepository;
+
+ public void insertBusinessRule(String hash, String identifier, String country, String version, String data) {
+ BusinessRuleEntity bre = new BusinessRuleEntity();
+ bre.setHash(hash);
+ bre.setIdentifier(identifier);
+ bre.setVersion(version);
+ bre.setCountry(country);
+ bre.setRawData(data);
+
+ businessRuleRepository.save(bre);
+ }
+
+
+ public void insertValueSet(String hash, String identifier, String data) {
+ ValueSetEntity vse = new ValueSetEntity();
+ vse.setHash(hash);
+ vse.setId(identifier);
+ vse.setRawData(data);
+
+ valueSetRepository.save(vse);
+
+ }
+}
diff --git a/src/test/resources/application.yml b/src/test/resources/application.yml
index 04d168c..abd53f6 100644
--- a/src/test/resources/application.yml
+++ b/src/test/resources/application.yml
@@ -5,15 +5,21 @@ spring:
active:
- test
application:
- name: dgca-verifier-service
+ name: dgca-businessrule-service
liquibase:
change-log: classpath:db/changelog.xml
main:
allow-bean-definition-overriding: true
dgc:
- synchroniseCertificates:
- timeInterval: 60000
- lockLimit: 1800000
+ businessRulesDownload:
+ timeInterval: 1800000
+ lockLimit: 3600000
+ valueSetsDownload:
+ timeInterval: 1800000
+ lockLimit: 3600000
+ countryListDownload:
+ timeInterval: 1800000
+ lockLimit: 3600000
gateway:
connector:
enabled: false
diff --git a/templates/file-header.txt b/templates/file-header.txt
index 2e2579b..288fbd6 100644
--- a/templates/file-header.txt
+++ b/templates/file-header.txt
@@ -1,6 +1,6 @@
/*-
* ---license-start
- * eu-digital-green-certificates / dgca-verifier-service
+ * eu-digital-green-certificates / dgca-businessrule-service
* ---
* Copyright (C) 2021 T-Systems International GmbH and all other contributors
* ---
From 6e87451612437324c03287cb6aabd31d7d501612 Mon Sep 17 00:00:00 2001
From: Julian <82032362+jurosens@users.noreply.github.com>
Date: Sat, 26 Jun 2021 00:13:55 +0200
Subject: [PATCH 2/2] feat: gateway integration on BTP (#15)
---
pom.xml | 5 +
.../btp/SapCredentialStoreCfEnvProcessor.java | 68 ++++
.../GatewayDataDownloadBtpServiceImpl.java | 364 ++++++++++++++++++
.../businessrule/service/ValueSetService.java | 8 +
.../utils/btp/CredentialStore.java | 45 +++
.../utils/btp/CredentialStoreConfig.java | 42 ++
.../utils/btp/CredentialStoreCryptoUtil.java | 80 ++++
.../utils/btp/JsonNodeDeserializer.java | 22 ++
.../businessrule/utils/btp/SapCredential.java | 31 ++
src/main/resources/META-INF/spring.factories | 1 +
src/main/resources/application-btp.yml | 16 +-
11 files changed, 676 insertions(+), 6 deletions(-)
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/config/btp/SapCredentialStoreCfEnvProcessor.java
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadBtpServiceImpl.java
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/utils/btp/CredentialStore.java
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/utils/btp/CredentialStoreConfig.java
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/utils/btp/CredentialStoreCryptoUtil.java
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/utils/btp/JsonNodeDeserializer.java
create mode 100644 src/main/java/eu/europa/ec/dgc/businessrule/utils/btp/SapCredential.java
create mode 100644 src/main/resources/META-INF/spring.factories
diff --git a/pom.xml b/pom.xml
index 8ea59dd..e10220a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -260,6 +260,11 @@
com.sap.hcp.cf.logging
cf-java-logging-support-logback
+
+ com.nimbusds
+ nimbus-jose-jwt
+ 9.9.2
+
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/config/btp/SapCredentialStoreCfEnvProcessor.java b/src/main/java/eu/europa/ec/dgc/businessrule/config/btp/SapCredentialStoreCfEnvProcessor.java
new file mode 100644
index 0000000..d4a5231
--- /dev/null
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/config/btp/SapCredentialStoreCfEnvProcessor.java
@@ -0,0 +1,68 @@
+package eu.europa.ec.dgc.businessrule.config.btp;
+
+import io.pivotal.cfenv.core.CfCredentials;
+import io.pivotal.cfenv.core.CfService;
+import io.pivotal.cfenv.spring.boot.CfEnvProcessor;
+import io.pivotal.cfenv.spring.boot.CfEnvProcessorProperties;
+import java.util.Map;
+
+/**
+ * Custom implementation of {@link CfEnvProcessor} for reading the SAP credential store parameters from the
+ * VCAP_SERVICES
environment variable and making them available as properties in the spring context.
+ *
+ * The following properties are available in the context after the processor is done:
+ *
+ *
+ * - sap.btp.credstore.url
+ * - sap.btp.credstore.password
+ * - sap.btp.credstore.username
+ * - sap.btp.credstore.clientPrivateKey
+ * - sap.btp.credstore.serverPublicKey
+ *
+ *
+ *
+ * @see CfEnvProcessor
+ */
+public class SapCredentialStoreCfEnvProcessor implements CfEnvProcessor {
+
+ private static final String CRED_STORE_SCHEME = "credstore";
+ private static final String CRED_STORE_PROPERTY_PREFIX = "sap.btp.credstore";
+
+ @Override
+ public boolean accept(CfService service) {
+ return service.existsByTagIgnoreCase(CRED_STORE_SCHEME, "securestore", "keystore", "credentials")
+ || service.existsByLabelStartsWith(CRED_STORE_SCHEME)
+ || service.existsByUriSchemeStartsWith(CRED_STORE_SCHEME);
+ }
+
+ @Override
+ public void process(CfCredentials cfCredentials, Map properties) {
+ properties.put(CRED_STORE_PROPERTY_PREFIX + ".url", cfCredentials.getString("url"));
+ properties.put(CRED_STORE_PROPERTY_PREFIX + ".password", cfCredentials.getString("password"));
+ properties.put(CRED_STORE_PROPERTY_PREFIX + ".username", cfCredentials.getString("username"));
+
+ @SuppressWarnings("unchecked")
+ Map encryption = (Map) cfCredentials.getMap().get("encryption");
+ if (encryption == null) {
+ // Encryption features have been disabled on this BTP instance.
+ properties.put(CRED_STORE_PROPERTY_PREFIX + ".clientPrivateKey", "encryption-disabled");
+ properties.put(CRED_STORE_PROPERTY_PREFIX + ".serverPublicKey", "encryption-disabled");
+ return;
+ }
+
+ String clientPrivateKey = encryption.get("client_private_key").toString();
+ String serverPublicKey = encryption.get("server_public_key").toString();
+
+ properties.put(CRED_STORE_PROPERTY_PREFIX + ".clientPrivateKey", clientPrivateKey);
+ properties.put(CRED_STORE_PROPERTY_PREFIX + ".serverPublicKey", serverPublicKey);
+ }
+
+ @Override
+ public CfEnvProcessorProperties getProperties() {
+ return CfEnvProcessorProperties.builder()
+ .propertyPrefixes(CRED_STORE_PROPERTY_PREFIX)
+ .serviceName("CredentialStore")
+ .build();
+ }
+
+}
diff --git a/src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadBtpServiceImpl.java b/src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadBtpServiceImpl.java
new file mode 100644
index 0000000..240e7b2
--- /dev/null
+++ b/src/main/java/eu/europa/ec/dgc/businessrule/service/GatewayDataDownloadBtpServiceImpl.java
@@ -0,0 +1,364 @@
+package eu.europa.ec.dgc.businessrule.service;
+
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.gson.FieldNamingPolicy;
+import com.google.gson.FieldNamingStrategy;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.TypeAdapter;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;
+import com.sap.cloud.sdk.cloudplatform.connectivity.HttpClientAccessor;
+import com.sap.cloud.sdk.cloudplatform.connectivity.HttpDestination;
+import eu.europa.ec.dgc.businessrule.model.BusinessRuleItem;
+import eu.europa.ec.dgc.businessrule.model.ValueSetItem;
+import eu.europa.ec.dgc.businessrule.utils.btp.JsonNodeDeserializer;
+import eu.europa.ec.dgc.gateway.connector.dto.TrustListItemDto;
+import eu.europa.ec.dgc.gateway.connector.dto.ValidationRuleDto;
+import eu.europa.ec.dgc.gateway.connector.model.ValidationRule;
+import eu.europa.ec.dgc.signing.SignedStringMessageParser;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.RequestBuilder;
+import org.apache.http.util.EntityUtils;
+import org.bouncycastle.cert.X509CertificateHolder;
+import org.slf4j.MDC;
+import org.springframework.context.annotation.Profile;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@RequiredArgsConstructor
+@Component
+@Profile("btp")
+public class GatewayDataDownloadBtpServiceImpl implements GatewayDataDownloadService {
+
+ private static final String DGCG_DESTINATION = "dgcg-destination";
+ private static final String DCCG_UPLOAD_CERTS_ENDPOINT = "/trustList/UPLOAD";
+ private static final String DCCG_BUSINESS_RULES_ENDPOINT = "/rules";
+ private static final String DCCG_VALUE_SETS_ENDPOINT = "/valuesets";
+ private static final String DCCG_COUNTRY_LIST_ENDPOINT = "/countrylist";
+
+ private final BusinessRuleService businessRuleService;
+ private final ValueSetService valueSetService;
+ private final CountryListService countryListService;
+
+ @Override
+ @Scheduled(fixedDelayString = "${dgc.businessRulesDownload.timeInterval}")
+ @SchedulerLock(name = "GatewayDataDownloadService_downloadBusinessRules", lockAtLeastFor = "PT0S",
+ lockAtMostFor = "${dgc.businessRulesDownload.lockLimit}")
+ public void downloadBusinessRules() {
+ try {
+ initializeLogging();
+ log.debug("Business rules download started.");
+
+ //List uploadCerts = fetchUploadCerts(httpClient);
+ List countryCodes = fetchCountryList();
+
+ List ruleItems = new ArrayList<>();
+ try {
+ ruleItems = businessRuleService.createBusinessRuleItemList(fetchValidationRulesAndVerify(countryCodes));
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Could not create business rule item list: {}", e.getMessage(), e);
+ }
+
+ if (!ruleItems.isEmpty()) {
+ businessRuleService.updateBusinesRules(ruleItems);
+ } else {
+ log.warn("The download of the business rules seems to fail, as the download connector "
+ + "returns an empty list. No data will be changed.");
+ }
+
+ log.info("Business rules download finished.");
+ } finally {
+ cleanLogging();
+ }
+
+ }
+
+ @Override
+ @Scheduled(fixedDelayString = "${dgc.valueSetsDownload.timeInterval}")
+ @SchedulerLock(name = "GatewayDataDownloadService_downloadValueSets", lockAtLeastFor = "PT0S",
+ lockAtMostFor = "${dgc.valueSetsDownload.lockLimit}")
+ public void downloadValueSets() {
+ try {
+ initializeLogging();
+ log.debug("Value sets download started.");
+ List valueSetItems;
+ List valueSetIds = fetchValueSetIds();
+
+ try {
+ valueSetItems = valueSetService.createValueSetItemListFromMap(fetchValueSets(valueSetIds));
+ log.debug("Downloaded {} value set items.", valueSetItems.size());
+ } catch (NoSuchAlgorithmException e) {
+ log.error("Failed to hash value set on download.",e);
+ return;
+ }
+
+ if (!valueSetItems.isEmpty()) {
+ valueSetService.updateValueSets(valueSetItems);
+ } else {
+ log.warn("The download of the value sets seems to fail, as the download connector "
+ + "returns an empty list. No data will be changed.");
+ }
+
+ log.debug("Value sets download finished.");
+ } finally {
+ cleanLogging();
+ }
+ }
+
+ @Override
+ @Scheduled(fixedDelayString = "${dgc.countryListDownload.timeInterval}")
+ @SchedulerLock(name = "GatewayDataDownloadService_downloadCountryList", lockAtLeastFor = "PT0S",
+ lockAtMostFor = "${dgc.countryListDownload.lockLimit}")
+ public void downloadCountryList() {
+ try {
+ initializeLogging();
+ log.debug("Country list download started.");
+
+ List countryList = fetchCountryList();
+ log.debug("Downloaded {} country codes.", countryList.size());
+
+ if (!countryList.isEmpty()) {
+ countryListService.updateCountryList(gson().toJson(countryList));
+ } else {
+ log.warn("The download of the country list seems to fail as the gateway "
+ + "returns an empty list. No data will be changed.");
+ }
+
+ log.debug("Country list download finished.");
+ } finally {
+ cleanLogging();
+ }
+ }
+
+ private List fetchUploadCerts(HttpClient httpClient) {
+ List listOfUploadCerts = new ArrayList<>();
+
+ try {
+ HttpResponse response = httpClient.execute(RequestBuilder.get(DCCG_UPLOAD_CERTS_ENDPOINT).build());
+ List trustListItems = gson().fromJson(toJsonString(response.getEntity()),
+ new TypeToken>() {}.getType());
+
+ listOfUploadCerts = trustListItems.stream()
+ .filter(this::checkThumbprintIntegrity)
+ .filter(this::checkTrustAnchorSignature)
+ .map(this::getCertificateFromTrustListItem)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ } catch (IOException e) {
+ log.error("Fetching upload verts from gateway failed: {}", e.getMessage(), e);
+ }
+
+ return listOfUploadCerts;
+ }
+
+ private List fetchCountryList() {
+ HttpDestination httpDestination = DestinationAccessor.getDestination(DGCG_DESTINATION).asHttp();
+ HttpClient httpClient = HttpClientAccessor.getHttpClient(httpDestination);
+ List countryList = new ArrayList<>();
+
+ try {
+ HttpResponse response = httpClient.execute(RequestBuilder.get(DCCG_COUNTRY_LIST_ENDPOINT).build());
+ countryList = new ArrayList<>(gson().fromJson(toJsonString(response.getEntity()),
+ new TypeToken>() {}.getType()));
+ } catch (IOException e) {
+ log.error("Could not fetch country list from gateway: {}", e.getMessage(), e);
+ }
+
+ return countryList;
+ }
+
+ private List fetchValueSetIds() {
+ HttpDestination httpDestination = DestinationAccessor.getDestination(DGCG_DESTINATION).asHttp();
+ HttpClient httpClient = HttpClientAccessor.getHttpClient(httpDestination);
+ List valueSetIds = new ArrayList<>();
+
+ try {
+ HttpResponse response = httpClient.execute(RequestBuilder.get(DCCG_VALUE_SETS_ENDPOINT).build());
+ valueSetIds = new ArrayList<>(gson().fromJson(toJsonString(response.getEntity()),
+ new TypeToken>() {}.getType()));
+ } catch (IOException e) {
+ log.error("Could not fetch value set IDs from gateway: {}", e.getMessage());
+ }
+
+ return valueSetIds;
+ }
+
+ private Gson gson() {
+ return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new TypeAdapter() {
+ @Override
+ public void write(JsonWriter out, ZonedDateTime value) throws IOException {
+ out.value(value.toString());
+ }
+
+ @Override
+ public ZonedDateTime read(JsonReader in) throws IOException {
+ return ZonedDateTime.parse(in.nextString());
+ }
+ })
+ .enableComplexMapKeySerialization()
+ .create();
+ }
+
+ private Gson gsonForValidationRule() {
+ return new GsonBuilder().registerTypeAdapter(ZonedDateTime.class, new TypeAdapter() {
+ @Override
+ public void write(JsonWriter out, ZonedDateTime value) throws IOException {
+ out.value(value.toString());
+ }
+
+ @Override
+ public ZonedDateTime read(JsonReader in) throws IOException {
+ return ZonedDateTime.parse(in.nextString());
+ }
+ })
+ .registerTypeAdapter(JsonNode.class, new JsonNodeDeserializer())
+ .setFieldNamingStrategy(FieldNamingPolicy.UPPER_CAMEL_CASE)
+ .enableComplexMapKeySerialization()
+ .create();
+ }
+
+ private String toJsonString(HttpEntity entity) throws IOException {
+ return EntityUtils.toString(entity);
+ }
+
+ private boolean checkThumbprintIntegrity(TrustListItemDto trustListItem) {
+ byte[] certificateRawData = Base64.getDecoder().decode(trustListItem.getRawData());
+
+ try {
+ if (trustListItem.getThumbprint()
+ .equals(this.getCertThumbprint(new X509CertificateHolder(certificateRawData)))) {
+ return true;
+ } else {
+ log.debug("Thumbprint of trust list item '{}' did not match.", trustListItem.getKid());
+ return false;
+ }
+ } catch (IOException e) {
+ log.error("Could not parse certificate raw data: {}", e.getMessage());
+ return false;
+ }
+ }
+
+ private String getCertThumbprint(X509CertificateHolder x509CertificateHolder) {
+ try {
+ byte[] data = x509CertificateHolder.getEncoded();
+ byte[] certHashBytes = MessageDigest.getInstance("SHA-256").digest(data);
+ String hexString = (new BigInteger(1, certHashBytes)).toString(16);
+ if (hexString.length() == 63) {
+ hexString = "0" + hexString;
+ }
+ return hexString;
+ } catch (NoSuchAlgorithmException | IOException e) {
+ log.error("Could not calculate thumbprint of certificate '{}': {}.",
+ x509CertificateHolder.getSubject(), e.getMessage());
+ return null;
+ }
+ }
+
+ private X509CertificateHolder getCertificateFromTrustListItem(TrustListItemDto trustListItem) {
+ byte[] decodedBytes = Base64.getDecoder().decode(trustListItem.getRawData());
+ try {
+ return new X509CertificateHolder(decodedBytes);
+ } catch (IOException e) {
+ log.error("Failed to parse Certificate Raw Data. KID: {}, Country: {}", trustListItem.getKid(),
+ trustListItem.getCountry());
+ return null;
+ }
+ }
+
+ private boolean checkTrustAnchorSignature(TrustListItemDto trustListItemDto) {
+ // Implement me...
+ return true;
+ }
+
+ private List fetchValidationRulesAndVerify(List countryCodes) {
+ HttpDestination httpDestination = DestinationAccessor.getDestination(DGCG_DESTINATION).asHttp();
+ HttpClient httpClient = HttpClientAccessor.getHttpClient(httpDestination);
+ List allRules = new ArrayList<>();
+
+ for (String countryCode : countryCodes) {
+ log.debug("Fetching rules for country '{}'...", countryCode);
+ try {
+ HttpResponse response = httpClient
+ .execute(RequestBuilder.get(DCCG_BUSINESS_RULES_ENDPOINT + "/" + countryCode).build());
+ Map fetchedForCountry = gson().fromJson(toJsonString(response.getEntity()),
+ new TypeToken