package de.rwth.idsg.steve.config; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.AnnotationIntrospector; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; import de.rwth.idsg.steve.ocpp.OcppVersion; import de.rwth.idsg.steve.ocpp.ws.OcppWebSocketUpgrader; import de.rwth.idsg.steve.ocpp.ws.ocpp12.Ocpp12JacksonModule; import de.rwth.idsg.steve.ocpp.ws.ocpp12.Ocpp12WebSocketEndpoint; import de.rwth.idsg.steve.ocpp.ws.ocpp15.Ocpp15JacksonModule; import de.rwth.idsg.steve.ocpp.ws.ocpp15.Ocpp15WebSocketEndpoint; import de.rwth.idsg.steve.repository.ChargePointRepository; import lombok.extern.slf4j.Slf4j; import org.eclipse.jetty.websocket.api.WebSocketBehavior; import org.eclipse.jetty.websocket.api.WebSocketPolicy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.ServletWebSocketHandlerRegistry; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; import org.springframework.web.socket.server.support.DefaultHandshakeHandler; import java.util.concurrent.TimeUnit; /** * @author Sevket Goekay <goekay@dbis.rwth-aachen.de> * @since 11.03.2015 */ @EnableWebSocket @Configuration @Slf4j public class WebSocketConfiguration implements WebSocketConfigurer { @Autowired private Ocpp12WebSocketEndpoint ocpp12WebSocketEndpoint; @Autowired private Ocpp15WebSocketEndpoint ocpp15WebSocketEndpoint; @Autowired private ChargePointRepository chargePointRepository; public static final long IDLE_TIMEOUT = TimeUnit.HOURS.toMillis(2); public static final long PING_INTERVAL = TimeUnit.MINUTES.toMinutes(15); private static final int MAX_MSG_SIZE = 8_388_608; // 8 MB for max message size // The order affects the choice private static final String[] PROTOCOLS = { OcppVersion.V_15.getValue(), OcppVersion.V_12.getValue() }; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { WebSocketPolicy policy = new WebSocketPolicy(WebSocketBehavior.SERVER); policy.setMaxTextMessageBufferSize(MAX_MSG_SIZE); policy.setMaxTextMessageSize(MAX_MSG_SIZE); policy.setIdleTimeout(IDLE_TIMEOUT); OcppWebSocketUpgrader upgradeStrategy = new OcppWebSocketUpgrader( policy, ocpp12WebSocketEndpoint, ocpp15WebSocketEndpoint, chargePointRepository); DefaultHandshakeHandler handler = new DefaultHandshakeHandler(upgradeStrategy); handler.setSupportedProtocols(PROTOCOLS); registry.addHandler(ocpp12WebSocketEndpoint, "/websocket/CentralSystemService/*") .addHandler(ocpp15WebSocketEndpoint, "/websocket/CentralSystemService/*") .setHandshakeHandler(handler) .setAllowedOrigins("*"); } @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); mapper.registerModule(new Ocpp12JacksonModule()); mapper.registerModule(new Ocpp15JacksonModule()); mapper.setAnnotationIntrospector( AnnotationIntrospector.pair( new JacksonAnnotationIntrospector(), new JaxbAnnotationIntrospector(mapper.getTypeFactory()) ) ); return mapper; } // ------------------------------------------------------------------------- // We don't need no SockJS fallback. But, nevertheless, Spring initializes // a scheduler for it, to be used in the implementation // AbstractWebSocketHandlerRegistration.withSockJS(). We don't call // WebSocketHandlerRegistry.withSockJS() above to add SockJS support, // so the scheduler is useless. // // Hereby, we override the default beans provided by // org.springframework.web.socket.config.annotation.WebSocketConfigurationSupport // ------------------------------------------------------------------------- @Bean public HandlerMapping webSocketHandlerMapping() { ServletWebSocketHandlerRegistry registry = new ServletWebSocketHandlerRegistry(null); registerWebSocketHandlers(registry); return registry.getHandlerMapping(); } @Bean public ThreadPoolTaskScheduler defaultSockJsTaskScheduler() { return null; } }