Skip to content

Commit

Permalink
[SRM] visited countries
Browse files Browse the repository at this point in the history
  • Loading branch information
srmontero committed Dec 14, 2020
1 parent bf8613e commit 54b4976
Show file tree
Hide file tree
Showing 20 changed files with 309 additions and 58 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## [Unreleased]

### Added

- Download keys service save visited countries in database.

## [1.1.0.RELEASE] - 2020-11-12

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ EFGS Service in terms of the Radar COVID project enables the connectivity with [
These are the frameworks and tools used to develop the solution:

- [Java 11](https://openjdk.java.net/).
- [Maven](https://maven.apache.org/).
- [Maven 3.6](https://maven.apache.org/).
- [Spring Boot](https://spring.io/projects/spring-boot) version 2.3.
- [Lombok](https://projectlombok.org/), to help programmer. Developers have to include the IDE plugin to support Lombok features (ie, for Eclipse based IDE, go [here](https://projectlombok.org/setup/eclipse)).
- [ArchUnit](https://www.archunit.org/) is used to check Java architecture.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
*/
package es.gob.radarcovid.efgs;

import es.gob.radarcovid.efgs.etc.EfgsProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

import es.gob.radarcovid.efgs.etc.EfgsProperties;

@SpringBootApplication
@EnableAspectJAutoProxy
@EnableJpaRepositories(basePackages = {"es.gob.radarcovid.efgs.persistence.repository"})
Expand All @@ -25,7 +26,8 @@
public class EfgsApplication {

public static void main(String[] args) {
SpringApplication.run(EfgsApplication.class, args);
System.exit(SpringApplication
.exit(SpringApplication.run(EfgsApplication.class, args)));
}

}
2 changes: 1 addition & 1 deletion efgs-server-boot/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ application:
efgs:
retention-days: 6
country: 'ES'
country-list: BE,BG,CZ,DK,DE,EE,ES,IE,GR,FR,HR,IT,CY,LV,LT,LU,HU,MT,NL,AT,PL,PT,RO,SI,SK,FI,SE,IS,LI,NO,CH
ssl:
enabled: ${EFGS_SSL_ENABLED:true}
key-store: classpath:radarcovid-ta.jks
Expand All @@ -84,7 +85,6 @@ application:
json-version: 1.0
upload-diagnosis-keys:
enabled: ${EFGS_UPLOAD_DIAGNOSIS_KEYS_ENABLED:true}
country-list: BE,BG,CZ,DK,DE,EE,IE,GR,FR,HR,IT,CY,LV,LT,LU,HU,MT,NL,AT,PL,PT,RO,SI,SK,FI,SE,IS,LI,NO,CH
default-values:
transmission-risk-level: ${EFGS_DEFAULT_TRANSMISSION_RISK_LEVEL:2}
report-type: ${EFGS_DEFAULT_REPORT_TYPE:CONFIRMED_TEST}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.springframework.test.context.ActiveProfiles

import es.gob.radarcovid.efgs.etc.EfgsProperties
import es.gob.radarcovid.efgs.persistence.entity.GaenExposedEntity
import es.gob.radarcovid.efgs.persistence.entity.VisitedEntity
import es.gob.radarcovid.efgs.persistence.mapper.GaenExposedMapper
import es.gob.radarcovid.efgs.persistence.model.GaenExposedDto
import eu.interop.federationgateway.model.EfgsProto.ReportType
Expand Down Expand Up @@ -48,11 +49,12 @@ class GaenExposedMapperTestSpec extends Specification {
dto.reportType == efgsProperties.uploadDiagnosisKeys.defaultValues.reportType
dto.daysSinceOnset == (entity.daysSinceOnset != null ? entity.daysSinceOnset : 1)
dto.efgsSharing == entity.efgsSharing
dto.visitedCountries.size() == entity.visitedCountries.size()

where:
entity << [
createEntity(1, 'key1', 13, 5, 8, LocalDateTime.now(), 11, true),
createEntity(2, 'key2', 13, 144, 3, LocalDateTime.now(), -11, true),
createEntity(1, 'key1', 13, 5, 8, LocalDateTime.now(), 11, true, 'IT', 'FR', 'DE'),
createEntity(2, 'key2', 13, 144, 3, LocalDateTime.now(), -11, true, 'ES'),
createEntity(3, 'key3', null, null, null, LocalDateTime.now(), null, false)
]
}
Expand All @@ -73,17 +75,18 @@ class GaenExposedMapperTestSpec extends Specification {
entity.reportType == dto.reportType
entity.daysSinceOnset == dto.daysSinceOnset
entity.efgsSharing == dto.efgsSharing
entity.visitedCountries.size() == dto.visitedCountries.size()

where:
dto << [
createDto('key1', 13, 5, 8, LocalDateTime.now(), 'ES', ReportType.CONFIRMED_TEST, 11, true),
createDto('key2', 13, 144, 3, LocalDateTime.now(), 'DE', ReportType.CONFIRMED_CLINICAL_DIAGNOSIS, -11, true),
createDto('key1', 13, 5, 8, LocalDateTime.now(), 'ES', ReportType.CONFIRMED_TEST, 11, true, 'IT', 'FR', 'DE'),
createDto('key2', 13, 144, 3, LocalDateTime.now(), 'DE', ReportType.CONFIRMED_CLINICAL_DIAGNOSIS, -11, true, 'ES'),
createDto('key3', null, null, null, LocalDateTime.now(), null, ReportType.SELF_REPORT, null, false)
]
}

def createEntity(Integer id, String key, Integer rollingStartNumber, Integer rollingPeriod, Integer transmissionRiskLevel,
LocalDateTime receivedAt, Integer daysSinceOnset, Boolean efgsSharing) {
LocalDateTime receivedAt, Integer daysSinceOnset, Boolean efgsSharing, String... visitedCountries) {
def entity = new GaenExposedEntity()
entity.setId(id)
entity.setKey(key)
Expand All @@ -93,11 +96,19 @@ class GaenExposedMapperTestSpec extends Specification {
entity.setReceivedAt(receivedAt)
entity.setDaysSinceOnset(daysSinceOnset)
entity.setEfgsSharing(efgsSharing)

visitedCountries.stream().forEach({country ->
def visitedEntity = new VisitedEntity()
visitedEntity.setCountry(country)
entity.visitedCountries.add(visitedEntity)
} )

return entity
}

def createDto(String key, Integer rollingStartNumber, Integer rollingPeriod, Integer transmissionRiskLevel,
LocalDateTime receivedAt, String countryOrigin, ReportType reportType, Integer daysSinceOnset, Boolean efgsSharing) {
LocalDateTime receivedAt, String countryOrigin, ReportType reportType, Integer daysSinceOnset, Boolean efgsSharing,
String... visitedCountries) {
def dto = new GaenExposedDto()
dto.setKey(key)
dto.setRollingStartNumber(rollingStartNumber)
Expand All @@ -108,6 +119,7 @@ class GaenExposedMapperTestSpec extends Specification {
dto.setReportType(reportType)
dto.setDaysSinceOnset(daysSinceOnset)
dto.setEfgsSharing(efgsSharing)
dto.setVisitedCountries(visitedCountries as Set)
return dto
}
}
1 change: 1 addition & 0 deletions efgs-server-boot/src/test/resources/data.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
DELETE FROM DPPPT.DOWNLOAD_EXECUTION;
DELETE FROM DPPPT.UPLOAD_KEYS_EXECUTION;
DELETE FROM DPPPT.BATCH_JOB_EXECUTION;
DELETE FROM DPPPT.T_VISITED;
DELETE FROM DPPPT.T_GAEN_EXPOSED;
21 changes: 17 additions & 4 deletions efgs-server-boot/src/test/resources/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,20 @@ CREATE TABLE DPPPT.T_GAEN_EXPOSED(
BATCH_TAG CHAR VARYING(128)
);

ALTER TABLE DPPPT.T_GAEN_EXPOSED ADD CONSTRAINT PK_T_GAEN_EXPOSED PRIMARY KEY (PK_EXPOSED_ID);

ALTER TABLE DPPPT.T_GAEN_EXPOSED ADD CONSTRAINT GAEN_EXPOSED_KEY UNIQUE (KEY);

CREATE TABLE DPPPT.T_VISITED (
PFK_EXPOSED_ID INTEGER NOT NULL,
COUNTRY CHAR(2),
CONSTRAINT PK_T_VISITED
PRIMARY KEY (PFK_EXPOSED_ID, COUNTRY),
CONSTRAINT R_GAEN_EXPOSED_VISITED
FOREIGN KEY (PFK_EXPOSED_ID)
REFERENCES DPPPT.T_GAEN_EXPOSED (PK_EXPOSED_ID) ON DELETE CASCADE
);

ALTER SEQUENCE DPPPT.SQ_NM_ID_BATCH_JOB_EXECUTION
OWNED BY DPPPT.BATCH_JOB_EXECUTION.NM_JOB_EXECUTION_ID;

Expand All @@ -71,10 +85,6 @@ ALTER SEQUENCE DPPPT.SQ_NM_DOWNLOAD_EXECUTION

ALTER SEQUENCE DPPPT.SQ_NM_UPLOAD_KEYS_EXECUTION
OWNED BY DPPPT.UPLOAD_KEYS_EXECUTION.NM_UPLOAD_KEYS_ID;

ALTER TABLE DPPPT.T_GAEN_EXPOSED ADD CONSTRAINT PK_T_GAEN_EXPOSED PRIMARY KEY (PK_EXPOSED_ID);

ALTER TABLE DPPPT.T_GAEN_EXPOSED ADD CONSTRAINT GAEN_EXPOSED_KEY UNIQUE (KEY);

CREATE INDEX IN_EFGS_BATCH_JOB_EXECUTION_START_TIME
ON DPPPT.BATCH_JOB_EXECUTION(FC_START_TIME);
Expand All @@ -97,4 +107,7 @@ CREATE INDEX IN_GAEN_EXPOSED_COUNTRY_SHARING_RECEIVED
CREATE INDEX IN_GAEN_EXPOSED_COUNTRY_SHARING_BATCH_TAG
ON DPPPT.T_GAEN_EXPOSED(COUNTRY_ORIGIN, EFGS_SHARING, BATCH_TAG);

CREATE INDEX IDX_VISITED_EXPOSED_ID
ON DPPPT.T_VISITED(PFK_EXPOSED_ID);


Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class EfgsProperties {
private int retentionDays = 14;

private String country;
private List<String> countryList;

private final Credentials credentials = new Credentials();
private final Ssl ssl = new Ssl();
Expand Down Expand Up @@ -84,7 +85,6 @@ public static class ContentNegotiation {
@Setter
public static class UploadDiagnosisKeys {
private boolean enabled;
private List<String> countryList;
private int maximumUploadBatchSize = 5000;
private String url;
private final Retry retry = new Retry();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
*/
package es.gob.radarcovid.efgs.persistence;

import es.gob.radarcovid.efgs.persistence.model.GaenExposedDto;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;

import org.springframework.transaction.annotation.Transactional;

import es.gob.radarcovid.efgs.persistence.model.GaenExposedDto;

public interface GaenExposedDao {

@Transactional(readOnly=true)
List<GaenExposedDto> findPendingByCountry(String country, Integer page, Integer size);

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "t_gaen_exposed")
Expand Down Expand Up @@ -57,6 +59,9 @@ public class GaenExposedEntity implements Serializable {

@Column(name = "batch_tag")
private String batchTag;

@OneToMany(mappedBy = "gaenExposed")
private Set<VisitedEntity> visitedCountries = new HashSet<>();

public EfgsProto.ReportType getReportType() {
return EfgsProto.ReportType.valueOf(reportType);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2020 Gobierno de España
*
* 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 http://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/
package es.gob.radarcovid.efgs.persistence.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import lombok.Data;

@Entity
@Table(name = "t_visited")
@IdClass(VisitedEntityId.class)
@Data
public class VisitedEntity implements Serializable {

@Id
@Column(name = "pfk_exposed_id")
private Integer exposedId;

@Id
@Column(name = "country")
private String country;

@ManyToOne
@JoinColumn(name = "pfk_exposed_id", insertable = false, updatable = false)
private GaenExposedEntity gaenExposed;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2020 Gobierno de España
*
* 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 http://mozilla.org/MPL/2.0/.
*
* SPDX-License-Identifier: MPL-2.0
*/
package es.gob.radarcovid.efgs.persistence.entity;

import java.io.Serializable;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class VisitedEntityId implements Serializable {

private Integer exposedId;
private String country;

}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ public void updateBatchTagForKeys(Collection<GaenExposedDto> originalKeys, Strin
@Override
public int saveAll(List<GaenExposedDto> gaenExposedDtos) {
AtomicInteger total = new AtomicInteger(0);
gaenExposedDtos.stream().forEach(dto -> {
int saved = repository.saveUpdateOnConflict(
gaenExposedDtos.stream().forEach(dto -> {
repository.saveOnConflictUpdate(
dto.getKey(),
dto.getRollingStartNumber(),
dto.getRollingPeriod(),
Expand All @@ -60,9 +60,10 @@ public int saveAll(List<GaenExposedDto> gaenExposedDtos) {
dto.getReportType().getNumber(),
dto.getDaysSinceOnset(),
dto.getEfgsSharing(),
dto.getBatchTag());
total.addAndGet(saved);
});
dto.getBatchTag(),
dto.getVisitedCountries());
total.addAndGet(1);
});
return total.get();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import es.gob.radarcovid.efgs.persistence.model.GaenExposedDto;
import eu.interop.federationgateway.model.EfgsProto;

@Mapper(componentModel = "spring")
@Mapper(componentModel = "spring", uses = VisitedMapper.class)
public abstract class GaenExposedMapper {

@Autowired
Expand Down Expand Up @@ -67,7 +67,7 @@ public EfgsProto.DiagnosisKey dtoToDiagnosisKey(GaenExposedDto gaenExposedDto) {
.setOrigin(gaenExposedDto.getCountryOrigin())
.setReportType(gaenExposedDto.getReportType())
.setDaysSinceOnsetOfSymptoms(gaenExposedDto.getDaysSinceOnset())
.addAllVisitedCountries(efgsProperties.getUploadDiagnosisKeys().getCountryList())
.addAllVisitedCountries(efgsProperties.getCountryList())
.build();
}

Expand All @@ -78,7 +78,8 @@ public EfgsProto.DiagnosisKey dtoToDiagnosisKey(GaenExposedDto gaenExposedDto) {
@Mapping(target = "countryOrigin", source = "origin"),
@Mapping(target = "daysSinceOnset", ignore = true),
@Mapping(target = "efgsSharing", ignore = true),
@Mapping(target = "batchTag", ignore = true)
@Mapping(target = "batchTag", ignore = true),
@Mapping(target = "visitedCountries", source = "visitedCountriesList")
})
public abstract GaenExposedDto diagnosisKeyToDto(EfgsProto.DiagnosisKey diagnosisKey);

Expand Down
Loading

0 comments on commit 54b4976

Please sign in to comment.