CompletableFuture para envio de emails

Codigo

En algunas ocasiones necesitamos realizar otros procesos mientras se termina un proceso y bloquear el panel hasta que termine de ejecutarse.

Y ejecutar otros procesos mientras se envian los emails

formulario

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:b="http://bootsfaces.net/ui"
      xmlns:p="http://primefaces.org/ui">

    <f:view contentType="text/html">
        <h:head>
            <f:facet name="first">
                <meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
                <title>PrimeFaces</title>
            </f:facet>
        </h:head>

        <h:body>

            <b:form id="form" prependId="false">
              
                
             <p:panel id="panel" header="Email Asincronicos" style="margin-bottom:10px;">
                   <p:messages id="messages" showDetail="true" closable="true">
                    <p:autoUpdate />
                </p:messages>
              
                 <h:panelGrid columns="2" cellpadding="5">
                    <p:outputLabel value="Time"/>
                    <p:inputText value="#{prueba.time}"/>
                    <p:outputLabel value="component"/>
                    <p:inputText value="#{prueba.component}"/>
                    <p:outputLabel value="Send Email"/>
                    <p:commandButton value="Send"
                                     id="send"
                                     update=":form :form:messages"
                                     action="#{prueba.enviar()}"/>
                    </h:panelGrid>
             </p:panel>
                
                 <p:blockUI block="panel" trigger="send" />
            </b:form>


        </h:body>

    </f:view>
</html>

Controller

Crear la funcion

public Future<String> calculateAsync() throws InterruptedException {
        System.out.println("---->invocando");
        CompletableFuture<String> completableFuture
                = new CompletableFuture<>();

        Executors.newCachedThreadPool().submit(() -> {
            System.out.println("........ voy a enviar el email");
                Date date = new Date();
                managerEmail.sendOutlook("destino@gmail.com", "Async}", "prueba a " + date.toString(), "origen@email.com", "mipassword");
            System.out.println(".......... email enviado");
//              Thread.sleep(2500);
                Thread.sleep(time);
                completableFuture.complete("Hello");
         

            return null;
        });

        return completableFuture;
    }

Invocarla

 Future<String> completableFuture = calculateAsync();
         

// ... 
            String result = completableFuture.get();

Si comentamos la linea

   String result = completableFuture.get();
   

La aplicación continua y esos procesos quedan en hilos

Código Completo

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.book.web;

import com.avbravo.jmoordbutils.JsfUtil;
import com.avbravo.jmoordbutils.email.ManagerEmail;
import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.omnifaces.util.Ajax;
import org.primefaces.PrimeFaces;

/**
 *
 * @author avbravo
 */
@Named
@ViewScoped
public class Prueba implements Serializable {

    ManagerEmail managerEmail = new ManagerEmail();
    private Integer time = 2500;
    private String component = "form:panel";
    Integer contadoremail = 0;

    public Integer getTime() {
        return time;
    }

    public String getComponent() {
        return component;
    }

    public void setComponent(String component) {
        this.component = component;
    }

    public void setTime(Integer time) {
        this.time = time;
    }

    public void enviar() {
        try {
            long start = System.currentTimeMillis();
            JsfUtil.successMessage("voy a enviar " + start);

            Future<String> completableFuture = calculateAsync();
            System.out.println("... mientras se envia, ejecuta las acciones siguientes");

            /*
            Si se utiliza el esperara que termine.
            Cuando no se usa el completableFuture.get(); el programa sigue su curso
            y queda en un hilo el envio de emails
           
             */
            // String result = completableFuture.get();
            long end = System.currentTimeMillis();

            System.out.println("Tiempo estimado: " + (end - start));
        } catch (Exception e) {
            System.out.println("Error " + e.getLocalizedMessage());
        }
    }

    public Future<String> calculateAsync() throws InterruptedException {
        System.out.println("---->calculateAsync()");
        contadoremail++;
        CompletableFuture<String> completableFuture
                = new CompletableFuture<>();

        Executors.newCachedThreadPool().submit(() -> {
            System.out.println("........ Voy a enviar el email");
            Date date = new Date();
            managerEmail.sendOutlook("miemail@gmail.com", "{Async}:" + contadoremail, "prueba a " + date.toString(), "emailemisor@gmail.com", "passwordemisor");
            System.out.println(".......... Email enviado");
//              Thread.sleep(2500);
          //  Thread.sleep(time);
            completableFuture.complete("Hello");

            return null;
        });

        return completableFuture;
    }
}

Last updated