From d45bc3f1e7b85d6dad061933723e2fd7c6a4a848 Mon Sep 17 00:00:00 2001 From: Falucho <german.faller@pcunix71.fing.edu.uy> Date: Sun, 23 Jun 2019 01:13:35 -0300 Subject: [PATCH] Push en BackOffice --- backoffice/pom.xml | 12 ++- .../java/uy/edu/fing/tse/jsf/AjaxBean.java | 71 ++++++++++++++ .../java/uy/edu/fing/tse/jsf/RequestBean.java | 95 ++++++++++++++++++- backoffice/src/main/webapp/WEB-INF/beans.xml | 8 +- .../webapp/WEB-INF/templates/template.xhtml | 35 ++++--- backoffice/src/main/webapp/WEB-INF/web.xml | 5 + backoffice/src/main/webapp/index.xhtml | 36 ++++++- backoffice/src/main/webapp/jsf/ajax.xhtml | 59 ++++++++++++ .../fing/tse/central/business/Business.java | 5 + .../tse/central/business/BusinessBean.java | 18 ++++ .../tse/central/business/common/Notifier.java | 29 ++++++ pom.xml | 7 ++ 12 files changed, 346 insertions(+), 34 deletions(-) create mode 100644 backoffice/src/main/java/uy/edu/fing/tse/jsf/AjaxBean.java create mode 100644 backoffice/src/main/webapp/jsf/ajax.xhtml create mode 100644 central-ejb/src/main/java/uy/edu/fing/tse/central/business/common/Notifier.java diff --git a/backoffice/pom.xml b/backoffice/pom.xml index f4bf4d2..5174f39 100644 --- a/backoffice/pom.xml +++ b/backoffice/pom.xml @@ -40,12 +40,18 @@ <scope>provided</scope> </dependency> + <!-- <dependency>--> + <!-- <groupId>org.jboss.spec.javax.faces</groupId>--> + <!-- <artifactId>jboss-jsf-api_2.3_spec</artifactId>--> + <!-- <scope>provided</scope>--> + <!-- </dependency>--> + <dependency> - <groupId>org.jboss.spec.javax.faces</groupId> - <artifactId>jboss-jsf-api_2.3_spec</artifactId> - <scope>provided</scope> + <groupId>org.wildfly</groupId> + <artifactId>wildfly-jsf</artifactId> </dependency> + <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> diff --git a/backoffice/src/main/java/uy/edu/fing/tse/jsf/AjaxBean.java b/backoffice/src/main/java/uy/edu/fing/tse/jsf/AjaxBean.java new file mode 100644 index 0000000..da97bad --- /dev/null +++ b/backoffice/src/main/java/uy/edu/fing/tse/jsf/AjaxBean.java @@ -0,0 +1,71 @@ +package uy.edu.fing.tse.jsf; + +import javax.faces.event.AbortProcessingException; +import javax.faces.event.AjaxBehaviorEvent; +import javax.faces.push.Push; +import javax.faces.push.PushContext; +import javax.faces.view.ViewScoped; +import javax.inject.Inject; +import javax.inject.Named; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * @author hantsy + */ +@ViewScoped +@Named("ajaxBean") +public class AjaxBean implements Serializable { + + private static final Logger LOG = Logger.getLogger(AjaxBean.class.getName()); + + @Inject + @Push + PushContext ajaxChannel; + + @Inject + @Push + PushContext ajaxListenerChannel; + + @Inject + @Push + PushContext commandScriptChannel; + + private List<String> messages = new ArrayList<>(); + + public void ajaxPushed(AjaxBehaviorEvent e) throws AbortProcessingException { + LOG.log(Level.INFO, "ajax pushed: " + e.toString()); + messages.add("ajaxListenerEvent is sent at: " + LocalDateTime.now()); + } + + public void commandScriptExecuted() { + LOG.log(Level.INFO, "commandScriptExecuted pushed."); + messages.add("commandScriptExecuted message is sent at: " + LocalDateTime.now()); + } + + public void pushToAjaxChannel() { + messages.add("ajaxEvent is sent at: " + LocalDateTime.now()); + ajaxChannel.send("ajaxEvent"); + } + + public void pushToAjaxListenerChannel() { + ajaxListenerChannel.send("ajaxListenerEvent"); + } + + public void pushToCommandScriptChannel() { + commandScriptChannel.send("onCommandScript"); + } + + public List<String> getMessages() { + return messages; + } + + public void setMessages(List<String> messages) { + this.messages = messages; + } + +} \ No newline at end of file diff --git a/backoffice/src/main/java/uy/edu/fing/tse/jsf/RequestBean.java b/backoffice/src/main/java/uy/edu/fing/tse/jsf/RequestBean.java index ad64d9f..55aee8d 100644 --- a/backoffice/src/main/java/uy/edu/fing/tse/jsf/RequestBean.java +++ b/backoffice/src/main/java/uy/edu/fing/tse/jsf/RequestBean.java @@ -1,18 +1,105 @@ package uy.edu.fing.tse.jsf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import uy.edu.fing.tse.central.business.BusinessLocal; +import uy.edu.fing.tse.central.business.common.Notifier; +import uy.edu.fing.tse.dto.Peripherical; +import javax.annotation.PostConstruct; import javax.ejb.EJB; -import javax.enterprise.context.RequestScoped; +import javax.faces.event.AbortProcessingException; +import javax.faces.event.AjaxBehaviorEvent; +import javax.faces.push.Push; +import javax.faces.push.PushContext; +import javax.faces.view.ViewScoped; +import javax.inject.Inject; import javax.inject.Named; +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; -@Named -@RequestScoped -public class RequestBean { +@Named("faller") +@ViewScoped +public class RequestBean implements Serializable { + private static final long serialVersionUID = 4465735311570405045L; + + + private static final Logger LOG = LoggerFactory.getLogger(RequestBean.class); @EJB private BusinessLocal negocio; + @Inject + @Push + PushContext channel; + + + private Peripherical peri; + private String name = "German"; + private String async; + + private List<String> mensaje = new ArrayList<>(); + + @PostConstruct + public void init() { + LOG.info("Init"); + mensaje.add("INIT"); + Notifier.subscribe("test", this::pushToChannel); + } + + public void pushed(AjaxBehaviorEvent e) throws AbortProcessingException { + LOG.info("ajax pushed: " + e.toString()); + mensaje.add("ajaxListenerEvent is sent at: " + LocalDateTime.now()); + } + + public void commandScriptExecuted() { + LOG.info("commandScriptExecuted pushed."); + mensaje.add("commandScriptExecuted message is sent at: " + LocalDateTime.now()); + } + + public void pushToChannel(String s) { + mensaje.add("Push: " + s); + channel.send("updatemsg"); + } + + + public void hacerAlgo() { + LOG.info("hacerAlgo"); + negocio.test(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAsync() { + return async; + } + + public void setAsync(String async) { + this.async = async; + } + + public Peripherical getPeri() { + return peri; + } + + public void setPeri(Peripherical peri) { + this.peri = peri; + } + + public List<String> getMensajes() { + return mensaje; + } + public void setMensajes(List<String> mensaje) { + this.mensaje = mensaje; + } } diff --git a/backoffice/src/main/webapp/WEB-INF/beans.xml b/backoffice/src/main/webapp/WEB-INF/beans.xml index 76426bc..e71e480 100644 --- a/backoffice/src/main/webapp/WEB-INF/beans.xml +++ b/backoffice/src/main/webapp/WEB-INF/beans.xml @@ -1,7 +1 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- Marker file indicating CDI should be enabled --> -<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation=" - http://xmlns.jcp.org/xml/ns/javaee - http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all"> -</beans> +<beans></beans> \ No newline at end of file diff --git a/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml b/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml index 6a23d21..0f091e8 100644 --- a/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml +++ b/backoffice/src/main/webapp/WEB-INF/templates/template.xhtml @@ -1,21 +1,26 @@ <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" - xmlns:ui="http://java.sun.com/jsf/facelets"> - -<head> + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:p="http://primefaces.org/ui" + xmlns:h="http://xmlns.jcp.org/jsf/html" +> +<h:head> <title>BackOffice - feiknius</title> -</head> -<body> -<header> +</h:head> + +<h:body> -</header> -<!-- Menús, headers y todo lo que vaya antes del contenido --> -<ui:insert name="contenido"> - Contenido por defecto para que no quede en blanco... -</ui:insert> -<!-- Footer y otros componentes que vayan después del contenido --> -<footer> + <header> + <h1>BackOffice - feiknius</h1> + </header> + <!-- Menús, headers y todo lo que vaya antes del contenido --> + <p:messages/> + <ui:insert name="contenido"> + Contenido por defecto para que no quede en blanco... + </ui:insert> + <!-- Footer y otros componentes que vayan después del contenido --> + <footer> -</footer> -</body> + </footer> +</h:body> </html> \ No newline at end of file diff --git a/backoffice/src/main/webapp/WEB-INF/web.xml b/backoffice/src/main/webapp/WEB-INF/web.xml index 891e0f2..17e6bd9 100644 --- a/backoffice/src/main/webapp/WEB-INF/web.xml +++ b/backoffice/src/main/webapp/WEB-INF/web.xml @@ -27,6 +27,11 @@ <param-value>true</param-value> </context-param> + <context-param> + <param-name>javax.faces.ENABLE_WEBSOCKET_ENDPOINT</param-name> + <param-value>true</param-value> + </context-param> + <!-- JSF mapping --> <servlet> <servlet-name>Faces Servlet</servlet-name> diff --git a/backoffice/src/main/webapp/index.xhtml b/backoffice/src/main/webapp/index.xhtml index 5856e54..08b9fd6 100644 --- a/backoffice/src/main/webapp/index.xhtml +++ b/backoffice/src/main/webapp/index.xhtml @@ -1,7 +1,33 @@ -<ui:decorate xmlns="http://www.w3.org/1999/xhtml" - xmlns:ui="http://java.sun.com/jsf/facelets" template="WEB-INF/templates/template.xhtml"> +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" + xmlns:ui="http://java.sun.com/jsf/facelets" + xmlns:p="http://primefaces.org/ui" + xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html" +> +<body> + +<ui:decorate template="WEB-INF/templates/template.xhtml"> <ui:define name="contenido"> - <h1>Contenido que inserta el cliente en el template.</h1> - <h1>FALLER</h1> + <h1>Push</h1> + <h:panelGroup id="messagePanel" layout="block"> + <ul> + <ui:repeat value="#{faller.mensajes}" var="message"> + <li>#{message}</li> + </ui:repeat> + </ul> + </h:panelGroup> + <h:form> + <p:outputLabel value="#{faller.async}"/> + <p:inputText value="#{faller.name}"/> + <p:commandButton value="tocame" action="#{faller.hacerAlgo()}"/> + </h:form> + <h:form> + <f:websocket channel="channel" scope="view"> + <f:ajax event="updatemsg" listener="#{faller.pushed}" render=":messagePanel"/> + </f:websocket> + </h:form> + </ui:define> -</ui:decorate> \ No newline at end of file +</ui:decorate> +</body> +</html> \ No newline at end of file diff --git a/backoffice/src/main/webapp/jsf/ajax.xhtml b/backoffice/src/main/webapp/jsf/ajax.xhtml new file mode 100644 index 0000000..940a5db --- /dev/null +++ b/backoffice/src/main/webapp/jsf/ajax.xhtml @@ -0,0 +1,59 @@ +<!DOCTYPE html> +<html lang="en" + xmlns="http://www.w3.org/1999/xhtml" + xmlns:ui="http://xmlns.jcp.org/jsf/facelets" + xmlns:f="http://xmlns.jcp.org/jsf/core" + xmlns:h="http://xmlns.jcp.org/jsf/html" +> +<h:head> + <title>JSF 2.3: Websocket Sample</title> +</h:head> +<h:body> + <h1>JSF 2.3: Websocket and Ajax </h1> + <h:panelGroup id="messagePanel" layout="block"> + <ul> + <ui:repeat value="#{ajaxBean.messages}" var="m"> + <li>#{m}</li> + </ui:repeat> + </ul> + </h:panelGroup> + + <h:form id="form"> + <h:commandButton + id="pushToAjaxChannel" + action="#{ajaxBean.pushToAjaxChannel()}" + value="pushToAjaxChannel"> + <f:ajax/> + </h:commandButton> + <h:commandButton + id="pushToAjaxListenerChannel" + action="#{ajaxBean.pushToAjaxListenerChannel()}" + value="pushToAjaxListenerChannel"> + <f:ajax/> + </h:commandButton> + <h:commandButton + id="pushToCommandScriptChannel" + action="#{ajaxBean.pushToCommandScriptChannel()}" + value="pushToCommandScriptChannel"> + <f:ajax/> + </h:commandButton> + </h:form> + + <h:form> + <f:websocket channel="ajaxChannel" scope="view"> + <f:ajax event="ajaxEvent" render=":messagePanel"/> + </f:websocket> + </h:form> + + <h:form> + <f:websocket channel="ajaxListenerChannel" scope="view"> + <f:ajax event="ajaxListenerEvent" listener="#{ajaxBean.ajaxPushed}" render=":messagePanel"/> + </f:websocket> + </h:form> + + <f:websocket channel="commandScriptChannel" scope="view" onmessage="onCommandScript"/> + <h:form> + <h:commandScript name="onCommandScript" action="#{ajaxBean.commandScriptExecuted()}" render=":messagePanel"/> + </h:form> +</h:body> +</html> \ No newline at end of file diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/Business.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/Business.java index 97909c8..cc868cc 100644 --- a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/Business.java +++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/Business.java @@ -4,10 +4,15 @@ package uy.edu.fing.tse.central.business; import uy.edu.fing.tse.dto.CheckMechanism; import uy.edu.fing.tse.dto.Peripherical; +import javax.ejb.Asynchronous; + public interface Business { void altaPeriferico(Peripherical p); void altaVerificacionMecanismo(CheckMechanism cm); + + @Asynchronous + void test(); } diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/BusinessBean.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/BusinessBean.java index d150c47..60701e3 100644 --- a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/BusinessBean.java +++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/BusinessBean.java @@ -1,6 +1,9 @@ package uy.edu.fing.tse.central.business; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import uy.edu.fing.tse.central.business.common.Notifier; import uy.edu.fing.tse.central.db.DataAccessLocal; import uy.edu.fing.tse.dto.CheckMechanism; import uy.edu.fing.tse.dto.Peripherical; @@ -12,6 +15,8 @@ import javax.ejb.Stateless; @Stateless public class BusinessBean implements BusinessLocal, BusinessRemote { + private static final Logger LOG = LoggerFactory.getLogger(Business.class); + @EJB private DataAccessLocal dataAccess; @@ -29,4 +34,17 @@ public class BusinessBean implements BusinessLocal, BusinessRemote { public void altaVerificacionMecanismo(CheckMechanism cm) { } + + @Override + public void test() { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + + } + LOG.info("###++++++++++++++++++"); + Notifier.notify("test", "este es un mensaje del mas alla"); + } + + } diff --git a/central-ejb/src/main/java/uy/edu/fing/tse/central/business/common/Notifier.java b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/common/Notifier.java new file mode 100644 index 0000000..cd20972 --- /dev/null +++ b/central-ejb/src/main/java/uy/edu/fing/tse/central/business/common/Notifier.java @@ -0,0 +1,29 @@ +package uy.edu.fing.tse.central.business.common; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +public final class Notifier { + + public static Map<String, List<Consumer<String>>> actions = new HashMap<>(); + + private static List<Consumer<String>> getActionsByName(final String name) { + return actions.getOrDefault(name, new ArrayList<>()); + } + + public static void subscribe(final String name, final Consumer<String> c) { + final var actionsByName = getActionsByName(name); + actionsByName.add(c); + actions.put(name, actionsByName); + } + + public static void notify(final String name, final String msg) { + for (Consumer<String> callable : getActionsByName(name)) { + callable.accept(msg); + } + } + +} diff --git a/pom.xml b/pom.xml index 09df15d..f76fe53 100644 --- a/pom.xml +++ b/pom.xml @@ -198,6 +198,13 @@ <version>3.0.12.Final</version> </dependency> + <dependency> + <groupId>org.wildfly</groupId> + <artifactId>wildfly-jsf</artifactId> + <version>15.0.0.Final</version> + <scope>provided</scope> + </dependency> + <dependency> <groupId>org.jboss.spec.javax.faces</groupId> <artifactId>jboss-jsf-api_2.3_spec</artifactId> -- GitLab