This repository has been archived by the owner on May 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add Entity and Service for Portal Cancellation * * added CancellationController and endpoint for creating cancellations. * * added endpoint to check cancellation status * * added endpoint to request the download/start the cancellation process * *added checks to prevent Creating new Tests in Backend when cancellation has started * *implemented longterm archive job for cancellation * *implemented automatic trigger download 7 days before final deletion * *implemented Data-Export/CSV Job * *implemented endpoint to get Download Link * Fix Locklimit property * * locklimit for test properties fixed * response code for /download swagger fixed * * logging * * switched from group representation id to name for partnerId * * fixed tests for new group representation name * * implemented Final Delete all data associated to Partner * * changed from pocId to tenantId when encrypting * * moved magic numbers to config * * fixed some more getId for partnerid * * fixed tests * * added updateDownloadLinkRequested set after requested link * * set updateFinalDeletion after final delete * * set updateFinalDeletion after final delete * Add Archive-Ignore-Check to Cancellation Archive Job * Add Support for Legacy-Quick-Test-Partners * Remove old MTR from CI-Master (#255) (#256) * Remove old MTR from CI-Master * Update ci-master.yml * Add CancellationDate and refactor FinalDeletion Date to be calculated * Merge Master Branch * Add Error Logging to CSV Upload Job Add User Logging to DownloadRequested Action for Cancellation * Fix Cancellation Check methods * Fix Get Quicktests Endpoint Cancellation Check * Refactor to ZonedDateTime Refactor CancellationJobs to work with batches * Checkstyle * Add own config property for complete pending tests for cancellations Add Vault Mapping for several config properties Co-authored-by: Felix Dittrich <[email protected]> Co-authored-by: Morphyum <[email protected]> Co-authored-by: Felix Dittrich <[email protected]>
- Loading branch information
1 parent
521478a
commit d789809
Showing
31 changed files
with
2,085 additions
and
322 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
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
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
34 changes: 34 additions & 0 deletions
34
src/main/java/app/coronawarn/quicktest/config/CsvUploadConfig.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,34 @@ | ||
package app.coronawarn.quicktest.config; | ||
|
||
import lombok.Data; | ||
import org.springframework.boot.context.properties.ConfigurationProperties; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@ConfigurationProperties("s3") | ||
@Data | ||
public class CsvUploadConfig { | ||
private String accessKey; | ||
private String secretKey; | ||
private String bucketName; | ||
private int expiration; | ||
|
||
private Region region; | ||
|
||
private ProxyConfig proxy; | ||
|
||
|
||
|
||
@Data | ||
public static class Region { | ||
private String name = ""; | ||
private String endpoint; | ||
} | ||
|
||
@Data | ||
public static class ProxyConfig { | ||
private Boolean enabled = Boolean.FALSE; | ||
private String host; | ||
private Integer port; | ||
} | ||
} |
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
48 changes: 48 additions & 0 deletions
48
src/main/java/app/coronawarn/quicktest/config/S3StorageClientConfig.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,48 @@ | ||
package app.coronawarn.quicktest.config; | ||
|
||
import com.amazonaws.ClientConfiguration; | ||
import com.amazonaws.auth.AWSCredentials; | ||
import com.amazonaws.auth.AWSStaticCredentialsProvider; | ||
import com.amazonaws.auth.BasicAWSCredentials; | ||
import com.amazonaws.client.builder.AwsClientBuilder; | ||
import com.amazonaws.services.s3.AmazonS3; | ||
import com.amazonaws.services.s3.AmazonS3ClientBuilder; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class S3StorageClientConfig { | ||
|
||
private final CsvUploadConfig s3Config; | ||
|
||
/** | ||
* Creates a Bean for accessing S3 storage depending on application configuration. | ||
* | ||
* @return Preconfigured AmazonS3 instance. | ||
*/ | ||
@Bean | ||
public AmazonS3 getStorage() { | ||
ClientConfiguration clientConfig = new ClientConfiguration(); | ||
clientConfig.setSignerOverride("AWSS3V4SignerType"); | ||
|
||
if (s3Config.getProxy().getEnabled()) { | ||
log.info("Setting proxy for S3 connection."); | ||
clientConfig.setProxyHost(s3Config.getProxy().getHost()); | ||
clientConfig.setProxyPort(s3Config.getProxy().getPort()); | ||
} | ||
|
||
AWSCredentials credentials = new BasicAWSCredentials(s3Config.getAccessKey(), s3Config.getSecretKey()); | ||
|
||
return AmazonS3ClientBuilder.standard() | ||
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration( | ||
s3Config.getRegion().getEndpoint(), s3Config.getRegion().getName())) | ||
.withPathStyleAccessEnabled(true) | ||
.withClientConfiguration(clientConfig) | ||
.withCredentials(new AWSStaticCredentialsProvider(credentials)) | ||
.build(); | ||
} | ||
} |
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
146 changes: 146 additions & 0 deletions
146
src/main/java/app/coronawarn/quicktest/controller/CancellationController.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,146 @@ | ||
package app.coronawarn.quicktest.controller; | ||
|
||
import static app.coronawarn.quicktest.config.SecurityConfig.ROLE_TERMINATOR; | ||
|
||
import app.coronawarn.quicktest.config.CsvUploadConfig; | ||
import app.coronawarn.quicktest.domain.Cancellation; | ||
import app.coronawarn.quicktest.model.cancellation.CancellationRequest; | ||
import app.coronawarn.quicktest.service.CancellationService; | ||
import app.coronawarn.quicktest.utils.Utilities; | ||
import com.amazonaws.HttpMethod; | ||
import com.amazonaws.services.s3.AmazonS3; | ||
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest; | ||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponses; | ||
import java.net.URL; | ||
import java.time.Instant; | ||
import java.time.ZoneId; | ||
import java.time.ZonedDateTime; | ||
import java.util.ArrayList; | ||
import java.util.Date; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.access.annotation.Secured; | ||
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.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import org.springframework.web.server.ResponseStatusException; | ||
|
||
|
||
@Slf4j | ||
@RestController | ||
@RequestMapping(value = "/api/cancellation") | ||
@RequiredArgsConstructor | ||
public class CancellationController { | ||
|
||
private final CsvUploadConfig s3Config; | ||
|
||
private final AmazonS3 s3Client; | ||
|
||
private final CancellationService cancellationService; | ||
|
||
private final Utilities utils; | ||
|
||
/** | ||
* Endpoint for creating new cancellations. | ||
* | ||
* @return List of successfully reported PartnerIds | ||
*/ | ||
@Operation( | ||
summary = "Creates a cancellation entry for each given PartnerId", | ||
description = "Creates a cancellation entry for each given PartnerId and returns a list of them." | ||
) | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "Successful") | ||
}) | ||
@PostMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE) | ||
@Secured({ROLE_TERMINATOR}) | ||
public ResponseEntity<List<Cancellation>> createCancellations(@RequestBody CancellationRequest request) { | ||
List<Cancellation> cancellations = new ArrayList<>(); | ||
|
||
for (String partnerId : request.getPartnerIds()) { | ||
cancellations.add(cancellationService.createCancellation( | ||
partnerId, request.getCancellationDate().atZone(ZoneId.of("UTC")))); | ||
} | ||
|
||
return ResponseEntity.ok(cancellations); | ||
} | ||
|
||
/** | ||
* Endpoint for receiving information about cancellations. | ||
* | ||
* @return Cancellation information for users PartnerId | ||
*/ | ||
@Operation( | ||
summary = "Returns information about a cancellation", | ||
description = "Returns Information about a cancellation for the partnerId associated to the requesting user." | ||
) | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "Successful"), | ||
@ApiResponse(responseCode = "404", description = "No cancellation found for given PartnerId.") | ||
}) | ||
@GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE) | ||
public ResponseEntity<Cancellation> getCancellation() { | ||
Optional<Cancellation> cancellation = cancellationService.getByPartnerId(utils.getTenantIdFromToken()); | ||
|
||
if (cancellation.isPresent()) { | ||
return ResponseEntity.ok(cancellation.get()); | ||
} else { | ||
throw new ResponseStatusException( | ||
HttpStatus.NOT_FOUND, "No cancellation found for given PartnerId."); | ||
} | ||
} | ||
|
||
/** | ||
* Endpoint for receiving download link of tenant. | ||
* | ||
* @return Download link of csv for tenant | ||
*/ | ||
@Operation( | ||
summary = "Returns Download link of csv for tenant", | ||
description = "Returns Download link of csv with all quicktests for tenant." | ||
) | ||
@ApiResponses(value = { | ||
@ApiResponse(responseCode = "200", description = "Successful"), | ||
@ApiResponse(responseCode = "400", description = "Download Link for given PartnerId not yet available, " | ||
+ "cancellation might not have been processed yet."), | ||
@ApiResponse(responseCode = "404", description = "No cancellation found for given PartnerId.") | ||
}) | ||
@GetMapping(value = "/download", produces = MediaType.APPLICATION_JSON_VALUE) | ||
public ResponseEntity<URL> getCsvLink() { | ||
Optional<Cancellation> cancellation = cancellationService.getByPartnerId(utils.getTenantIdFromToken()); | ||
|
||
if (cancellation.isPresent() && ZonedDateTime.now().isAfter(cancellation.get().getCancellationDate())) { | ||
|
||
if (cancellation.get().getCsvCreated() != null && cancellation.get().getBucketObjectId() != null) { | ||
long expTimeMillis = Instant.now().toEpochMilli(); | ||
expTimeMillis += s3Config.getExpiration(); | ||
Date expiration = new Date(); | ||
expiration.setTime(expTimeMillis); | ||
GeneratePresignedUrlRequest generatePresignedUrlRequest = | ||
new GeneratePresignedUrlRequest(s3Config.getBucketName(), cancellation.get().getBucketObjectId()) | ||
.withMethod(HttpMethod.GET) | ||
.withExpiration(expiration); | ||
cancellationService.updateDownloadLinkRequested( | ||
cancellation.get(), ZonedDateTime.now(), utils.getUserNameFromToken()); | ||
return ResponseEntity.ok(s3Client.generatePresignedUrl(generatePresignedUrlRequest)); | ||
} else { | ||
throw new ResponseStatusException( | ||
HttpStatus.BAD_REQUEST, | ||
"Download Link for given PartnerId not yet available, " | ||
+ "cancellation might not have been processed yet."); | ||
} | ||
} else { | ||
throw new ResponseStatusException( | ||
HttpStatus.NOT_FOUND, "No cancellation found for given PartnerId."); | ||
} | ||
} | ||
} |
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.