Skip to content
This repository has been archived by the owner on Sep 15, 2023. It is now read-only.

Commit

Permalink
Merge pull request #163 from admin-ch/feature/travel
Browse files Browse the repository at this point in the history
  • Loading branch information
gstoehld authored Apr 7, 2022
2 parents 4d2083e + 943318f commit 5d5bb96
Show file tree
Hide file tree
Showing 28 changed files with 987 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.covidcertificate.backend.verifier.data;

import ch.admin.bag.covidcertificate.backend.verifier.model.ForeignRule;
import java.util.List;

/**
* Dataservice to store and retrieve validation rules obtained from the DGC gateway
*/
public interface ForeignRulesDataService {

/**
*
* @return A list of all countries that we have rules for
*/
public List<String> getCountries();

/**
*
* @param country the two-letter country code
* @return All available versions of all rules for that country
*/
public List<ForeignRule> getRulesForCountry(String country);

/**
* Insert a rule into the DB
* @param rule the rule
*/
public void insertRule(ForeignRule rule);

/**
* Remove all rules for a given country (in order to insert a new set)
* @param country the country
*/
public void removeRuleSet(String country);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.covidcertificate.backend.verifier.data.impl;

import ch.admin.bag.covidcertificate.backend.verifier.data.ForeignRulesDataService;
import ch.admin.bag.covidcertificate.backend.verifier.data.mapper.ForeignRulesRowMapper;
import ch.admin.bag.covidcertificate.backend.verifier.model.ForeignRule;
import java.time.LocalDateTime;
import java.util.List;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

public class JdbcForeignRulesDataServiceImpl implements ForeignRulesDataService {

private static final Logger logger =
LoggerFactory.getLogger(JdbcForeignRulesDataServiceImpl.class);

private final NamedParameterJdbcTemplate jt;

public JdbcForeignRulesDataServiceImpl(DataSource dataSource) {
this.jt = new NamedParameterJdbcTemplate(dataSource);
}

@Override
public List<String> getCountries() {
String sql = "select distinct country from t_foreign_rules";
return jt.queryForList(sql, new MapSqlParameterSource(), String.class);
}

@Override
public List<ForeignRule> getRulesForCountry(String country) {
String sql =
"select country, rule_id, rule_version, rule_content, valid_from, valid_until from t_foreign_rules where country=:country";
var params = new MapSqlParameterSource();
params.addValue("country", country);
return jt.query(sql, params, new ForeignRulesRowMapper());
}

@Override
public void insertRule(ForeignRule rule) {
String sql =
"insert into t_foreign_rules"
+ "(country, rule_id, rule_version, rule_content, valid_from, valid_until, inserted_at) "
+ "values(:country, :rule_id, :rule_version, :rule_content, :valid_from, :valid_until, :inserted_at)";
var params = new MapSqlParameterSource();
params.addValue("country", rule.getCountry());
params.addValue("rule_id", rule.getId());
params.addValue("rule_version", rule.getVersion());
params.addValue("rule_content", rule.getContent());
params.addValue("valid_from", rule.getValidFrom());
params.addValue("valid_until", rule.getValidUntil());
params.addValue("inserted_at", LocalDateTime.now());
jt.update(sql, params);
}

@Override
public void removeRuleSet(String country) {
String sql = "delete from t_foreign_rules where country=:country";
var params = new MapSqlParameterSource();
params.addValue("country", country);
jt.update(sql, params);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.covidcertificate.backend.verifier.data.mapper;

import ch.admin.bag.covidcertificate.backend.verifier.model.ForeignRule;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;

public class ForeignRulesRowMapper implements RowMapper<ForeignRule> {

@Override
public ForeignRule mapRow(ResultSet resultSet, int i) throws SQLException {
var rule = new ForeignRule();
rule.setCountry(resultSet.getString("country"));
rule.setId(resultSet.getString("rule_id"));
rule.setVersion(resultSet.getString("rule_version"));
rule.setContent(resultSet.getString("rule_content"));
rule.setValidFrom(resultSet.getTimestamp("valid_from").toLocalDateTime());
rule.setValidUntil(resultSet.getTimestamp("valid_until").toLocalDateTime());
return rule;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class CacheUtil {
public static Duration VALUE_SETS_MAX_AGE;
public static Duration KEYS_UPDATES_MAX_AGE;
public static Duration KEYS_LIST_MAX_AGE;
public static Duration FOREIGN_RULES_MAX_AGE;

public static Duration KEYS_BUCKET_DURATION;
public static Duration REVOCATION_RETENTION_BUCKET_DURATION;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE TABLE t_foreign_rules
(
pk_id SERIAL NOT NULL,
country CHAR(2) NOT NULL ,
rule_id VARCHAR(64) NOT NULL,
rule_version VARCHAR(32) NOT NULL,
rule_content TEXT NOT NULL,
valid_from timestamp with time zone,
valid_until timestamp with time zone,
inserted_at timestamp with time zone,
CONSTRAINT rules_pk_id PRIMARY KEY (pk_id)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE TABLE t_foreign_rules
(
pk_id SERIAL NOT NULL,
country CHAR(2) NOT NULL ,
rule_id VARCHAR(64) NOT NULL,
rule_version VARCHAR(32) NOT NULL,
rule_content TEXT NOT NULL,
valid_from timestamp with time zone,
valid_until timestamp with time zone,
inserted_at timestamp with time zone,
CONSTRAINT rules_pk_id PRIMARY KEY (pk_id)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.covidcertificate.backend.verifier.data;

import static org.junit.jupiter.api.Assertions.assertEquals;

import ch.admin.bag.covidcertificate.backend.verifier.model.ForeignRule;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import javax.sql.DataSource;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

class ForeignRulesDataServiceTest extends BaseDataServiceTest {

@Autowired ForeignRulesDataService dataService;
@Autowired DataSource dataSource;

ForeignRule atRule;
ForeignRule deRule1;
ForeignRule deRule2;

@BeforeAll
void setup(){
atRule = new ForeignRule();
atRule.setId("GR-AT-0039");
atRule.setVersion("0.0.1");
atRule.setValidFrom(LocalDateTime.now().minus(1, ChronoUnit.DAYS));
atRule.setValidUntil(LocalDateTime.now().plus(1, ChronoUnit.YEARS));
atRule.setContent("{}");
atRule.setCountry("AT");
deRule1 = new ForeignRule();
deRule1.setId("GR-DE-0039");
deRule1.setVersion("0.0.1");
deRule1.setValidFrom(LocalDateTime.now().minus(1, ChronoUnit.DAYS));
deRule1.setValidUntil(LocalDateTime.now().plus(1, ChronoUnit.YEARS));
deRule1.setContent("{}");
deRule1.setCountry("DE");
deRule2 = new ForeignRule();
deRule2.setId("GR-DE-0039");
deRule2.setVersion("0.0.2");
deRule2.setValidFrom(LocalDateTime.now().minus(1, ChronoUnit.HOURS));
deRule2.setValidUntil(LocalDateTime.now().plus(1, ChronoUnit.YEARS));
deRule2.setContent("{}");
deRule2.setCountry("DE");
dataService.insertRule(atRule);
dataService.insertRule(deRule1);
dataService.insertRule(deRule2);
}

@Test
void countryListTest() {
var countries = dataService.getCountries();
assertEquals(2, countries.size());
}

@Test
void rulesForCountryTest(){
var de = dataService.getRulesForCountry("DE");
assertEquals(2, de.size());
var fr = dataService.getRulesForCountry("FR");
assertEquals(0, fr.size());
}

@Test
void deletionTest(){
var de = dataService.getRulesForCountry("DE");
assertEquals(2, de.size());
dataService.removeRuleSet("DE");
de = dataService.getRulesForCountry("DE");
assertEquals(0, de.size());
var countries = dataService.getCountries();
assertEquals(1, countries.size());
var at = dataService.getRulesForCountry("AT");
assertEquals(1, at.size());
dataService.insertRule(deRule1);
dataService.insertRule(deRule2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
package ch.admin.bag.covidcertificate.backend.verifier.data.config;

import ch.admin.bag.covidcertificate.backend.verifier.data.AppTokenDataService;
import ch.admin.bag.covidcertificate.backend.verifier.data.ForeignRulesDataService;
import ch.admin.bag.covidcertificate.backend.verifier.data.RevokedCertDataService;
import ch.admin.bag.covidcertificate.backend.verifier.data.VerifierDataService;
import ch.admin.bag.covidcertificate.backend.verifier.data.impl.JdbcAppTokenDataServiceImpl;
import ch.admin.bag.covidcertificate.backend.verifier.data.impl.JdbcForeignRulesDataServiceImpl;
import ch.admin.bag.covidcertificate.backend.verifier.data.impl.JdbcRevokedCertDataServiceImpl;
import ch.admin.bag.covidcertificate.backend.verifier.data.impl.JdbcVerifierDataServiceImpl;
import ch.admin.bag.covidcertificate.backend.verifier.data.util.CacheUtil;
Expand Down Expand Up @@ -51,6 +53,13 @@ public RevokedCertDataService revokedCertDataService(
return new JdbcRevokedCertDataServiceImpl(dataSource, revokedCertBatchSize);
}

@Bean
public ForeignRulesDataService foreignRulesDataService(
DataSource dataSource
){
return new JdbcForeignRulesDataServiceImpl(dataSource);
}

@Value("${ws.revocation-list.retention-bucket-duration:PT6H}")
public void setRevocationRetentionBucketDuration(Duration bucketDuration) {
CacheUtil.REVOCATION_RETENTION_BUCKET_DURATION = bucketDuration;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package ch.admin.bag.covidcertificate.backend.verifier.model;

import java.time.LocalDateTime;
import java.util.Locale.IsoCountryCode;

public class ForeignRule {
private String country;
private String id;
private String version;
private String content;
private LocalDateTime validFrom;
private LocalDateTime validUntil;

public String getCountry() {
return country;
}

public void setCountry(String country) {
this.country = country;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

public LocalDateTime getValidFrom() {
return validFrom;
}

public void setValidFrom(LocalDateTime validFrom) {
this.validFrom = validFrom;
}

public LocalDateTime getValidUntil() {
return validUntil;
}

public void setValidUntil(LocalDateTime validUntil) {
this.validUntil = validUntil;
}
}
Loading

0 comments on commit 5d5bb96

Please sign in to comment.