1
votes

Existe-t-il une belle solution pour désactiver toutes les notifications par e-mail?

J'ai un service de messagerie qui envoie simplement une notification aux destinataires.

@RestController
public class MyRestController {

        @Autowired
        private MailService mailService;

        @PostMapping("/orders")
        public void createOrders(@RequestBody List<Order> orders) {
                // manipulations with orders
                mailService.send("Order notification", "New orders", "1@mail.com");
        }
}

Et puis j'ai un contrôleur de repos qui appelle cette méthode après une logique métier.

@Service
public class MailService {

        @Autowired
        private JavaMailSender mailSender;

        public void send(String subject, String text, String... emails) {
                // MailMessage object configuration
                mailSender.send(mail);
        }
}

Comment concevoir une application pour désactiver les notifications pour différents profils de ressort? Existe-t-il des bonnes pratiques pour configurer la distribution des e-mails en fonction du profil?


0 commentaires

3 Réponses :


0
votes

Ayez juste une implémentation fictive pour les profils qui en ont besoin

@Bean
@Profile("prod")
public JavaMailSender getRealJavaMailSender() {
    JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
    mailSender.setHost("smtp.gmail.com");
    mailSender.setPort(587);
     
    mailSender.setUsername("my.gmail@gmail.com");
    mailSender.setPassword("password");
     
    Properties props = mailSender.getJavaMailProperties();
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.debug", "true");
     
    return mailSender;
}

@Bean
@Profile("test")
public JavaMailSender getDummyJavaMailSender() {
    return new JavaMailSender() {
        ... dummy method implementations ...
    };
}


0 commentaires

0
votes

Utilisation de plusieurs implémentations

Une possibilité est de créer une interface MailService avec deux implémentations. En combinant ces implémentations avec l'annotation @Profile , vous pouvez correctement injecter l'une ou l'autre implémentation en fonction du profil que vous utilisez. Par exemple:

@RestController
public class MyRestController {

    @Autowired
    private MailService mailService;
    @Autowired
    private Environment environment;  

    @PostMapping("/orders")
    public void createOrders(@RequestBody List<Order> orders) {
        // manipulations with orders
        if (environment.acceptsProfiles(Profiles.of("mail"))) {
            mailService.send("Order notification", "New orders", "1@mail.com");
        }
    }
}

Ensuite, vous pouvez ajouter l'annotation @Profile ("mail") à une implémentation:

@Aspect
@Component
@Profile("mail")
public class OrderNotificationAspect {
    private final MailService mailService;

    public OrderNotificationAspect(MailService mailService) {
        this.mailService = mailService;
    }

    @AfterReturning("execution(* com.example.MyRestController.createOrders(..))")
    public void sendNotification() {
        mailService.send("Order notification", "New orders", "1@mail.com");
    }
}

De plus, vous pouvez ajouter une autre implémentation lorsque le profil de messagerie n'est pas actif:

@RestController
public class MyRestController {

    @PostMapping("/orders")
    public void createOrders(@RequestBody List<Order> orders) {
        // manipulations with orders
    }
}

Si vous utilisez maintenant MailService code> dans votre contrôleur, il implémentera correctement l'implémentation correcte en fonction du profil que vous utilisez.


Utilisation des aspects

Une autre alternative consiste à découpler l'envoi de mails entièrement depuis la logique de création de commande en utilisant des aspects.

Cela vous permet de supprimer complètement la dépendance MailService du contrôleur MyRestController :

@Service
@Profile("!mail") // By adding the exclamination mark, this implementation will be used when the mail profile isn't active
public class NoopMailServiceImpl implements MailService {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void send(String subject, String text, String... emails) {
        logger.debug("Dummy implementation, no e-mail is being sent");
    }
}

Au lieu de cela, vous ajoutez la logique mailService à un aspect distinct:

@Service
@Profile("mail") // Only create this bean when the 'mail' profile is used
public class JavaMailServiceImpl implements MailService {

    @Autowired
    private JavaMailSender mailSender;

    public void send(String subject, String text, String... emails) {
        // MailMessage object configuration
        mailSender.send(mail);
    }
}

Comme avant, nous utilisons l'annotation @Profile pour n'enregistrer le bean aspect que lorsque le profil de messagerie est actif. Cependant, comme nous ne lions plus directement le contrôleur au MailService , nous n'avons plus besoin de la "mise en œuvre factice".

Pour utiliser des aspects dans Spring boot, vous devez ajouter le Dépendance spring-boot-starter-aop .


Vérification des profils par programmation

Une autre option consiste à écrire la vérification dans votre code, par exemple:

public interface MailService {
    void send(String subject, String text, String... emails);
}

En fonction de la finesse de cette logique, vous pouvez soit la mettre dans le contrôleur, soit dans le service (si vous souhaitez désactiver tous les e-mails envoyé pour un profil spécifique).


L'option que vous choisissez dépend de vos besoins. L'utilisation de plusieurs implémentations est le moyen le plus simple de désactiver l'envoi de tous les e-mails.

Cependant, si vous souhaitez uniquement désactiver l'envoi de certains e-mails, vous devrez choisir un autre moyen. L'inconvénient de l'utilisation des aspects est que cela rend le flux parfois un peu plus difficile à suivre, bien que les IDE prennent en charge assez bien certains aspects.


0 commentaires

0
votes

Je suggère d'ajouter une variable (par exemple sendEmails = false ) aux fichiers application- [profile-name] .properties avec des paramètres différents pour chaque profil.

Ensuite dans votre code vous pouvez utiliser cette propriété pour décider si les e-mails doivent être envoyés.

@Service
public class MailService {

    @Value("sendEmails}")
    private boolean sendEmails;

    @Autowired
    private JavaMailSender mailSender;

    public void send(String subject, String text, String... emails) {
        if (sendEmails) {
            // MailMessage object configuration
            mailSender.send(mail);
        }
    }
}

Cette approche vous permet d'utiliser des paramètres différents (et facilement modifiables) pour chaque profil.


0 commentaires