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.messaging.MessageChannel; 020import org.springframework.messaging.SubscribableChannel; 021import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler; 022import org.springframework.messaging.tcp.TcpOperations; 023import org.springframework.messaging.tcp.reactor.Reactor2TcpClient; 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 private Long systemHeartbeatSendInterval; 047 048 private Long systemHeartbeatReceiveInterval; 049 050 private String virtualHost; 051 052 private TcpOperations<byte[]> tcpClient; 053 054 private boolean autoStartup = true; 055 056 private String userDestinationBroadcast; 057 058 private String userRegistryBroadcast; 059 060 061 public StompBrokerRelayRegistration(SubscribableChannel clientInboundChannel, 062 MessageChannel clientOutboundChannel, String[] destinationPrefixes) { 063 064 super(clientInboundChannel, clientOutboundChannel, destinationPrefixes); 065 } 066 067 068 /** 069 * Set the STOMP message broker host. 070 */ 071 public StompBrokerRelayRegistration setRelayHost(String relayHost) { 072 Assert.hasText(relayHost, "relayHost must not be empty"); 073 this.relayHost = relayHost; 074 return this; 075 } 076 077 /** 078 * Set the STOMP message broker port. 079 */ 080 public StompBrokerRelayRegistration setRelayPort(int relayPort) { 081 this.relayPort = relayPort; 082 return this; 083 } 084 085 /** 086 * Set the login to use when creating connections to the STOMP broker on 087 * behalf of connected clients. 088 * <p>By default this is set to "guest". 089 */ 090 public StompBrokerRelayRegistration setClientLogin(String login) { 091 Assert.hasText(login, "clientLogin must not be empty"); 092 this.clientLogin = login; 093 return this; 094 } 095 096 /** 097 * Set the passcode to use when creating connections to the STOMP broker on 098 * behalf of connected clients. 099 * <p>By default this is set to "guest". 100 */ 101 public StompBrokerRelayRegistration setClientPasscode(String passcode) { 102 Assert.hasText(passcode, "clientPasscode must not be empty"); 103 this.clientPasscode = passcode; 104 return this; 105 } 106 107 /** 108 * Set the login for the shared "system" connection used to send messages to 109 * the STOMP broker from within the application, i.e. messages not associated 110 * with a specific client session (e.g. REST/HTTP request handling method). 111 * <p>By default this is set to "guest". 112 */ 113 public StompBrokerRelayRegistration setSystemLogin(String login) { 114 Assert.hasText(login, "systemLogin must not be empty"); 115 this.systemLogin = login; 116 return this; 117 } 118 119 /** 120 * Set the passcode for the shared "system" connection used to send messages to 121 * the STOMP broker from within the application, i.e. messages not associated 122 * with a specific client session (e.g. REST/HTTP request handling method). 123 * <p>By default this is set to "guest". 124 */ 125 public StompBrokerRelayRegistration setSystemPasscode(String passcode) { 126 Assert.hasText(passcode, "systemPasscode must not be empty"); 127 this.systemPasscode = passcode; 128 return this; 129 } 130 131 /** 132 * Set the interval, in milliseconds, at which the "system" relay session will, 133 * in the absence of any other data being sent, send a heartbeat to the STOMP broker. 134 * A value of zero will prevent heartbeats from being sent to the broker. 135 * <p>The default value is 10000. 136 */ 137 public StompBrokerRelayRegistration setSystemHeartbeatSendInterval(long systemHeartbeatSendInterval) { 138 this.systemHeartbeatSendInterval = systemHeartbeatSendInterval; 139 return this; 140 } 141 142 /** 143 * Set the maximum interval, in milliseconds, at which the "system" relay session 144 * expects, in the absence of any other data, to receive a heartbeat from the STOMP 145 * broker. A value of zero will configure the relay session to expect not to receive 146 * heartbeats from the broker. 147 * <p>The default value is 10000. 148 */ 149 public StompBrokerRelayRegistration setSystemHeartbeatReceiveInterval(long heartbeatReceiveInterval) { 150 this.systemHeartbeatReceiveInterval = heartbeatReceiveInterval; 151 return this; 152 } 153 154 /** 155 * Set the value of the "host" header to use in STOMP CONNECT frames. When this 156 * property is configured, a "host" header will be added to every STOMP frame sent to 157 * the STOMP broker. This may be useful for example in a cloud environment where the 158 * actual host to which the TCP connection is established is different from the host 159 * providing the cloud-based STOMP service. 160 * <p>By default this property is not set. 161 */ 162 public StompBrokerRelayRegistration setVirtualHost(String virtualHost) { 163 this.virtualHost = virtualHost; 164 return this; 165 } 166 167 /** 168 * Configure a TCP client for managing TCP connections to the STOMP broker. 169 * By default {@link Reactor2TcpClient} is used. 170 * <p><strong>Note:</strong> when this property is used, any 171 * {@link #setRelayHost(String) host} or {@link #setRelayPort(int) port} 172 * specified are effectively ignored. 173 * @since 4.3.15 174 */ 175 public void setTcpClient(TcpOperations<byte[]> tcpClient) { 176 this.tcpClient = tcpClient; 177 } 178 179 /** 180 * Configure whether the {@link StompBrokerRelayMessageHandler} should start 181 * automatically when the Spring ApplicationContext is refreshed. 182 * <p>The default setting is {@code true}. 183 */ 184 public StompBrokerRelayRegistration setAutoStartup(boolean autoStartup) { 185 this.autoStartup = autoStartup; 186 return this; 187 } 188 189 /** 190 * Set a destination to broadcast messages to user destinations that remain 191 * unresolved because the user appears not to be connected. In a 192 * multi-application server scenario this gives other application servers 193 * a chance to try. 194 * <p>By default this is not set. 195 * @param destination the destination to broadcast unresolved messages to, 196 * e.g. "/topic/unresolved-user-destination" 197 */ 198 public StompBrokerRelayRegistration setUserDestinationBroadcast(String destination) { 199 this.userDestinationBroadcast = destination; 200 return this; 201 } 202 203 protected String getUserDestinationBroadcast() { 204 return this.userDestinationBroadcast; 205 } 206 207 /** 208 * Set a destination to broadcast the content of the local user registry to 209 * and to listen for such broadcasts from other servers. In a multi-application 210 * server scenarios this allows each server's user registry to be aware of 211 * users connected to other servers. 212 * <p>By default this is not set. 213 * @param destination the destination for broadcasting user registry details, 214 * e.g. "/topic/simp-user-registry". 215 */ 216 public StompBrokerRelayRegistration setUserRegistryBroadcast(String destination) { 217 this.userRegistryBroadcast = destination; 218 return this; 219 } 220 221 protected String getUserRegistryBroadcast() { 222 return this.userRegistryBroadcast; 223 } 224 225 226 @Override 227 protected StompBrokerRelayMessageHandler getMessageHandler(SubscribableChannel brokerChannel) { 228 StompBrokerRelayMessageHandler handler = new StompBrokerRelayMessageHandler( 229 getClientInboundChannel(), getClientOutboundChannel(), 230 brokerChannel, getDestinationPrefixes()); 231 232 handler.setRelayHost(this.relayHost); 233 handler.setRelayPort(this.relayPort); 234 235 handler.setClientLogin(this.clientLogin); 236 handler.setClientPasscode(this.clientPasscode); 237 238 handler.setSystemLogin(this.systemLogin); 239 handler.setSystemPasscode(this.systemPasscode); 240 241 if (this.systemHeartbeatSendInterval != null) { 242 handler.setSystemHeartbeatSendInterval(this.systemHeartbeatSendInterval); 243 } 244 if (this.systemHeartbeatReceiveInterval != null) { 245 handler.setSystemHeartbeatReceiveInterval(this.systemHeartbeatReceiveInterval); 246 } 247 if (this.virtualHost != null) { 248 handler.setVirtualHost(this.virtualHost); 249 } 250 if (this.tcpClient != null) { 251 handler.setTcpClient(this.tcpClient); 252 } 253 254 handler.setAutoStartup(this.autoStartup); 255 256 return handler; 257 } 258 259}