EmailClient.java
- package no.nav.data.common.mail;
- import io.netty.handler.logging.LogLevel;
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
- import org.springframework.http.client.reactive.ReactorClientHttpConnector;
- import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
- import org.springframework.security.oauth2.client.web.reactive.function.client.ServletOAuth2AuthorizedClientExchangeFilterFunction;
- import org.springframework.stereotype.Component;
- import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
- import org.springframework.web.reactive.function.client.WebClient;
- import org.springframework.web.reactive.function.client.WebClientResponseException;
- import reactor.core.publisher.Mono;
- import reactor.netty.http.client.HttpClient;
- import reactor.netty.transport.logging.AdvancedByteBufFormat;
- import reactor.util.retry.Retry;
- import java.time.Duration;
- import java.util.List;
- @Component
- public class EmailClient {
- public static final Logger logger = LogManager.getLogger(EmailClient.class);
- private final WebClient webClient;
- private final EmailProperties emailProperties;
- public EmailClient(
- OAuth2AuthorizedClientManager oAuth2AuthorizedClientManager,
- EmailProperties emailProperties
- ) {
- this.emailProperties = emailProperties;
- var oAuth2Filter = new ServletOAuth2AuthorizedClientExchangeFilterFunction(oAuth2AuthorizedClientManager);
- oAuth2Filter.setDefaultClientRegistrationId("email");
- this.webClient = WebClient.builder()
- .filter(oAuth2Filter)
- .baseUrl(emailProperties.baseUrl())
- .build();
- }
- public Mono<Void> sendEmail(MailTask mailTask) {
- if (emailProperties.enabled()) {
- var emailMessage = mapFrom(mailTask);
- return webClient.post()
- .body(Mono.just(emailMessage), EmailMessage.class)
- .retrieve()
- .bodyToMono(Void.class)
- .retryWhen(defaultRetry(emailProperties.maxAttempts(), emailProperties.backoffDurationMillis()))
- .doOnError(WebClientResponseException.class, (WebClientResponseException webClientResponseException) -> {
- String errorMsg = String.format(
- "POST %s resulted in status %s with body %s",
- webClientResponseException.getRequest() != null ? webClientResponseException.getRequest().getURI() : "n/a",
- webClientResponseException.getStatusCode().value(),
- webClientResponseException.getResponseBodyAsString()
- );
- throw new EmailClientUnforseenException(errorMsg);
- });
- } else {
- logger.info("Email which would have been sent: {}", mailTask);
- return Mono.empty();
- }
- }
- private EmailMessage mapFrom(MailTask mailTask){
- return new EmailMessage(
- mailTask.getSubject(),
- mailTask.getBody(),
- List.of(mailTask.getTo())
- );
- }
- private Retry defaultRetry(Integer maxAttempts, Integer backoffDurationMillis) {
- return Retry.backoff(maxAttempts, Duration.ofMillis(backoffDurationMillis)).jitter(0.75).filter(throwable -> {
- if (throwable instanceof WebClientResponseException) {
- return ((WebClientResponseException) throwable).getStatusCode().is5xxServerError();
- }
- return false;
- }).onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> {
- Throwable throwable = retrySignal.failure();
- if (throwable instanceof WebClientResponseException) {
- throw (WebClientResponseException) throwable;
- }
- throw new RuntimeException(throwable);
- });
- }
- }