Skip to content

Commit

Permalink
[SELC-3159] feat: send mail for approve on onboarding and registration (
Browse files Browse the repository at this point in the history
  • Loading branch information
manuraf authored Nov 10, 2023
1 parent fc334eb commit 17704ce
Show file tree
Hide file tree
Showing 13 changed files with 484 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,18 @@ public class OnboardingFunctions {
public static final String BUILD_CONTRACT_ACTIVITY_NAME = "BuildContract";
public static final String FORMAT_LOGGER_ONBOARDING_STRING = "%s: %s";
public static final String SEND_MAIL_REGISTRATION_WITH_CONTRACT_ACTIVITY_NAME = "SendMailRegistrationWithContract";
@Inject
OnboardingService service;
public static final String SEND_MAIL_REGISTRATION_REQUEST_ACTIVITY_NAME = "SendMailRegistrationRequest";
public static final String SEND_MAIL_REGISTRATION_APPROVE_ACTIVITY_NAME = "SendMailRegistrationApprove";
public static final String SEND_MAIL_ONBOARDING_APPROVE_ACTIVITY_NAME = "SendMailOnboardingApprove";

@Inject
ObjectMapper objectMapper;
private final OnboardingService service;

private final ObjectMapper objectMapper;

public OnboardingFunctions(OnboardingService service, ObjectMapper objectMapper) {
this.service = service;
this.objectMapper = objectMapper;
}

private static final TaskOptions optionsRetry;

Expand Down Expand Up @@ -81,7 +88,7 @@ public String onboardingsOrchestrator(
String onboardingId = ctx.getInput(String.class);
String onboardingString = getOnboardingString(onboardingId);

return onboardingsOrchestratorPAorSAorGSPIPA(ctx, onboardingString);
return onboardingsOrchestratorDefault(ctx, onboardingString);
}

private String getOnboardingString(String onboardingId) {
Expand All @@ -101,7 +108,8 @@ private String onboardingsOrchestratorDefault(TaskOrchestrationContext ctx, Stri
String result = "";
result += ctx.callActivity(BUILD_CONTRACT_ACTIVITY_NAME, onboardingString, optionsRetry, String.class).await() + ", ";
result += ctx.callActivity(SAVE_TOKEN_WITH_CONTRACT_ACTIVITY_NAME, onboardingString, optionsRetry, String.class).await() + ", ";
result += ctx.callActivity("SendMailRegistration", onboardingString, optionsRetry, String.class).await() + ", ";
result += ctx.callActivity(SEND_MAIL_REGISTRATION_APPROVE_ACTIVITY_NAME, onboardingString, optionsRetry, String.class).await() + ", ";
result += ctx.callActivity(SEND_MAIL_ONBOARDING_APPROVE_ACTIVITY_NAME, onboardingString, optionsRetry, String.class).await() + ", ";
return result;
}

Expand All @@ -126,11 +134,7 @@ private String onboardingsOrchestratorPG(TaskOrchestrationContext ctx, String on
@FunctionName(BUILD_CONTRACT_ACTIVITY_NAME)
public String buildContract(@DurableActivityTrigger(name = "onboardingString") String onboardingString, final ExecutionContext context) {
context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING, BUILD_CONTRACT_ACTIVITY_NAME, onboardingString));
try {
service.createContract(objectMapper.readValue(onboardingString, Onboarding.class));
} catch (JsonProcessingException e) {
throw new FunctionOrchestratedException(e);
}
service.createContract(readOnboardingValue(onboardingString));
return onboardingString;
}

Expand All @@ -140,11 +144,7 @@ public String buildContract(@DurableActivityTrigger(name = "onboardingString") S
@FunctionName(SAVE_TOKEN_WITH_CONTRACT_ACTIVITY_NAME)
public String saveToken(@DurableActivityTrigger(name = "onboardingString") String onboardingString, final ExecutionContext context) {
context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING, SAVE_TOKEN_WITH_CONTRACT_ACTIVITY_NAME, onboardingString));
try {
service.saveTokenWithContract(objectMapper.readValue(onboardingString, Onboarding.class));
} catch (JsonProcessingException e) {
throw new FunctionOrchestratedException(e);
}
service.saveTokenWithContract(readOnboardingValue(onboardingString));
return onboardingString;
}

Expand All @@ -154,20 +154,28 @@ public String saveToken(@DurableActivityTrigger(name = "onboardingString") Strin
@FunctionName(SEND_MAIL_REGISTRATION_WITH_CONTRACT_ACTIVITY_NAME)
public String sendMailRegistrationWithContract(@DurableActivityTrigger(name = "onboardingString") String onboardingString, final ExecutionContext context) {
context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING, SEND_MAIL_REGISTRATION_WITH_CONTRACT_ACTIVITY_NAME, onboardingString));
try {
service.sendMailRegistrationWithContract(objectMapper.readValue(onboardingString, Onboarding.class));
} catch (JsonProcessingException e) {
throw new FunctionOrchestratedException(e);
}
service.sendMailRegistrationWithContract(readOnboardingValue(onboardingString));
return onboardingString;
}

/**
* This is the activity function that gets invoked by the orchestrator function.
*/
@FunctionName("SendMailRegistration")
@FunctionName(SEND_MAIL_REGISTRATION_REQUEST_ACTIVITY_NAME)
public String sendMailRegistration(@DurableActivityTrigger(name = "onboardingString") String onboardingString, final ExecutionContext context) {
context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING, "SendMailRegistration", onboardingString));
context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING, SEND_MAIL_REGISTRATION_REQUEST_ACTIVITY_NAME, onboardingString));
service.sendMailRegistration(readOnboardingValue(onboardingString));
return onboardingString;
}

@FunctionName(SEND_MAIL_REGISTRATION_APPROVE_ACTIVITY_NAME)
public String sendMailRegistrationApprove(@DurableActivityTrigger(name = "onboardingString") String onboardingString, final ExecutionContext context) {
context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING, SEND_MAIL_REGISTRATION_APPROVE_ACTIVITY_NAME, onboardingString));
service.sendMailRegistrationApprove(readOnboardingValue(onboardingString));
return onboardingString;
}

@FunctionName(SEND_MAIL_ONBOARDING_APPROVE_ACTIVITY_NAME)
public String sendMailOnboardingApprove(@DurableActivityTrigger(name = "onboardingString") String onboardingString, final ExecutionContext context) {
context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING, SEND_MAIL_ONBOARDING_APPROVE_ACTIVITY_NAME, onboardingString));
service.sendMailOnboardingApprove(readOnboardingValue(onboardingString));
return onboardingString;
}

Expand All @@ -179,4 +187,12 @@ public String sendMailConfirmation(@DurableActivityTrigger(name = "onboardingStr
context.getLogger().info(String.format(FORMAT_LOGGER_ONBOARDING_STRING,"SendMailConfirmation", onboardingString));
return onboardingString;
}

private Onboarding readOnboardingValue(String onboardingString) {
try {
return objectMapper.readValue(onboardingString, Onboarding.class);
} catch (JsonProcessingException e) {
throw new FunctionOrchestratedException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ public interface MailTemplatePathConfig {

String registrationPath();

String notificationPath();
String onboardingApprovePath();

String rejectPath();
String registrationRequestPath();
String registrationNotificationAdminPath();
String registrationApprovePath();
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,5 @@ public interface MailTemplatePlaceholdersConfig {
String rejectOnboardingUrlValue();
String rejectProductName();

String notificationAdminEmail();


}
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,14 @@ public class ContractServiceDefault implements ContractService {
private static final Logger log = LoggerFactory.getLogger(ContractServiceDefault.class);
public static final String PDF_FORMAT_FILENAME = "%s.pdf";

@Inject
AzureStorageConfig azureStorageConfig;
private final AzureStorageConfig azureStorageConfig;

@Inject
AzureBlobClient azureBlobClient;
private final AzureBlobClient azureBlobClient;

public ContractServiceDefault(AzureStorageConfig azureStorageConfig, AzureBlobClient azureBlobClient) {
this.azureStorageConfig = azureStorageConfig;
this.azureBlobClient = azureBlobClient;
}

/**
* Creates a PDF contract document from a given contract template file and institution data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,11 @@

public interface NotificationService {

void sendMailRegistration(String institutionName, String destination, String name, String username, String productName);

void sendMailRegistrationApprove(String institutionName, String name, String username, String productName, String token);

void sendMailOnboardingApprove(String institutionName, String name, String username, String productName, String token);

void sendMailRegistrationWithContract(String onboardingId, String destination, String name, String username, String productName, String token);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import it.pagopa.selfcare.onboarding.entity.MailTemplate;
import it.pagopa.selfcare.onboarding.exception.GenericOnboardingException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.apache.commons.text.StringSubstitutor;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.slf4j.Logger;
Expand All @@ -19,10 +18,7 @@
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

Expand All @@ -35,18 +31,21 @@ public class NotificationServiceDefault implements NotificationService {

private static final Logger log = LoggerFactory.getLogger(NotificationServiceDefault.class);

final private MailTemplatePlaceholdersConfig templatePlaceholdersConfig;
final private MailTemplatePathConfig templatePathConfig;
final private AzureBlobClient azureBlobClient;
final private ObjectMapper objectMapper;
final private ContractService contractService;
final private String senderMail;
final private Boolean destinationMailTest;
final private String destinationMailTestAddress;
final private Mailer mailer;
private final MailTemplatePlaceholdersConfig templatePlaceholdersConfig;
private final MailTemplatePathConfig templatePathConfig;
private final AzureBlobClient azureBlobClient;
private final ObjectMapper objectMapper;
private final ContractService contractService;
private final String senderMail;
private final Boolean destinationMailTest;
private final String destinationMailTestAddress;

private final String notificationAdminMail;
private final Mailer mailer;

public NotificationServiceDefault(MailTemplatePlaceholdersConfig templatePlaceholdersConfig, MailTemplatePathConfig templatePathConfig,
AzureBlobClient azureBlobClient, ObjectMapper objectMapper, Mailer mailer, ContractService contractService,
@ConfigProperty(name = "onboarding-functions.notification-admin-email") String notificationAdminMail,
@ConfigProperty(name = "onboarding-functions.sender-mail") String senderMail,
@ConfigProperty(name = "onboarding-functions.destination-mail-test") Boolean destinationMailTest,
@ConfigProperty(name = "onboarding-functions.destination-mail-test-address") String destinationMailTestAddress) {
Expand All @@ -58,9 +57,47 @@ public NotificationServiceDefault(MailTemplatePlaceholdersConfig templatePlaceho
this.senderMail = senderMail;
this.destinationMailTest = destinationMailTest;
this.destinationMailTestAddress = destinationMailTestAddress;
this.notificationAdminMail = notificationAdminMail;
this.mailer = mailer;
}

@Override
public void sendMailRegistration(String institutionName, String destination, String name, String username, String productName) {

// Prepare data for email
Map<String, String> mailParameters = new HashMap<>();
mailParameters.put(templatePlaceholdersConfig.productName(), productName);
Optional.ofNullable(name).ifPresent(value -> mailParameters.put(templatePlaceholdersConfig.notificationRequesterName(), value));
Optional.ofNullable(username).ifPresent(value -> mailParameters.put(templatePlaceholdersConfig.notificationRequesterSurname(), value));
mailParameters.put(templatePlaceholdersConfig.institutionDescription(), institutionName);

sendMailWithFile(List.of(destination), templatePathConfig.registrationRequestPath(), mailParameters, productName, null);
}

@Override
public void sendMailRegistrationApprove(String institutionName, String name, String username, String productName, String token) {
sendMailOnboardingOrRegistrationApprove(institutionName, name, username, productName, token, templatePathConfig.registrationApprovePath());
}

@Override
public void sendMailOnboardingApprove(String institutionName, String name, String username, String productName, String token) {
sendMailOnboardingOrRegistrationApprove(institutionName, name, username, productName, token, templatePathConfig.onboardingApprovePath());
}


private void sendMailOnboardingOrRegistrationApprove(String institutionName, String name, String username, String productName, String token, String templatePath) {
// Prepare data for email
Map<String, String> mailParameters = new HashMap<>();
mailParameters.put(templatePlaceholdersConfig.productName(), productName);
Optional.ofNullable(name).ifPresent(value -> mailParameters.put(templatePlaceholdersConfig.notificationRequesterName(), value));
Optional.ofNullable(username).ifPresent(value -> mailParameters.put(templatePlaceholdersConfig.notificationRequesterSurname(), value));
mailParameters.put(templatePlaceholdersConfig.institutionDescription(), institutionName);
StringBuilder adminApproveLink = new StringBuilder(templatePlaceholdersConfig.adminLink());
mailParameters.put(templatePlaceholdersConfig.confirmTokenName(), adminApproveLink.append(token).toString());

sendMailWithFile(List.of(notificationAdminMail), templatePath, mailParameters, productName, null);
}

@Override
public void sendMailRegistrationWithContract(String onboardingId, String destination, String name, String username, String productName, String token) {

Expand All @@ -78,11 +115,6 @@ public void sendMailRegistrationWithContract(String onboardingId, String destina
throw new RuntimeException(e);
}

// Dev mode send mail to test digital address
List<String> destinationMail = destinationMailTest ?
List.of(destinationMailTestAddress):
List.of(destination);

// Prepare data for email
Map<String, String> mailParameters = new HashMap<>();
mailParameters.put(templatePlaceholdersConfig.productName(), productName);
Expand All @@ -91,33 +123,44 @@ public void sendMailRegistrationWithContract(String onboardingId, String destina
mailParameters.put(templatePlaceholdersConfig.rejectTokenName(), templatePlaceholdersConfig.rejectTokenPlaceholder() + token);
mailParameters.put(templatePlaceholdersConfig.confirmTokenName(), templatePlaceholdersConfig.confirmTokenPlaceholder() + token);

sendMailWithFile(destinationMail, templatePathConfig.registrationPath(), mailParameters, contractZipData, fileNameZip, productName);
log.debug("Mail registration with contract successful sent !!");
FileMailData fileMailData = new FileMailData();
fileMailData.contentType = "application/zip";
fileMailData.data = contractZipData;
fileMailData.name = fileNameZip;

sendMailWithFile(List.of(destination), templatePathConfig.registrationPath(), mailParameters, productName, fileMailData);
}

public void sendMailWithFile(List<String> destinationMail, String templateName, Map<String, String> mailParameters, byte[] fileData, String fileName, String prefixSubject) {
private void sendMailWithFile(List<String> destinationMail, String templateName, Map<String, String> mailParameters, String prefixSubject, FileMailData fileMailData) {
try {
log.info("START - sendMailWithFile to {}, with prefixSubject {}", destinationMail, prefixSubject);

// Dev mode send mail to test digital address
List<String> destinations = destinationMailTest ?
List.of(destinationMailTestAddress):
destinationMail;

log.info("Sending mail to {}, with prefixSubject {}", destinationMail, prefixSubject);
String template = azureBlobClient.getFileAsText(templateName);
MailTemplate mailTemplate = objectMapper.readValue(template, MailTemplate.class);
String html = StringSubstitutor.replace(mailTemplate.getBody(), mailParameters);
log.trace("sendMessage start");

final String subject = String.format("%s: %s", prefixSubject, mailTemplate.getSubject());

Mail mail = Mail
.withHtml(destinationMail.get(0), subject, html)
.addAttachment(fileName, fileData, "application/zip")
.withHtml(destinations.get(0), subject, html)
.setFrom(senderMail);

if(Objects.nonNull(fileMailData)) {
mail.addAttachment(fileMailData.name, fileMailData.data, fileMailData.contentType);
}

mailer.send(mail);

log.info("END - sendMail to {}, with subject {}", destinationMail, subject);
log.info("End of sending mail to {}, with subject {}", destinationMail, subject);
} catch (Exception e) {
log.error(ERROR_DURING_SEND_MAIL + ":" + e.getMessage());
log.error(String.format("%s: %s", ERROR_DURING_SEND_MAIL, e.getMessage()));
throw new GenericOnboardingException(ERROR_DURING_SEND_MAIL.getMessage());
}
log.trace("sendMessage end");
}

public byte[] zipBytes(String filename, byte[] data) {
Expand All @@ -136,4 +179,10 @@ public byte[] zipBytes(String filename, byte[] data) {
}
}

static class FileMailData {
byte[] data;
String name;
String contentType;
}

}
Loading

0 comments on commit 17704ce

Please sign in to comment.