diff --git a/pom.xml b/pom.xml index 4d07f379e..4c64e0911 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,9 @@ 2.3.3.RELEASE + + + 1.8 @@ -26,13 +29,22 @@ 2.2.4 1.8.0 + 8.32 0.8.5 + 4.13 + 1.0.0 + 1.18.12 + 3.1.1 + 2.3.8 0.0.4.RELEASE 0.0.25 + + + - + org.springframework.boot spring-boot-starter-actuator @@ -57,6 +69,10 @@ org.springframework.boot spring-boot-starter-thymeleaf + + org.springframework.boot + spring-boot-starter-websocket + org.springframework.boot spring-boot-starter-test @@ -69,15 +85,7 @@ - - - org.modelmapper - modelmapper - 2.3.8 - compile - - - + com.h2database h2 @@ -89,6 +97,15 @@ runtime + + + org.modelmapper + modelmapper + ${modelmapper.version} + compile + + + javax.cache @@ -100,6 +117,12 @@ + + org.webjars + webjars-locator + 0.40 + + org.webjars webjars-locator-core @@ -119,9 +142,35 @@ bootstrap ${webjars-bootstrap.version} + + org.webjars + stomp-websocket + 2.3.3-1 + + + + org.webjars + sockjs-client + 1.1.2 + + + - + + com.fasterxml.jackson.core + jackson-core + 2.10.2 + + + + com.fasterxml.jackson.core + jackson-databind + 2.10.2 + + + + org.junit.jupiter junit-jupiter-engine @@ -138,20 +187,23 @@ spring-boot-devtools true - - junit - junit - 4.13 - test - + + junit + junit + ${junit.version} + test + + org.projectlombok lombok - 1.18.12 - test + ${lombok.version} + + + @@ -170,12 +222,12 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.1.1 + ${maven-checkstyle-plugin.version} com.puppycrawl.tools checkstyle - 8.32 + ${checkstyle.version} io.spring.nohttp @@ -297,7 +349,7 @@ - + org.apache.maven.plugins maven-surefire-plugin @@ -349,6 +401,9 @@ + + + Apache License, Version 2.0 @@ -356,6 +411,9 @@ + + + spring-snapshots @@ -375,6 +433,9 @@ + + + spring-snapshots @@ -394,7 +455,11 @@ + + + + m2e @@ -410,7 +475,7 @@ org.eclipse.m2e lifecycle-mapping - 1.0.0 + ${lifecycle-mapping.version} @@ -450,5 +515,4 @@ - diff --git a/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java new file mode 100644 index 000000000..c7b1734cc --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketConfig.java @@ -0,0 +1,32 @@ +package org.springframework.samples.petclinic.configuration; + +import org.springframework.context.annotation.Configuration; + +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +/** + * Configuration class to enable WebSocket and STOMP messaging. + * + * @author Paul-Emmanuel DOS SANTOS FACAO + */ +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/websocket") + .withSockJS(); + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry config) { + config.setApplicationDestinationPrefixes("/app"); + config.enableSimpleBroker("/topic/"); + } + + +} diff --git a/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketSchedulerConfiguration.java b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketSchedulerConfiguration.java new file mode 100644 index 000000000..db13377f6 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/configuration/WebSocketSchedulerConfiguration.java @@ -0,0 +1,22 @@ +package org.springframework.samples.petclinic.configuration; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.samples.petclinic.model.common.WebSocketMessage; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; + +@Configuration +@EnableScheduling +public class WebSocketSchedulerConfiguration { + + @Autowired + SimpMessagingTemplate simpMessagingTemplate; + + @Scheduled(fixedDelay = 3000) + public void sendMessages() { + + simpMessagingTemplate.convertAndSend("/topic/user", new WebSocketMessage("Fixed Delay Scheduler")); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/controller/common/UserController.java b/src/main/java/org/springframework/samples/petclinic/controller/common/UserController.java new file mode 100644 index 000000000..fe16663c7 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/controller/common/UserController.java @@ -0,0 +1,19 @@ +package org.springframework.samples.petclinic.controller.common; + +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.samples.petclinic.model.common.User; +import org.springframework.samples.petclinic.model.common.WebSocketMessage; +import org.springframework.stereotype.Controller; + +@Controller +public class UserController { + + + @MessageMapping("/user") + @SendTo("/topic/user") + public WebSocketMessage getUser(User user) { + + return new WebSocketMessage("Hi " + user.getFirstName() + user.getLastName()); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketController.java b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketController.java new file mode 100644 index 000000000..5074205b7 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketController.java @@ -0,0 +1,26 @@ +package org.springframework.samples.petclinic.controller.common; + +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.messaging.simp.SimpMessageHeaderAccessor; +import org.springframework.samples.petclinic.model.common.WebSocketMessage; +import org.springframework.stereotype.Controller; + +@Controller +public class WebSocketController { + + @MessageMapping("/websocket.send") + @SendTo("/topic/public") + public WebSocketMessage sendMessage(@Payload final WebSocketMessage message) { + return message; + } + + @MessageMapping("/websocket.newUser") + @SendTo("/topic/public") + public WebSocketMessage newUser(@Payload final WebSocketMessage message, SimpMessageHeaderAccessor headerAccessor) { + headerAccessor.getSessionAttributes().put("usqername", message.getSender()); + return message; + } + +} diff --git a/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketEventListener.java b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketEventListener.java new file mode 100644 index 000000000..0ddfbc523 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/controller/common/WebSocketEventListener.java @@ -0,0 +1,33 @@ +package org.springframework.samples.petclinic.controller.common; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.event.EventListener; +import org.springframework.messaging.simp.SimpMessageSendingOperations; +import org.springframework.messaging.simp.stomp.StompHeaderAccessor; +import org.springframework.samples.petclinic.model.common.WebSocketMessage; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.messaging.SessionConnectedEvent; + +@Slf4j +@Component +public class WebSocketEventListener { + + @Autowired + private SimpMessageSendingOperations sendingOperations; + + @EventListener + public void handlewebSocketConnectListener(final SessionConnectedEvent event) { + log.info("Ding dong. We have a new connection!"); + } + + @EventListener + public void handlewebSocketDisconnectListener(final SessionConnectedEvent event) { + + final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage()); + + final String username = (String) headerAccessor.getSessionAttributes().get("username"); + + sendingOperations.convertAndSend("/topic/public", new WebSocketMessage("Hello" + username)); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/model/common/User.java b/src/main/java/org/springframework/samples/petclinic/model/common/User.java new file mode 100644 index 000000000..6cad7820e --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/model/common/User.java @@ -0,0 +1,10 @@ +package org.springframework.samples.petclinic.model.common; + +import org.springframework.samples.petclinic.model.Person; + +public class User extends Person { + + public User() { + super(); + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessage.java b/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessage.java new file mode 100644 index 000000000..916cf3df6 --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessage.java @@ -0,0 +1,43 @@ +package org.springframework.samples.petclinic.model.common; + + +import java.time.LocalDate; + +public class WebSocketMessage { + + private String sender; + + private String time; + + private String content; + + + public WebSocketMessage(String content) { + this.time = LocalDate.now().toString(); + this.content = content; + } + + public String getSender() { + return sender; + } + + public void setSender(String sender) { + this.sender = sender; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } +} diff --git a/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessageType.java b/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessageType.java new file mode 100644 index 000000000..52d946eaf --- /dev/null +++ b/src/main/java/org/springframework/samples/petclinic/model/common/WebSocketMessageType.java @@ -0,0 +1,7 @@ +package org.springframework.samples.petclinic.model.common; + +public enum WebSocketMessageType { + MESSAGE, + CONNECT, + DISCONNECT +}