001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.messaging.simp.config; 018 019import org.springframework.lang.Nullable; 020import org.springframework.messaging.MessageChannel; 021import org.springframework.messaging.SubscribableChannel; 022import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler; 023import org.springframework.messaging.tcp.TcpOperations; 024import org.springframework.util.Assert; 025 026/** 027 * Registration class for configuring a {@link StompBrokerRelayMessageHandler}. 028 * 029 * @author Rossen Stoyanchev 030 * @since 4.0 031 */ 032public class StompBrokerRelayRegistration extends AbstractBrokerRegistration { 033 034 private String relayHost = "127.0.0.1"; 035 036 private int relayPort = 61613; 037 038 private String clientLogin = "guest"; 039 040 private String clientPasscode = "guest"; 041 042 private String systemLogin = "guest"; 043 044 private String systemPasscode = "guest"; 045 046 @Nullable 047 private Long systemHeartbeatSendInterval; 048 049 @Nullable 050 private Long systemHeartbeatReceiveInterval; 051 052 @Nullable 053 private String virtualHost; 054 055 @Nullable 056 private TcpOperations<byte[]> tcpClient; 057 058 private boolean autoStartup = true; 059 060 @Nullable 061 private String userDestinationBroadcast; 062 063 @Nullable 064 private String userRegistryBroadcast; 065 066 067 public StompBrokerRelayRegistration(SubscribableChannel clientInboundChannel, 068 MessageChannel clientOutboundChannel, String[] destinationPrefixes) { 069 070 super(clientInboundChannel, clientOutboundChannel, destinationPrefixes); 071 } 072 073 074 /** 075 * Set the STOMP message broker host. 076 */ 077 public StompBrokerRelayRegistration setRelayHost(String relayHost) { 078 Assert.hasText(relayHost, "relayHost must not be empty"); 079 this.relayHost = relayHost; 080 return this; 081 } 082 083 /** 084 * Set the STOMP message broker port. 085 */ 086 public StompBrokerRelayRegistration setRelayPort(int relayPort) { 087 this.relayPort = relayPort; 088 return this; 089 } 090 091 /** 092 * Set the login to use when creating connections to the STOMP broker on 093 * behalf of connected clients. 094 * <p>By default this is set to "guest". 095 */ 096 public StompBrokerRelayRegistration setClientLogin(String login) { 097 Assert.hasText(login, "clientLogin must not be empty"); 098 this.clientLogin = login; 099 return this; 100 } 101 102 /** 103 * Set the passcode to use when creating connections to the STOMP broker on 104 * behalf of connected clients. 105 * <p>By default this is set to "guest". 106 */ 107 public StompBrokerRelayRegistration setClientPasscode(String passcode) { 108 Assert.hasText(passcode, "clientPasscode must not be empty"); 109 this.clientPasscode = passcode; 110 return this; 111 } 112 113 /** 114 * Set the login for the shared "system" connection used to send messages to 115 * the STOMP broker from within the application, i.e. messages not associated 116 * with a specific client session (e.g. REST/HTTP request handling method). 117 * <p>By default this is set to "guest". 118 */ 119 public StompBrokerRelayRegistration setSystemLogin(String login) { 120 Assert.hasText(login, "systemLogin must not be empty"); 121 this.systemLogin = login; 122 return this; 123 } 124 125 /** 126 * Set the passcode for the shared "system" connection used to send messages to 127 * the STOMP broker from within the application, i.e. messages not associated 128 * with a specific client session (e.g. REST/HTTP request handling method). 129 * <p>By default this is set to "guest". 130 */ 131 public StompBrokerRelayRegistration setSystemPasscode(String passcode) { 132 Assert.hasText(passcode, "systemPasscode must not be empty"); 133 this.systemPasscode = passcode; 134 return this; 135 } 136 137 /** 138 * Set the interval, in milliseconds, at which the "system" relay session will, 139 * in the absence of any other data being sent, send a heartbeat to the STOMP broker. 140 * A value of zero will prevent heartbeats from being sent to the broker. 141 * <p>The default value is 10000. 142 */ 143 public StompBrokerRelayRegistration setSystemHeartbeatSendInterval(long systemHeartbeatSendInterval) { 144 this.systemHeartbeatSendInterval = systemHeartbeatSendInterval; 145 return this; 146 } 147 148 /** 149 * Set the maximum interval, in milliseconds, at which the "system" relay session 150 * expects, in the absence of any other data, to receive a heartbeat from the STOMP 151 * broker. A value of zero will configure the relay session to expect not to receive 152 * heartbeats from the broker. 153 * <p>The default value is 10000. 154 */ 155 public StompBrokerRelayRegistration setSystemHeartbeatReceiveInterval(long heartbeatReceiveInterval) { 156 this.systemHeartbeatReceiveInterval = heartbeatReceiveInterval; 157 return this; 158 } 159 160 /** 161 * Set the value of the "host" header to use in STOMP CONNECT frames. When this 162 * property is configured, a "host" header will be added to every STOMP frame sent to 163 * the STOMP broker. This may be useful for example in a cloud environment where the 164 * actual host to which the TCP connection is established is different from the host 165 * providing the cloud-based STOMP service. 166 * <p>By default this property is not set. 167 */ 168 public StompBrokerRelayRegistration setVirtualHost(String virtualHost) { 169 this.virtualHost = virtualHost; 170 return this; 171 } 172 173 /** 174 * Configure a TCP client for managing TCP connections to the STOMP broker. 175 * <p>By default {@code ReactorNettyTcpClient} is used. 176 * <p><strong>Note:</strong> when this property is used, any 177 * {@link #setRelayHost(String) host} or {@link #setRelayPort(int) port} 178 * specified are effectively ignored. 179 * @since 4.3.15 180 */ 181 public void setTcpClient(TcpOperations<byte[]> tcpClient) { 182 this.tcpClient = tcpClient; 183 } 184 185 /** 186 * Configure whether the {@link StompBrokerRelayMessageHandler} should start 187 * automatically when the Spring ApplicationContext is refreshed. 188 * <p>The default setting is {@code true}. 189 */ 190 public StompBrokerRelayRegistration setAutoStartup(boolean autoStartup) { 191 this.autoStartup = autoStartup; 192 return this; 193 } 194 195 /** 196 * Set a destination to broadcast messages to user destinations that remain 197 * unresolved because the user appears not to be connected. In a 198 * multi-application server scenario this gives other application servers 199 * a chance to try. 200 * <p>By default this is not set. 201 * @param destination the destination to broadcast unresolved messages to, 202 * e.g. "/topic/unresolved-user-destination" 203 */ 204 public StompBrokerRelayRegistration setUserDestinationBroadcast(String destination) { 205 this.userDestinationBroadcast = destination; 206 return this; 207 } 208 209 @Nullable 210 protected String getUserDestinationBroadcast() { 211 return this.userDestinationBroadcast; 212 } 213 214 /** 215 * Set a destination to broadcast the content of the local user registry to 216 * and to listen for such broadcasts from other servers. In a multi-application 217 * server scenarios this allows each server's user registry to be aware of 218 * users connected to other servers. 219 * <p>By default this is not set. 220 * @param destination the destination for broadcasting user registry details, 221 * e.g. "/topic/simp-user-registry". 222 */ 223 public StompBrokerRelayRegistration setUserRegistryBroadcast(String destination) { 224 this.userRegistryBroadcast = destination; 225 return this; 226 } 227 228 @Nullable 229 protected String getUserRegistryBroadcast() { 230 return this.userRegistryBroadcast; 231 } 232 233 234 @Override 235 protected StompBrokerRelayMessageHandler getMessageHandler(SubscribableChannel brokerChannel) { 236 StompBrokerRelayMessageHandler handler = new StompBrokerRelayMessageHandler( 237 getClientInboundChannel(), getClientOutboundChannel(), 238 brokerChannel, getDestinationPrefixes()); 239 240 handler.setRelayHost(this.relayHost); 241 handler.setRelayPort(this.relayPort); 242 243 handler.setClientLogin(this.clientLogin); 244 handler.setClientPasscode(this.clientPasscode); 245 246 handler.setSystemLogin(this.systemLogin); 247 handler.setSystemPasscode(this.systemPasscode); 248 249 if (this.systemHeartbeatSendInterval != null) { 250 handler.setSystemHeartbeatSendInterval(this.systemHeartbeatSendInterval); 251 } 252 if (this.systemHeartbeatReceiveInterval != null) { 253 handler.setSystemHeartbeatReceiveInterval(this.systemHeartbeatReceiveInterval); 254 } 255 if (this.virtualHost != null) { 256 handler.setVirtualHost(this.virtualHost); 257 } 258 if (this.tcpClient != null) { 259 handler.setTcpClient(this.tcpClient); 260 } 261 262 handler.setAutoStartup(this.autoStartup); 263 264 return handler; 265 } 266 267}