-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
VKT(Backend) Viestintäpalvelu attachment proof of concept implementation
- Loading branch information
Showing
2 changed files
with
73 additions
and
14 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
package fi.oph.vkt.api; | ||
|
||
import static fi.oph.vkt.util.LocalisationUtil.localeFI; | ||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import fi.oph.vkt.api.dto.PublicEducationDTO; | ||
import fi.oph.vkt.api.dto.PublicEnrollmentCreateDTO; | ||
|
@@ -16,16 +17,21 @@ | |
import fi.oph.vkt.model.type.EnrollmentType; | ||
import fi.oph.vkt.model.type.ExamLevel; | ||
import fi.oph.vkt.model.type.FreeEnrollmentType; | ||
import fi.oph.vkt.repository.EnrollmentRepository; | ||
import fi.oph.vkt.service.FeatureFlagService; | ||
import fi.oph.vkt.service.PaymentService; | ||
import fi.oph.vkt.service.PublicAuthService; | ||
import fi.oph.vkt.service.PublicEnrollmentService; | ||
import fi.oph.vkt.service.PublicExamEventService; | ||
import fi.oph.vkt.service.PublicPersonService; | ||
import fi.oph.vkt.service.PublicReservationService; | ||
import fi.oph.vkt.service.email.EmailAttachmentData; | ||
import fi.oph.vkt.service.email.EmailData; | ||
import fi.oph.vkt.service.email.sender.EmailSenderViestintapalveluNew; | ||
import fi.oph.vkt.service.koski.KoskiService; | ||
import fi.oph.vkt.service.receipt.ReceiptData; | ||
import fi.oph.vkt.service.receipt.ReceiptRenderer; | ||
import fi.oph.vkt.util.LocalisationUtil; | ||
import fi.oph.vkt.util.SessionUtil; | ||
import fi.oph.vkt.util.UIRouteUtil; | ||
import fi.oph.vkt.util.exception.APIException; | ||
|
@@ -39,6 +45,7 @@ | |
import java.util.Arrays; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Locale; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.concurrent.ExecutionException; | ||
|
@@ -95,6 +102,12 @@ public class PublicController { | |
@Resource | ||
private CasClient casClient; | ||
|
||
@Resource | ||
private EnrollmentRepository enrollmentRepository; | ||
|
||
@Resource | ||
private ReceiptRenderer receiptRenderer; | ||
|
||
@GetMapping(path = "/examEvent") | ||
public List<PublicExamEventDTO> list() { | ||
return publicExamEventService.listExamEvents(ExamLevel.EXCELLENT); | ||
|
@@ -339,6 +352,16 @@ public void paymentSuccess( | |
public void email( | ||
) throws IOException, ExecutionException, InterruptedException { | ||
final EmailSenderViestintapalveluNew emailSenderViestintapalveluNew = new EmailSenderViestintapalveluNew(casClient, Constants.SERVICENAME, Constants.EMAIL_SENDER_NAME); | ||
|
||
final byte[] receiptBytes = "test".getBytes(); | ||
|
||
final EmailAttachmentData emailAttachmentData = EmailAttachmentData | ||
.builder() | ||
.name("test.txt") | ||
.contentType("text/plain") | ||
.data(receiptBytes) | ||
.build(); | ||
|
||
emailSenderViestintapalveluNew.sendEmail( | ||
EmailData | ||
.builder() | ||
|
@@ -347,7 +370,7 @@ public void email( | |
.recipientAddress("[email protected]") | ||
.recipientName("Test") | ||
.body("This is a test") | ||
.attachments(List.of()) | ||
.attachments(List.of(emailAttachmentData)) | ||
.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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,9 +18,8 @@ | |
import org.asynchttpclient.Request; | ||
import org.asynchttpclient.RequestBuilder; | ||
import org.asynchttpclient.Response; | ||
import org.asynchttpclient.request.body.multipart.ByteArrayPart; | ||
import org.asynchttpclient.util.HttpConstants; | ||
import org.springframework.http.MediaType; | ||
import reactor.core.publisher.Mono; | ||
|
||
@RequiredArgsConstructor | ||
public class EmailSenderViestintapalveluNew implements EmailSender { | ||
|
@@ -36,14 +35,15 @@ public class EmailSenderViestintapalveluNew implements EmailSender { | |
@Override | ||
public String sendEmail(final EmailData emailData) throws JsonProcessingException, ExecutionException, InterruptedException { | ||
final ObjectMapper objectMapper = new ObjectMapper(); | ||
final Map<String, Object> postData = createPostData(emailData); | ||
final List<String> attachments = createAndPostAttachments(emailData.attachments()); | ||
final Map<String, Object> postData = createPostData(emailData, attachments); | ||
final String body = objectMapper.writeValueAsString(postData); | ||
|
||
final Request request = new RequestBuilder() | ||
.setUrl("https://viestinvalitys.testiopintopolku.fi/lahetys/v1/viestit") | ||
.setMethod("POST") | ||
.setBody(body) | ||
.setRequestTimeout(Duration.ofMillis(10000)) | ||
.setRequestTimeout(Duration.ofSeconds(10)) | ||
.addHeader("Caller-Id", callerId) | ||
.addHeader("Content-Type", "application/json") | ||
.addHeader("Accept", "application/json") | ||
|
@@ -53,7 +53,7 @@ public String sendEmail(final EmailData emailData) throws JsonProcessingExceptio | |
final Response response = casClient.executeAndRetryWithCleanSessionOnStatusCodes(request, Set.of(401)).get(); | ||
|
||
if (response.getStatusCode() == HttpConstants.ResponseStatusCodes.OK_200) { | ||
return parseExternalId(response.getResponseBody()); | ||
return parseExternalId(response.getResponseBody(), "lahetysTunniste"); | ||
} | ||
} catch (Exception e) { | ||
throw e; | ||
|
@@ -62,7 +62,7 @@ public String sendEmail(final EmailData emailData) throws JsonProcessingExceptio | |
return null; | ||
} | ||
|
||
private Map<String, Object> createPostData(final EmailData emailData) { | ||
private Map<String, Object> createPostData(final EmailData emailData, final List<String> attachments) { | ||
final Map<String, Object> senderFields = Map.of("nimi", sender, "sahkopostiOsoite", "[email protected]"); | ||
// Allowed characters: a-z, A-Z, 0-9 ja -_. | ||
final String emailKeyPrefix = "vkt-email-"; | ||
|
@@ -90,26 +90,62 @@ private Map<String, Object> createPostData(final EmailData emailData) { | |
"sailytysaika", | ||
expirationDays, | ||
"idempotencyKey", | ||
emailKeyPrefix + emailData.id() | ||
//"attachments", | ||
//createAttachments(emailData.attachments()) | ||
emailKeyPrefix + emailData.id(), | ||
"liitteidenTunnisteet", | ||
attachments | ||
); | ||
} | ||
|
||
private List<Map<String, Object>> createAttachments(final List<EmailAttachmentData> attachments) { | ||
private String postAttachment(final EmailAttachmentData attachment) throws ExecutionException, InterruptedException, JsonProcessingException { | ||
final Request request = new RequestBuilder() | ||
.setUrl("https://viestinvalitys.testiopintopolku.fi/lahetys/v1/liitteet") | ||
.setMethod("POST") | ||
.addBodyPart(new ByteArrayPart("liite", attachment.data(), attachment.contentType(), null, attachment.name())) | ||
.setRequestTimeout(Duration.ofSeconds(10)) | ||
.addHeader("Caller-Id", callerId) | ||
.addHeader("Content-Type", "multipart/form-data") | ||
.addHeader("Accept", "application/json") | ||
.build(); | ||
|
||
try { | ||
final Response response = casClient.executeAndRetryWithCleanSessionOnStatusCodes(request, Set.of(401)).get(); | ||
|
||
if (response.getStatusCode() == HttpConstants.ResponseStatusCodes.OK_200) { | ||
final String id = parseExternalId(response.getResponseBody(), "liiteTunniste"); | ||
|
||
if (id == null) { | ||
throw new RuntimeException(""); | ||
} | ||
|
||
return id; | ||
} else { | ||
throw new RuntimeException(""); | ||
} | ||
} catch (Exception e) { | ||
throw e; | ||
} | ||
} | ||
|
||
private List<String> createAndPostAttachments(final List<EmailAttachmentData> attachments) { | ||
return Optional | ||
.ofNullable(attachments) | ||
.map(nonNullAttachments -> | ||
nonNullAttachments | ||
.stream() | ||
.map(a -> Map.<String, Object>of("data", a.data(), "name", a.name(), "contentType", a.contentType())) | ||
.map(attachment -> { | ||
try { | ||
return postAttachment(attachment); | ||
} catch (final Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
}) | ||
.toList() | ||
) | ||
.orElse(List.of()); | ||
} | ||
|
||
private String parseExternalId(final String result) throws JsonProcessingException { | ||
private String parseExternalId(final String result, final String key) throws JsonProcessingException { | ||
final Map<String, String> map = OBJECT_MAPPER.readValue(result, new TypeReference<>() {}); | ||
return map.get("id"); | ||
return map.get(key); | ||
} | ||
} |