diff --git a/backoffice/pom.xml b/backoffice/pom.xml index f4bf4d24f7ce2be95f870de7819c9fbae8b8abc9..5174f39b70849e5aadd7c288726bde7c13917774 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 0000000000000000000000000000000000000000..da97badf2ccec58a7d30e0629b2877cd0ffa310d --- /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 ad64d9f6a3c3f67c30b75dd717fe9a06eb274f1e..55aee8de5398766556c226e1cd634d4359dbe604 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 76426bcac566205e6c414979c639bf1cd7f29d2d..e71e48076738661e3438a50513325165005c82df 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 6a23d21bf333d6df990fd28376d4796e9c8829ab..0f091e85ed540dddf7a2466706758107e35f5b6a 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 891e0f2315abf4fb902d2f758246a4c75b616c0d..17e6bd92c45ac5d289376c219ccacc1cc4db7cd4 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 5856e5468ec84d61e04e84caead8d65127ac0632..08b9fd6596987ecfb506667ed31ea04dea6fa4de 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 0000000000000000000000000000000000000000..940a5dbb45ecba27dc8afdec418b74e7239bcc66 --- /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 97909c83f2c8aa24df8a99eb162c5edd1a9f1da7..cc868ccffd10753e93a8a6577d789a5c6470eb08 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 d150c47df83e2977b05e935d602c7f2915cf646f..60701e38d83bbb8f3b4c00101b396d4344a7baa3 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 0000000000000000000000000000000000000000..cd20972e521d8fb237e845c64085d1994cb63ab6 --- /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 09df15dd09f24ce4260610d70767ccf154762587..f76fe538d15a3892afb03507684b0cddd453fe3e 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>