Class | MCollective::Connector::Stomp |
In: |
spec/unit/util_spec.rb
plugins/mcollective/connector/stomp.rb |
Parent: | MCollective::Connector::Base |
Handles sending and receiving messages over the Stomp protocol
This plugin supports version 1.1 or 1.1.6 and newer of the Stomp rubygem the versions between those had multi threading issues.
For all versions you can configure it as follows:
connector = stomp plugin.stomp.host = stomp.your.net plugin.stomp.port = 6163 plugin.stomp.user = you plugin.stomp.password = secret
All of these can be overriden per user using environment variables:
STOMP_SERVER, STOMP_PORT, STOMP_USER, STOMP_PASSWORD
Version 1.1.6 onward support supplying multiple connections and it will do failover between these servers, you can configure it as follows:
connector = stomp plugin.stomp.pool.size = 2 plugin.stomp.pool.host1 = stomp1.your.net plugin.stomp.pool.port1 = 6163 plugin.stomp.pool.user1 = you plugin.stomp.pool.password1 = secret plugin.stomp.pool.ssl1 = true plugin.stomp.pool.host2 = stomp2.your.net plugin.stomp.pool.port2 = 6163 plugin.stomp.pool.user2 = you plugin.stomp.pool.password2 = secret plugin.stomp.pool.ssl2 = false
Using this method you can supply just STOMP_USER and STOMP_PASSWORD you have to supply the hostname for each pool member in the config. The port will default to 6163 if not specified.
In addition you can set the following options but only when using pooled configuration:
plugin.stomp.pool.initial_reconnect_delay = 0.01 plugin.stomp.pool.max_reconnect_delay = 30.0 plugin.stomp.pool.use_exponential_back_off = true plugin.stomp.pool.back_off_multiplier = 2 plugin.stomp.pool.max_reconnect_attempts = 0 plugin.stomp.pool.randomize = false plugin.stomp.pool.timeout = -1
For versions of ActiveMQ that supports message priorities you can set a priority, this will cause a "priority" header to be emitted if present:
plugin.stomp.priority = 4
connection | [R] |
# File plugins/mcollective/connector/stomp.rb, line 64 64: def initialize 65: @config = Config.instance 66: @subscriptions = [] 67: end
Connects to the Stomp middleware
# File plugins/mcollective/connector/stomp.rb, line 70 70: def connect(connector = ::Stomp::Connection) 71: if @connection 72: Log.debug("Already connection, not re-initializing connection") 73: return 74: end 75: 76: begin 77: host = nil 78: port = nil 79: user = nil 80: password = nil 81: @base64 = get_bool_option("stomp.base64", false) 82: @msgpriority = get_option("stomp.priority", 0).to_i 83: 84: # Maintain backward compat for older stomps 85: unless @config.pluginconf.include?("stomp.pool.size") 86: host = get_env_or_option("STOMP_SERVER", "stomp.host") 87: port = get_env_or_option("STOMP_PORT", "stomp.port", 6163).to_i 88: user = get_env_or_option("STOMP_USER", "stomp.user") 89: password = get_env_or_option("STOMP_PASSWORD", "stomp.password") 90: 91: Log.debug("Connecting to #{host}:#{port}") 92: @connection = connector.new(user, password, host, port, true) 93: else 94: pools = @config.pluginconf["stomp.pool.size"].to_i 95: hosts = [] 96: 97: 1.upto(pools) do |poolnum| 98: host = {} 99: 100: host[:host] = get_option("stomp.pool.host#{poolnum}") 101: host[:port] = get_option("stomp.pool.port#{poolnum}", 6163).to_i 102: host[:login] = get_env_or_option("STOMP_USER", "stomp.pool.user#{poolnum}") 103: host[:passcode] = get_env_or_option("STOMP_PASSWORD", "stomp.pool.password#{poolnum}") 104: host[:ssl] = get_bool_option("stomp.pool.ssl#{poolnum}", false) 105: 106: Log.debug("Adding #{host[:host]}:#{host[:port]} to the connection pool") 107: hosts << host 108: end 109: 110: raise "No hosts found for the STOMP connection pool" if hosts.size == 0 111: 112: connection = {:hosts => hosts} 113: 114: # Various STOMP gem options, defaults here matches defaults for 1.1.6 the meaning of 115: # these can be guessed, the documentation isn't clear 116: connection[:initial_reconnect_delay] = get_option("stomp.pool.initial_reconnect_delay", 0.01).to_f 117: connection[:max_reconnect_delay] = get_option("stomp.pool.max_reconnect_delay", 30.0).to_f 118: connection[:use_exponential_back_off] = get_bool_option("stomp.pool.use_exponential_back_off", true) 119: connection[:back_off_multiplier] = get_bool_option("stomp.pool.back_off_multiplier", 2).to_i 120: connection[:max_reconnect_attempts] = get_option("stomp.pool.max_reconnect_attempts", 0).to_i 121: connection[:randomize] = get_bool_option("stomp.pool.randomize", false) 122: connection[:backup] = get_bool_option("stomp.pool.backup", false) 123: connection[:timeout] = get_option("stomp.pool.timeout", -1).to_i 124: 125: @connection = connector.new(connection) 126: end 127: rescue Exception => e 128: raise("Could not connect to Stomp Server: #{e}") 129: end 130: end
gets a boolean option from the config, supports y/n/true/false/1/0
# File plugins/mcollective/connector/stomp.rb, line 217 217: def get_bool_option(opt, default) 218: return default unless @config.pluginconf.include?(opt) 219: 220: val = @config.pluginconf[opt] 221: 222: if val =~ /^1|yes|true/ 223: return true 224: elsif val =~ /^0|no|false/ 225: return false 226: else 227: return default 228: end 229: end
looks in the environment first then in the config file for a specific option, accepts an optional default.
raises an exception when it cant find a value anywhere
# File plugins/mcollective/connector/stomp.rb, line 198 198: def get_env_or_option(env, opt, default=nil) 199: return ENV[env] if ENV.include?(env) 200: return @config.pluginconf[opt] if @config.pluginconf.include?(opt) 201: return default if default 202: 203: raise("No #{env} environment or plugin.#{opt} configuration option given") 204: end
looks for a config option, accepts an optional default
raises an exception when it cant find a value anywhere
# File plugins/mcollective/connector/stomp.rb, line 209 209: def get_option(opt, default=nil) 210: return @config.pluginconf[opt] if @config.pluginconf.include?(opt) 211: return default if default 212: 213: raise("No plugin.#{opt} configuration option given") 214: end
# File plugins/mcollective/connector/stomp.rb, line 231 231: def make_target(agent, type, collective) 232: raise("Unknown target type #{type}") unless [:broadcast, :directed, :reply].include?(type) 233: raise("Unknown collective '#{collective}' known collectives are '#{@config.collectives.join ', '}'") unless @config.collectives.include?(collective) 234: 235: type = :command unless type == :reply 236: 237: ["#{@config.topicprefix}#{collective}", agent, type].join(@config.topicsep) 238: end
# File plugins/mcollective/connector/stomp.rb, line 187 187: def msgheaders 188: headers = {} 189: headers = {"priority" => @msgpriority} if @msgpriority > 0 190: 191: return headers 192: end
Sends a message to the Stomp connection
# File plugins/mcollective/connector/stomp.rb, line 148 148: def publish(target, msg) 149: Log.debug("Sending a message to Stomp target '#{target}'") 150: 151: msg = SSL.base64_encode(msg) if @base64 152: 153: # deal with deprecation warnings in newer stomp gems 154: if @connection.respond_to?("publish") 155: @connection.publish(target, msg, msgheaders) 156: else 157: @connection.send(target, msg, msgheaders) 158: end 159: end
Receives a message from the Stomp connection
# File plugins/mcollective/connector/stomp.rb, line 133 133: def receive 134: Log.debug("Waiting for a message from Stomp") 135: msg = @connection.receive 136: 137: # STOMP puts the payload in the body variable, pass that 138: # into the payload of MCollective::Request and discard all the 139: # other headers etc that stomp provides 140: if @base64 141: Request.new(SSL.base64_decode(msg.body)) 142: else 143: Request.new(msg.body) 144: end 145: end
Subscribe to a topic or queue
# File plugins/mcollective/connector/stomp.rb, line 162 162: def subscribe(agent, type, collective) 163: source = make_target(agent, type, collective) 164: 165: unless @subscriptions.include?(source) 166: Log.debug("Subscribing to #{source}") 167: @connection.subscribe(source) 168: @subscriptions << source 169: end 170: end
Subscribe to a topic or queue
# File plugins/mcollective/connector/stomp.rb, line 173 173: def unsubscribe(agent, type, collective) 174: source = make_target(agent, type, collective) 175: 176: Log.debug("Unsubscribing from #{source}") 177: @connection.unsubscribe(source) 178: @subscriptions.delete(source) 179: end