This repository has been archived by the owner on Sep 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #383 from admin-ch/feature/VACCINECER-2353_Automat…
…isierung_für_Export_PowerBI Feature/vaccinecer 2353 automatisierung für export power bi
- Loading branch information
Showing
14 changed files
with
620 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
src/main/java/ch/admin/bag/covidcertificate/api/exception/BiDataError.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package ch.admin.bag.covidcertificate.api.exception; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import org.springframework.http.HttpStatus; | ||
|
||
import java.util.Objects; | ||
|
||
@AllArgsConstructor | ||
@Getter | ||
public class BiDataError { | ||
private final int errorCode; | ||
private final String errorMessage; | ||
private final HttpStatus httpStatus; | ||
|
||
@Override | ||
public String toString() { | ||
return "{\"errorCode\":" + errorCode + "," + | ||
"\"errorMessage\":\"" + errorMessage + "\"," + | ||
"\"httpStatus\":\"" + httpStatus.name() + "\"}"; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
BiDataError that = (BiDataError) o; | ||
return errorCode == that.errorCode && errorMessage.equals(that.errorMessage) && httpStatus == that.httpStatus; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(errorCode, errorMessage, httpStatus); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/ch/admin/bag/covidcertificate/api/exception/BiDataException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package ch.admin.bag.covidcertificate.api.exception; | ||
|
||
import lombok.Getter; | ||
import org.springframework.core.NestedRuntimeException; | ||
|
||
@Getter | ||
public class BiDataException extends NestedRuntimeException { | ||
|
||
private final BiDataError biDataError; | ||
|
||
public BiDataException(BiDataError error) { | ||
super(error.getErrorMessage()); | ||
this.biDataError = error; | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/ch/admin/bag/covidcertificate/api/response/BiDataDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package ch.admin.bag.covidcertificate.api.response; | ||
|
||
import ch.admin.bag.covidcertificate.domain.BiData; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.Setter; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.UUID; | ||
|
||
@Setter | ||
@Getter | ||
@NoArgsConstructor | ||
@AllArgsConstructor | ||
public class BiDataDto { | ||
UUID id; | ||
LocalDateTime timestamp; | ||
String type; | ||
String value; | ||
String details; | ||
String country; | ||
String systemSource; | ||
String apiGatewayId; | ||
String inAppDeliveryCode; | ||
Boolean fraud; | ||
String keyIdentifier; | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/ch/admin/bag/covidcertificate/api/response/BiDataResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package ch.admin.bag.covidcertificate.api.response; | ||
|
||
import lombok.AccessLevel; | ||
import lombok.AllArgsConstructor; | ||
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.NonNull; | ||
import lombok.ToString; | ||
|
||
@Getter | ||
@ToString | ||
@EqualsAndHashCode | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor | ||
public class BiDataResponseDto { | ||
|
||
@NonNull | ||
private byte[] zip; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
src/main/java/ch/admin/bag/covidcertificate/domain/BiData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package ch.admin.bag.covidcertificate.domain; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.UUID; | ||
|
||
public interface BiData { | ||
UUID getId(); | ||
LocalDateTime getTimestamp(); | ||
String getType(); | ||
String getValue(); | ||
String getDetails(); | ||
String getCountry(); | ||
String getSystemSource(); | ||
String getApiGatewayId(); | ||
String getInAppDeliveryCode(); | ||
Boolean getFraud(); | ||
String getKeyIdentifier(); | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/ch/admin/bag/covidcertificate/domain/KpiDataRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,31 @@ | ||
package ch.admin.bag.covidcertificate.domain; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.repository.query.Param; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
@Repository | ||
public interface KpiDataRepository extends JpaRepository<KpiData, UUID> { | ||
KpiData findByUvci(String uvci); | ||
|
||
@Query(value = "select k.id as id" + | ||
", k.timestamp as timestamp" + | ||
", k.value as value" + | ||
", k.details as details" + | ||
", k.country as country" + | ||
", k.systemSource as systemSource" + | ||
", k.apiGatewayId as apiGatewayId" + | ||
", k.inAppDeliveryCode as inAppDeliveryCode" + | ||
", r.fraud as fraud" + | ||
", k.keyIdentifier as keyIdentifier " + | ||
"from KpiData k " + | ||
"LEFT JOIN Revocation r on r.uvci = k.uvci " + | ||
"WHERE k.timestamp BETWEEN :fromDateTime AND :toDateTime " + | ||
"ORDER BY k.timestamp asc") | ||
List<BiData> findAllByDateRange(@Param("fromDateTime") LocalDateTime fromDateTime, @Param("toDateTime") LocalDateTime toDateTime); | ||
} |
116 changes: 116 additions & 0 deletions
116
src/main/java/ch/admin/bag/covidcertificate/service/BiDataService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package ch.admin.bag.covidcertificate.service; | ||
|
||
import ch.admin.bag.covidcertificate.api.exception.BiDataException; | ||
import ch.admin.bag.covidcertificate.api.response.BiDataDto; | ||
import ch.admin.bag.covidcertificate.api.response.BiDataResponseDto; | ||
import ch.admin.bag.covidcertificate.domain.BiData; | ||
import ch.admin.bag.covidcertificate.domain.KpiDataRepository; | ||
import com.opencsv.CSVWriter; | ||
import com.opencsv.bean.StatefulBeanToCsv; | ||
import com.opencsv.bean.StatefulBeanToCsvBuilder; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.nio.charset.Charset; | ||
import java.nio.file.Files; | ||
import java.time.LocalDate; | ||
import java.time.LocalDateTime; | ||
import java.time.LocalTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.List; | ||
import java.util.UUID; | ||
import java.util.stream.Collectors; | ||
import java.util.zip.ZipEntry; | ||
import java.util.zip.ZipOutputStream; | ||
|
||
import static ch.admin.bag.covidcertificate.api.Constants.DATES_NOT_VALID; | ||
import static ch.admin.bag.covidcertificate.api.Constants.WRITING_CSV_RESULT_FAILED; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class BiDataService { | ||
|
||
private final KpiDataRepository kpiDataRepository; | ||
|
||
public BiDataResponseDto loadBiData(LocalDate fromDate, LocalDate toDate) throws BiDataException { | ||
|
||
validateDateRange(fromDate, toDate); | ||
|
||
LocalDateTime fromDateTime = fromDate.atTime(LocalTime.MIN); | ||
LocalDateTime toDateTime = toDate.atTime(LocalTime.MAX); | ||
List<BiData> biDataList = this.kpiDataRepository.findAllByDateRange(fromDateTime, toDateTime); | ||
List<BiDataDto> biDataDtoList = biDataList.stream().map(this::convert).collect(Collectors.toList()); | ||
|
||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(baos)) { | ||
byte[] csv = createCsvResponse(biDataDtoList); | ||
var entry = new ZipEntry("kpi_prod_export_" + | ||
fromDateTime.format(DateTimeFormatter.ISO_DATE) + | ||
"-" + | ||
toDateTime.format(DateTimeFormatter.ISO_DATE) + | ||
".csv"); | ||
entry.setSize(csv.length); | ||
zos.putNextEntry(entry); | ||
zos.write(csv); | ||
zos.closeEntry(); | ||
zos.close(); | ||
return new BiDataResponseDto(baos.toByteArray()); | ||
} catch (IOException ex) { | ||
log.error("IOException creating CSV response", ex); | ||
throw new BiDataException(WRITING_CSV_RESULT_FAILED); | ||
} | ||
} | ||
|
||
private void validateDateRange(LocalDate fromDate, LocalDate toDate) { | ||
if (fromDate == null || toDate == null) { | ||
throw new BiDataException(DATES_NOT_VALID); | ||
} | ||
if (!fromDate.isBefore(toDate)) { | ||
throw new BiDataException(DATES_NOT_VALID); | ||
} | ||
if (!(fromDate.plusMonths(1l).minusDays(1).isEqual(toDate) || fromDate.plusDays(6l).isEqual(toDate))) { | ||
// time range is not one month or not one week | ||
throw new BiDataException(DATES_NOT_VALID); | ||
} | ||
} | ||
|
||
private byte[] createCsvResponse(List<BiDataDto> biDataDtos) throws IOException { | ||
var returnFile = writeCsv(biDataDtos, Charset.defaultCharset()); | ||
return Files.readAllBytes(returnFile.toPath()); | ||
} | ||
|
||
private File writeCsv(List<BiDataDto> biDataDtos, Charset charset) throws IOException { | ||
var randomUUID = UUID.randomUUID(); | ||
var file = File.createTempFile("bi_data_" + randomUUID, ".csv"); | ||
try (var csvWriter = new CSVWriter(new FileWriter(file, charset))) { | ||
StatefulBeanToCsv<BiDataDto> beanToCsv = new StatefulBeanToCsvBuilder<BiDataDto>(csvWriter) | ||
.withSeparator(CSVWriter.DEFAULT_SEPARATOR) | ||
.withApplyQuotesToAll(true) | ||
.build(); | ||
beanToCsv.write(biDataDtos); | ||
return file; | ||
} catch (Exception e) { | ||
Files.delete(file.toPath()); | ||
throw new BiDataException(WRITING_CSV_RESULT_FAILED); | ||
} | ||
} | ||
|
||
private BiDataDto convert(BiData biData) { | ||
return new BiDataDto(biData.getId(), | ||
biData.getTimestamp(), | ||
biData.getType(), | ||
biData.getValue(), | ||
biData.getDetails(), | ||
biData.getCountry(), | ||
biData.getSystemSource(), | ||
biData.getApiGatewayId(), | ||
biData.getInAppDeliveryCode(), | ||
biData.getFraud(), | ||
biData.getKeyIdentifier()); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/ch/admin/bag/covidcertificate/web/controller/BiDataController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package ch.admin.bag.covidcertificate.web.controller; | ||
|
||
import ch.admin.bag.covidcertificate.api.response.BiDataResponseDto; | ||
import ch.admin.bag.covidcertificate.service.BiDataService; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.format.annotation.DateTimeFormat; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
import java.time.LocalDate; | ||
|
||
@RestController | ||
@RequestMapping("/api/v1/bi-data/{fromDate}/{toDate}") | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class BiDataController { | ||
|
||
private final BiDataService biDataService; | ||
|
||
@GetMapping() | ||
public BiDataResponseDto loadBiData( | ||
@PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate fromDate, | ||
@PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate toDate) { | ||
|
||
return biDataService.loadBiData(fromDate, toDate); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.