stomp_message 0.0.3 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +7 -1
- data/Manifest.txt +4 -0
- data/README.txt +26 -1
- data/bin/stomp_message_send.rb +69 -17
- data/config/hoe.rb +4 -4
- data/lib/stomp_message/message.rb +84 -16
- data/lib/stomp_message/stomp_participant.rb +102 -0
- data/lib/stomp_message/stomp_send_topic.rb +173 -0
- data/lib/stomp_message/stomp_server.rb +176 -0
- data/lib/stomp_message/stomp_statistics_server.rb +83 -0
- data/lib/stomp_message/version.rb +2 -2
- data/test/test_stomp_message.rb +193 -3
- metadata +12 -8
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
@@ -7,6 +7,10 @@ config/hoe.rb
|
|
7
7
|
config/requirements.rb
|
8
8
|
lib/stomp_message.rb
|
9
9
|
lib/stomp_message/version.rb
|
10
|
+
lib/stomp_message/stomp_server.rb
|
11
|
+
lib/stomp_message/stomp_statistics_server.rb
|
12
|
+
lib/stomp_message/stomp_send_topic.rb
|
13
|
+
lib/stomp_message/stomp_participant.rb
|
10
14
|
lib/stomp_message/message.rb
|
11
15
|
log/debug.log
|
12
16
|
bin/stomp_message_send.rb
|
data/README.txt
CHANGED
@@ -1 +1,26 @@
|
|
1
|
-
|
1
|
+
A basic package for sending and receiving stomp messages
|
2
|
+
|
3
|
+
|
4
|
+
A server class will listen to topics (StompMessage::StompServer)
|
5
|
+
|
6
|
+
|
7
|
+
A class to easily send (and receive messages from the server). Since the messsage protocol is semi one way to receive a message you reply to a distinct topic and a call back is executed.
|
8
|
+
|
9
|
+
The code below creates server class and sends message/gets response.
|
10
|
+
|
11
|
+
IMPORTANT apachemq or some other messaging platform must be running :)
|
12
|
+
|
13
|
+
args={:topic => '/topic/test'}
|
14
|
+
ss=StompMessage::StompStatisticsServer.new(args)
|
15
|
+
ss_thread = Thread.new {
|
16
|
+
ss.run }
|
17
|
+
|
18
|
+
msg=StompMessage::Message.new('stomp_REPORT', "body")
|
19
|
+
|
20
|
+
puts "creating send topic"
|
21
|
+
send_topic=StompMessage::StompSendTopic.new(args)
|
22
|
+
send_topic.send_topic_acknowledge(msg,{ :msisdn => "639999"}) { |m|
|
23
|
+
puts "#{m.to_s}"
|
24
|
+
msg=StompMessage::Message.load_xml(m)
|
25
|
+
assert msg.command== 'stomp_REPLY', "command wrong"
|
26
|
+
}
|
data/bin/stomp_message_send.rb
CHANGED
@@ -8,6 +8,12 @@ require 'stomp_message'
|
|
8
8
|
def usage
|
9
9
|
puts "Usage: stomp_message_send.rb -t topic -m command -b body -h host -p port "
|
10
10
|
puts "to turn on debug: stomp_message_send.rb -t '/topic/sms' -m stomp_DEBUG -b nil"
|
11
|
+
puts "for statistics report: stomp_message_send.rb -t '/topic/sms' -m stomp_REPORT -b nil -a true"
|
12
|
+
puts "for statistics report: stomp_message_send.rb -t '/topic/sms' -m stomp_REPORT -b nil -a true"
|
13
|
+
puts "for ping test: stomp_message_send.rb -t '/topic/sms' -m stomp_PING -b nil -a true"
|
14
|
+
puts "for email ping test: stomp_message_send.rb -t '/topic/sms' -m stomp_PING -b nil -a true -d comma_separated_email_addresses"
|
15
|
+
puts "-a flag for response"
|
16
|
+
|
11
17
|
exit
|
12
18
|
end
|
13
19
|
def parse_options(params)
|
@@ -17,23 +23,35 @@ def parse_options(params)
|
|
17
23
|
#puts "paramsp is #{paramsp}"
|
18
24
|
topic_flag=command_flag=body_flag=true
|
19
25
|
temp_hash = {}
|
26
|
+
temp_hash[:ack]= 'false' # no ack by default
|
27
|
+
temp_hash[:msisdn] = 'not_defined'
|
28
|
+
email_flag=false
|
20
29
|
opts.on("-h","--host VAL", String) {|val| temp_hash[:host ] = val
|
21
|
-
|
30
|
+
# puts "host is #{val}"
|
22
31
|
}
|
32
|
+
opts.on("-d","--email VAL", String) {|val| temp_hash[:email ] = val
|
33
|
+
puts "email address is #{val}"
|
34
|
+
# puts "host is #{val}"
|
35
|
+
}
|
36
|
+
|
23
37
|
opts.on("-p","--port VAL", String) {|val| temp_hash[:port ] = val
|
24
|
-
|
38
|
+
# puts "port is #{val}"
|
25
39
|
}
|
40
|
+
opts.on("-a","--ack VAL", String) {|val| temp_hash[:ack ] = val
|
41
|
+
puts "ack is #{val}"
|
42
|
+
}
|
43
|
+
|
26
44
|
opts.on("-u","--user VAL", String) {|val| temp_hash[:user ] = val
|
27
|
-
|
45
|
+
# puts "user is #{val}"
|
28
46
|
user_flag=false }
|
29
47
|
opts.on("-t","--topic VAL", String) {|val| temp_hash[:topic ] = val
|
30
|
-
|
48
|
+
# puts "topic is #{val}"
|
31
49
|
topic_flag=false }
|
32
50
|
opts.on("-m","--msg_command VAL", String) {|val| temp_hash[:command ] = val
|
33
|
-
|
51
|
+
# puts "command is #{val}"
|
34
52
|
command_flag=false }
|
35
53
|
opts.on("-b","--body VAL", String) {|val| temp_hash[:body ] = val
|
36
|
-
|
54
|
+
# puts "body is #{val}"
|
37
55
|
body_flag=false }
|
38
56
|
#opts.on("-d","--database VAL", String) {|val| temp_hash[:db ] = val }
|
39
57
|
#opts.on("-p","--password VAL", String) {|val| temp_hash[:password ] = val }
|
@@ -48,16 +66,50 @@ def parse_options(params)
|
|
48
66
|
require 'pp'
|
49
67
|
options = arg_hash
|
50
68
|
# set up variables using hash
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
conn = Stomp::Connection.open '', '', host, port, false
|
55
|
-
# self.conn.subscribe @@TOPIC, { :ack =>"auto" }
|
56
|
-
puts "finished initializing"
|
57
|
-
m=StompMessage::Message.new(options[:command], options[:body])
|
58
|
-
# puts "message body is #{msgbody}"
|
59
|
-
conn.send options[:topic], m.to_xml, {'persistent'=>'false'}
|
60
|
-
|
69
|
+
msg_sender=StompMessage::StompSendTopic.new(options)
|
70
|
+
msg_sender.setup_auto_close
|
71
|
+
m=StompMessage::Message.new(options[:command],options[:body])
|
61
72
|
puts "message is: #{m.to_xml}"
|
62
|
-
|
73
|
+
# billing_sender.send_topic(m.body, arg_hash[:msisdn])
|
74
|
+
# m=StompMessage::Message.new('stomp_BILLING', msg)
|
75
|
+
header = {}
|
76
|
+
header[:msisdn]=arg_hash[:msisdn]
|
77
|
+
msg_received_flag=false
|
78
|
+
msg_data=nil
|
79
|
+
case options[:ack].downcase
|
80
|
+
when 'true'
|
81
|
+
msg_sender.send_topic_acknowledge(m,header,50) { |msg| # puts 'in handle action block'
|
82
|
+
puts 'MESSAGE RECEIVED ----'
|
83
|
+
msg_received_flag=true
|
84
|
+
msg_data=msg
|
85
|
+
puts "handle action block msg is #{msg.to_s}" }
|
86
|
+
begin
|
87
|
+
Timeout::timeout(100) {
|
88
|
+
while true
|
89
|
+
putc '.'
|
90
|
+
exit(0) if msg_received_flag
|
91
|
+
sleep(1)
|
92
|
+
end }
|
93
|
+
rescue SystemExit
|
94
|
+
|
95
|
+
rescue Exception => e
|
96
|
+
puts "exception #{e.message} class: #{e.class}"
|
97
|
+
puts "no receipt"
|
98
|
+
# raise "timeout"
|
99
|
+
#ensure
|
100
|
+
# msg_sender.setup_auto_close
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
else
|
105
|
+
msg_sender.send_topic(m,header)
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
msg_sender.send_email_stomp("scott.sproule@cure.com.ph","STOMP MSG", options[:email],
|
110
|
+
m.command, msg_data) if msg_received_flag and options[:email]!=nil
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
puts '-------------finished processing!!!'
|
63
115
|
|
data/config/hoe.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'stomp_message/version'
|
2
2
|
|
3
|
-
AUTHOR = '
|
4
|
-
EMAIL = "
|
5
|
-
DESCRIPTION = "
|
3
|
+
AUTHOR = 'scott sproule' # can also be an array of Authors
|
4
|
+
EMAIL = "scott dot sproule at ficonab dot com"
|
5
|
+
DESCRIPTION = "handling stomp messages and servers"
|
6
6
|
GEM_NAME = 'stomp_message' # what ppl will type to install your gem
|
7
|
-
RUBYFORGE_PROJECT = '
|
7
|
+
RUBYFORGE_PROJECT = 'stompmessage' # The unix name for your project
|
8
8
|
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
9
9
|
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
10
10
|
|
@@ -1,29 +1,97 @@
|
|
1
1
|
# basic format for stomp messages
|
2
2
|
require 'rexml/document'
|
3
|
+
#require 'xml_helper.rb'
|
4
|
+
require 'rubygems'
|
5
|
+
gem 'stomp_message'
|
6
|
+
require 'stomp_message'
|
3
7
|
module StompMessage
|
8
|
+
module XmlHelper
|
9
|
+
# create elements from instance variables... (instance variablesneed to be set)
|
10
|
+
#array variables need to end in s (eg mssidns) and are handled recurvisely
|
11
|
+
def xml_instance_variable(iv_input)
|
12
|
+
iv=iv_input.delete('@')
|
13
|
+
class_var=eval("self.#{iv}.class")
|
14
|
+
# puts "class is #{class_var} "
|
15
|
+
iv_xml=[]
|
16
|
+
case
|
17
|
+
when class_var==Array
|
18
|
+
#puts "in array with #{iv}"
|
19
|
+
len=iv.size
|
20
|
+
check_for_s=iv[len-1]
|
21
|
+
# puts "iv #{iv}: len is #{len} last digit is #{check_for_s}"
|
22
|
+
raise "not terminate in s or too short" if len <=1 or check_for_s!=115
|
23
|
+
the_array = eval("self.#{iv}")
|
24
|
+
iv_short = iv[0..len-2]
|
25
|
+
#puts "iv short is #{iv_short}"
|
26
|
+
the_array.each {|e|
|
27
|
+
iv_xml << create_element(iv_short,e) }
|
28
|
+
|
29
|
+
else
|
30
|
+
val= eval "self.#{iv}"
|
31
|
+
iv_xml[0]= create_element(iv.to_s,val)
|
32
|
+
end
|
33
|
+
return iv_xml
|
34
|
+
end
|
35
|
+
def create_element(element_name, element_value)
|
36
|
+
# puts "in create element #{element_name}: #{element_value}"
|
37
|
+
element_xml= REXML::Element.new element_name
|
38
|
+
element_xml.text=element_value
|
39
|
+
element_xml
|
40
|
+
end
|
41
|
+
# add all elements to top variable
|
42
|
+
def add_elements(top)
|
43
|
+
elements = []
|
44
|
+
self.instance_variables.each {|iv| xml_instance_variable(iv).each {|x| elements << x}
|
45
|
+
|
46
|
+
|
47
|
+
}
|
48
|
+
elements.each {|e| top.add_element e}
|
49
|
+
top
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
4
53
|
class Message
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
54
|
+
include StompMessage::XmlHelper
|
55
|
+
attr_accessor :__stomp_msg_command, :__stomp_msg_body
|
56
|
+
def initialize(cmd, bdy=nil)
|
57
|
+
raise 'command nil' if cmd==nil
|
58
|
+
self.__stomp_msg_command = cmd==nil ? '' : cmd.to_s
|
59
|
+
self.__stomp_msg_body = bdy==nil ? '' : bdy.to_s
|
60
|
+
|
9
61
|
end
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
62
|
+
def body
|
63
|
+
self.__stomp_msg_body
|
64
|
+
end
|
65
|
+
def command
|
66
|
+
self.__stomp_msg_command
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_xml
|
70
|
+
doc=REXML::Document.new()
|
71
|
+
msg_xml = REXML::Element.new "stomp_msg_message"
|
72
|
+
doc.add_element(msg_xml)
|
73
|
+
msg3 = self.add_elements(REXML::Element.new("__instance_variables"))
|
74
|
+
doc.root.add_element(msg3)
|
75
|
+
output =""
|
76
|
+
doc.write output
|
77
|
+
output
|
19
78
|
# doc= REXML::Document.new sms_xml.to_s
|
20
79
|
# doc.to_s
|
21
80
|
end
|
81
|
+
|
22
82
|
def self.load_xml(xml_string)
|
83
|
+
begin
|
23
84
|
doc=REXML::Document.new(xml_string)
|
24
|
-
command=REXML::XPath.first(doc, "//
|
25
|
-
|
26
|
-
|
85
|
+
command=REXML::XPath.first(doc, "//__stomp_msg_command").text
|
86
|
+
# puts "load_xml command is #{command}"
|
87
|
+
body=REXML::XPath.first(doc, "//__stomp_msg_body").text
|
88
|
+
# puts "load_xml body is #{body}"
|
89
|
+
sms=StompMessage::Message.new(command, body)
|
90
|
+
rescue Exception => e
|
91
|
+
puts "Exception in load xml:#{xml_string}"
|
92
|
+
puts "message #{e.message}"
|
93
|
+
end
|
94
|
+
sms
|
27
95
|
end
|
28
96
|
end
|
29
97
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'stomp_message'
|
3
|
+
require 'stomp_message'
|
4
|
+
require 'timeout'
|
5
|
+
gem 'openwferu'
|
6
|
+
require 'openwfe/participants/participants'
|
7
|
+
|
8
|
+
|
9
|
+
module OpenWFE
|
10
|
+
|
11
|
+
#
|
12
|
+
# Participant to send/receive work items to stomp message servers applications
|
13
|
+
# send message and asynch wait for response
|
14
|
+
#
|
15
|
+
# Timeoout may need to be changed
|
16
|
+
#
|
17
|
+
# On the return side, you can override the method handle_call_result
|
18
|
+
# for better mappings between messages calls and the workitems.
|
19
|
+
#
|
20
|
+
class StompParticipant
|
21
|
+
include LocalParticipant
|
22
|
+
attr_accessor :timeout_val, :options, :msg_sender
|
23
|
+
def initialize(topic, host='localhost', port=61613, timeout=4, &block)
|
24
|
+
|
25
|
+
|
26
|
+
self.options={}
|
27
|
+
self.options[:host]=host
|
28
|
+
self.options[:port]=port
|
29
|
+
self.options[:topic]=topic
|
30
|
+
self.timeout_val = timeout
|
31
|
+
self.msg_sender=StompMessage::StompSendTopic.new(self.options)
|
32
|
+
self.msg_sender.setup_auto_close
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# The method called by the engine when the flow reaches an instance
|
37
|
+
# of this Participant class.
|
38
|
+
#
|
39
|
+
def consume (workitem)
|
40
|
+
|
41
|
+
m=prepare_call_params(workitem)
|
42
|
+
puts "message is: #{m.to_xml}"
|
43
|
+
# billing_sender.send_topic(m.body, arg_hash[:msisdn])
|
44
|
+
# m=StompMessage::Message.new('stomp_BILLING', msg)
|
45
|
+
header={}
|
46
|
+
# header[:msisdn]=workitem.attributes[:msisdn]
|
47
|
+
begin
|
48
|
+
Timeout::timeout(self.timeout_val) {
|
49
|
+
self.msg_sender.send_topic_acknowledge(m,header) {
|
50
|
+
|msg| workitem=handle_call_result(msg, workitem)
|
51
|
+
}
|
52
|
+
}
|
53
|
+
rescue Timeout::Error
|
54
|
+
puts "STOMP participant:: consume(wi) exception"
|
55
|
+
workitem.attributes["__result__"]=false
|
56
|
+
workitem.attributes["stomp_TIMEOUT"]=true
|
57
|
+
# raise "timeout"
|
58
|
+
ensure
|
59
|
+
reply_to_engine(workitem)
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# The base implementation :prepares the message
|
68
|
+
# param there is a workitem field with the same name.
|
69
|
+
#
|
70
|
+
# Feel free to override this method.
|
71
|
+
#
|
72
|
+
def prepare_call_params (workitem)
|
73
|
+
m=StompMessage::Message.new(workitem.attributes[:command].to_s,
|
74
|
+
workitem.attributes[:body].to_s)
|
75
|
+
m
|
76
|
+
# puts "message is: #{m.to_xml}"
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# This implementation simply stuffs the result into the workitem
|
81
|
+
# as an attribute named "__result__".
|
82
|
+
#
|
83
|
+
# Feel free to override this method.
|
84
|
+
#
|
85
|
+
def handle_call_result (result, workitem)
|
86
|
+
|
87
|
+
puts 'in handle action block'
|
88
|
+
puts 'MESSAGE RECEIVED ----'
|
89
|
+
m= StompMessage::Message.load_xml(result)
|
90
|
+
workitem.attributes["__result__"]=m.to_xml
|
91
|
+
workitem.attributes["command"]=m.command.to_s
|
92
|
+
workitem.attributes["body"]=m.body.to_s
|
93
|
+
puts "wi #{workitem.attributes.to_s}"
|
94
|
+
workitem
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'rubygems'
|
3
|
+
gem 'stomp'
|
4
|
+
require 'stomp'
|
5
|
+
require 'net/smtp'
|
6
|
+
require 'net/http'
|
7
|
+
require 'socket'
|
8
|
+
|
9
|
+
# This
|
10
|
+
module StompMessage
|
11
|
+
# this class manages sending and receiving messages. It uses passed code block to execute received code
|
12
|
+
class StompSendTopic
|
13
|
+
attr_accessor :conn, :topic, :host, :port, :login, :password, :url
|
14
|
+
#need to define topic, host properly
|
15
|
+
|
16
|
+
def initialize(options={})
|
17
|
+
# set up variables using hash
|
18
|
+
@close_ok=false
|
19
|
+
init_vars(options)
|
20
|
+
# puts "host is: #{host} port is #{port}"
|
21
|
+
# using url as flag wrong
|
22
|
+
# self.conn = Stomp::Client.new(self.login, self.password, self.host, self.port, false) if self.url ==nil
|
23
|
+
|
24
|
+
puts "#{self.class}: Initialized host is: #{self.host} port is #{self.port} topic is #{self.topic} login #{self.login} pass: #{self.password}"
|
25
|
+
# scott old self.conn.subscribe( self.topic, { :ack =>"auto" }) { |m|
|
26
|
+
# self.conn.subscribe( self.topic, { :ack =>"client" }) { |m|
|
27
|
+
# # puts "#{self.class} msg: #{m.to_s}"
|
28
|
+
# }
|
29
|
+
# setup_auto_close
|
30
|
+
end
|
31
|
+
def init_vars(options)
|
32
|
+
self.login = options[:login]==nil ? '' : options[:login]
|
33
|
+
self.url = options[:url]== nil ? nil : options[:url]
|
34
|
+
self.password = options[:password]==nil ? '' : options[:password]
|
35
|
+
self.host = options[:host]==nil ? 'localhost' : options[:host]
|
36
|
+
self.port = options[:port]==nil ? '61613' : options[:port]
|
37
|
+
self.topic = options[:topic]==nil ? '/topic/undefined' : options[:topic]
|
38
|
+
self.conn=nil
|
39
|
+
puts "self url is #{self.url}"
|
40
|
+
end
|
41
|
+
# only call this once
|
42
|
+
def setup_auto_close
|
43
|
+
|
44
|
+
at_exit { puts "#{self.class}: auto close exit block"
|
45
|
+
close_topic
|
46
|
+
disconnect_stomp } if !@close_ok
|
47
|
+
@close_ok=true
|
48
|
+
end
|
49
|
+
#manage timeout etc...
|
50
|
+
def self.open_connection(old_conn,login,pass,host,port)
|
51
|
+
conn=old_conn
|
52
|
+
flag=false
|
53
|
+
begin
|
54
|
+
conn.close if conn!=nil
|
55
|
+
|
56
|
+
Timeout::timeout(5) {
|
57
|
+
conn=nil
|
58
|
+
conn = Stomp::Client.new(login, pass, host, port, false)
|
59
|
+
flag=true
|
60
|
+
}
|
61
|
+
|
62
|
+
rescue Timeout::Error
|
63
|
+
puts "Timeout error: exception retrying flag is: #{flag}"
|
64
|
+
retry if !flag
|
65
|
+
# raise "timeout"
|
66
|
+
|
67
|
+
end
|
68
|
+
conn
|
69
|
+
end
|
70
|
+
def open_connection
|
71
|
+
self.conn = StompMessage::StompSendTopic.open_connection(@conn, self.login, self.password, self.host, self.port) if self.conn==nil
|
72
|
+
end
|
73
|
+
# close the topic
|
74
|
+
def close_topic
|
75
|
+
self.conn.unsubscribe(self.topic) if self.conn !=nil
|
76
|
+
# self.conn=nil
|
77
|
+
end
|
78
|
+
#disconnect the connection
|
79
|
+
def disconnect_stomp
|
80
|
+
close_topic
|
81
|
+
puts "#{self.class} closing connection"
|
82
|
+
self.conn.close() if self.conn !=nil
|
83
|
+
end
|
84
|
+
# post stomp message to url
|
85
|
+
def post_stomp(msg,headers)
|
86
|
+
|
87
|
+
response_header = {"Content-type" => "text/xml"}
|
88
|
+
response_header.merge headers
|
89
|
+
ht =Net::HTTP.start(self.host,self.port)
|
90
|
+
r=ht.post(self.url,msg.to_xml,response_header)
|
91
|
+
puts "url was: #{url}"
|
92
|
+
puts "result: #{r.to_s}"
|
93
|
+
r
|
94
|
+
end
|
95
|
+
def send_topic(msg, headers, &r_block)
|
96
|
+
# m=StompMessage::Message.new('stomp_BILLING', msg)
|
97
|
+
open_connection
|
98
|
+
more_headers= {'persistent'=>'false' }
|
99
|
+
more_headers.merge headers
|
100
|
+
self.conn.send(self.topic, msg.to_xml, more_headers, &r_block)
|
101
|
+
# Thread.pass
|
102
|
+
end #send_sms
|
103
|
+
# be careful with the receipt topic calculations... strange errors onactive mq
|
104
|
+
def send_topic_acknowledge(msg, headers, timeout=4)
|
105
|
+
#m=StompMessage::Message.new('stomp_BILLING', msg)
|
106
|
+
open_connection
|
107
|
+
s=rand*20 # scott - used to be 1000 but seem to create connections on activemq
|
108
|
+
# open new topic to listen to reply...
|
109
|
+
# was this but jms seems to blow up receipt_topic="/topic/receipt/client#{s.to_i}"
|
110
|
+
receipt_topic="/topic/rcpt_client#{s.to_i}"
|
111
|
+
receipt_flag = false
|
112
|
+
# internal_conn = Stomp::Connection.open '', '', self.host, self.port, false
|
113
|
+
self.conn.subscribe( receipt_topic, { :ack =>"client" }) {|msg|
|
114
|
+
begin
|
115
|
+
Timeout::timeout(timeout) {
|
116
|
+
self.conn.acknowledge(msg,msg.headers)
|
117
|
+
msg2= msg.body
|
118
|
+
yield msg2
|
119
|
+
}
|
120
|
+
rescue Exception => e
|
121
|
+
puts "exception #{e.message}"
|
122
|
+
# raise "timeout"
|
123
|
+
ensure
|
124
|
+
receipt_flag=true
|
125
|
+
self.conn.unsubscribe receipt_topic
|
126
|
+
end
|
127
|
+
}
|
128
|
+
|
129
|
+
|
130
|
+
more_headers= {'persistent'=>'false', 'reply-to' => "#{receipt_topic}" }
|
131
|
+
more_headers.merge headers
|
132
|
+
self.conn.send(self.topic, msg.to_xml, more_headers )
|
133
|
+
Thread.new { sleep(timeout)
|
134
|
+
puts "calling unsubscribe on #{receipt_topic}" if !receipt_flag
|
135
|
+
self.conn.unsubscribe receipt_topic if !receipt_flag
|
136
|
+
}
|
137
|
+
end #send_sms
|
138
|
+
def send_email_stomp(from, from_alias, to, subject, message)
|
139
|
+
StompMessage::StompSendTopic.send_email_stomp(from,from_alias,to,subject,message)
|
140
|
+
end
|
141
|
+
def self.send_email_stomp(from, from_alias, to, subject, message)
|
142
|
+
#to_csv_array=to.each.join(",")
|
143
|
+
msg = <<EOF__RUBY_END_OF_MESSAGE
|
144
|
+
From: #{from_alias} <#{from}>
|
145
|
+
To: #{to}
|
146
|
+
Subject: #{subject} #{Time.now}
|
147
|
+
Comand ----------
|
148
|
+
#{subject}
|
149
|
+
RESPONSE -----------
|
150
|
+
#{message}
|
151
|
+
EOF__RUBY_END_OF_MESSAGE
|
152
|
+
recipients=to.split(',')
|
153
|
+
recipients.each {|r| StompMessage::StompSendTopic.send_email(from,r,msg)}
|
154
|
+
|
155
|
+
end
|
156
|
+
def self.send_email(from,to,msg)
|
157
|
+
case Socket.gethostname
|
158
|
+
when "svbalance.cure.com.ph"
|
159
|
+
smtp_host='mail2.cure.com.ph'
|
160
|
+
when "Scotts-Computer.local"
|
161
|
+
smtp_host='mail2.cure.com.ph'
|
162
|
+
else
|
163
|
+
smtp_host='localhost'
|
164
|
+
end
|
165
|
+
|
166
|
+
Net::SMTP.start(smtp_host) { |smtp|
|
167
|
+
smtp.send_message(msg, from, to)
|
168
|
+
}
|
169
|
+
end
|
170
|
+
|
171
|
+
end # stomp send topic
|
172
|
+
|
173
|
+
end #module
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# basic format for stomp messages
|
2
|
+
require 'rexml/document'
|
3
|
+
require 'socket'
|
4
|
+
# basic server class for listening to topics
|
5
|
+
module StompMessage
|
6
|
+
class StompServer
|
7
|
+
attr_accessor :conn, :topic, :msg_count, :exception_count, :host, :port, :login, :password, :queue, :thread_count, :mythreads
|
8
|
+
#need to define topic, host properly
|
9
|
+
@debug=false
|
10
|
+
|
11
|
+
def initialize(options={})
|
12
|
+
@my_hostname = Socket.gethostname
|
13
|
+
self.login = options[:login]==nil ? '' : options[:login]
|
14
|
+
num = options[:thread_count]==nil ? '2' : options[:thread_count]
|
15
|
+
self.thread_count=num.to_i
|
16
|
+
self.password = options[:password]==nil ? '' : options[:password]
|
17
|
+
self.host = options[:host]==nil ? 'localhost' : options[:host]
|
18
|
+
self.port = options[:port]==nil ? '61613' : options[:port]
|
19
|
+
self.topic = options[:topic]==nil ? '/topic/please_define' : options[:topic]
|
20
|
+
puts "#{self.class}: message broker host is: #{host} port is #{port} topic is: #{self.topic} threads #{self.thread_count} my host: #{@my_hostname}"
|
21
|
+
self.msg_count = self.exception_count=0
|
22
|
+
self.queue= Queue.new
|
23
|
+
self.conn=nil
|
24
|
+
connect_connection
|
25
|
+
# self.conn = Stomp::Client.new self.login, self.password, self.host, self.port, false
|
26
|
+
# self.conn = Stomp::Connection.open self.login, self.password, self.host , self.port, false
|
27
|
+
connect_topic
|
28
|
+
@debug=false
|
29
|
+
puts "finished StompServer initializing"
|
30
|
+
setup_auto_close
|
31
|
+
trap("INT") { puts "#{Time.now}: #{self.class} in interrupt trap\n"
|
32
|
+
#close_topic
|
33
|
+
#disconnect_stomp
|
34
|
+
#setup_auto_close already done in INIT
|
35
|
+
exit(0)}
|
36
|
+
end
|
37
|
+
def connect_connection
|
38
|
+
self.conn = StompMessage::StompSendTopic.open_connection(self.conn, self.login, self.password, self.host, self.port)
|
39
|
+
end
|
40
|
+
def setup_auto_close
|
41
|
+
at_exit { puts "#{self.class}: in at exit block"
|
42
|
+
close_topic
|
43
|
+
disconnect_stomp
|
44
|
+
# self.mythreads.each {|t| t.raise "auto exit" }
|
45
|
+
}
|
46
|
+
end
|
47
|
+
def disconnect_stomp
|
48
|
+
puts "#{self.class} #{@my_hostname} closing connection"
|
49
|
+
self.conn.close() if self.conn !=nil
|
50
|
+
end
|
51
|
+
def send_reply(headers,msg)
|
52
|
+
reply_topic=headers['reply-to']
|
53
|
+
# puts "headers: #{headers['msisdn']} reply topic #{headers['reply-to']}"
|
54
|
+
# internal_conn = Stomp::Connection.open '', '', self.host, self.port, false
|
55
|
+
# scott old auto
|
56
|
+
# scott not needed self.conn.subscribe(reply_topic, { :ack =>"client" }) {|m| puts "yes boring should not be called: #{m.to_s}"
|
57
|
+
# }
|
58
|
+
# m=StompMessage::Message.new('stomp_REPLY', msg_body)
|
59
|
+
response_header = {'persistent'=>'false'}
|
60
|
+
response_header.merge headers
|
61
|
+
self.conn.send(reply_topic, msg.to_xml, response_header )
|
62
|
+
# self.conn.unsubscribe reply_topic #testing shoul call this but not certain about it
|
63
|
+
# internal_conn.disconnect
|
64
|
+
end
|
65
|
+
# name is message command
|
66
|
+
def connect_topic
|
67
|
+
# scott old ack auot
|
68
|
+
# see http://activemq.apache.org/stomp.html for activemq.dispathAsync settig
|
69
|
+
self.conn.subscribe( self.topic, { :ack =>"client" , 'activemq.dispatchAsync' => 'false'}) { |msg|
|
70
|
+
|
71
|
+
self.msg_count+=1
|
72
|
+
begin
|
73
|
+
self.conn.acknowledge(msg,msg.headers)
|
74
|
+
self.queue << msg
|
75
|
+
|
76
|
+
rescue Exception => e
|
77
|
+
self.exception_count+=1
|
78
|
+
puts " Thread: :exception found #{e.backtrace}"
|
79
|
+
puts "Thread: :exception messag #{e.message}"
|
80
|
+
end
|
81
|
+
|
82
|
+
}
|
83
|
+
end
|
84
|
+
# close the topic, override if necessary
|
85
|
+
def close_topic
|
86
|
+
puts "#{self.class} #{@my_hostname} unsubscribing #{self.topic}"
|
87
|
+
self.conn.unsubscribe self.topic if self.conn!=nil
|
88
|
+
end
|
89
|
+
def stomp_PING(msg,stomp_msg)
|
90
|
+
body="ALIVE Class: #{self.class.to_s} listing to: #{self.topic} on host #{@my_hostname} msg_count #{self.msg_count} exception_count #{self.exception_count}"
|
91
|
+
reply_msg = StompMessage::Message.new('stomp_REPLY', body)
|
92
|
+
send_reply(stomp_msg.headers,reply_msg) if stomp_msg.headers['reply-to']!=nil
|
93
|
+
end
|
94
|
+
def stomp_DEBUG(msg,stomp_msg)
|
95
|
+
@debug=!@debug
|
96
|
+
puts "debug flag is now #{@debug}"
|
97
|
+
end
|
98
|
+
def method_missing(name, *args)
|
99
|
+
puts "Method missing called: #{name}"
|
100
|
+
puts "Likely invalid message recieved"
|
101
|
+
end
|
102
|
+
# monitor queue
|
103
|
+
def monitor_queue_status
|
104
|
+
puts "starting up queue status"
|
105
|
+
self.mythreads << Thread.new { while true
|
106
|
+
sleep(30)
|
107
|
+
puts "QUEUE size is: #{self.queue.size}"
|
108
|
+
# puts "-------conn var is on #{self.conn.inspect}"
|
109
|
+
if !self.conn.open?
|
110
|
+
puts "restarting connection"
|
111
|
+
self.conn=nil
|
112
|
+
connect_connection
|
113
|
+
connect_topic
|
114
|
+
end
|
115
|
+
end # while
|
116
|
+
}
|
117
|
+
end
|
118
|
+
def handle_message(msg)
|
119
|
+
puts "STOMP message frame is : #{msg} " if @debug
|
120
|
+
m=StompMessage::Message.load_xml(msg.body)
|
121
|
+
# puts "Message is: #{m.to_xml}" if @debug
|
122
|
+
puts "Message type is #{m.command}" if @debug
|
123
|
+
send(m.command, m, msg) # effectively case statement (Should SCREEN HERE)
|
124
|
+
# puts "sms text is: #{sms.text} dest is: #{sms.destination} result is: #{res}"
|
125
|
+
end
|
126
|
+
def run
|
127
|
+
self.mythreads = []
|
128
|
+
1.upto(self.thread_count) { |c| # create the threads here
|
129
|
+
puts "creating thread: #{c}"
|
130
|
+
self.mythreads << Thread.new(c) { |ctmp|
|
131
|
+
while true
|
132
|
+
|
133
|
+
begin
|
134
|
+
msg=self.queue.pop
|
135
|
+
handle_message(msg)
|
136
|
+
|
137
|
+
rescue Exception => e
|
138
|
+
self.exception_count+=1
|
139
|
+
puts " Thread: #{ctmp} :exception found #{e.backtrace}"
|
140
|
+
puts "Thread: #{ctmp} :exception messag #{e.message}"
|
141
|
+
result = "-----------EXCEPTION FOUND----------\n"
|
142
|
+
result << "ALIVE Class: #{self.class.to_s} listing to: #{self.topic} on host #{@my_hostname} msg_count #{self.msg_count} exception_count #{self.exception_count}\n"
|
143
|
+
result << "-----exception data--------\n"
|
144
|
+
result << " Thread: #{ctmp} :exception found #{e.backtrace}\n"
|
145
|
+
result << "Thread: #{ctmp} :exception messag #{e.message}"
|
146
|
+
begin
|
147
|
+
StompMessage::StompSendTopic.send_email_stomp("scott.sproule@cure.com.ph",
|
148
|
+
"STOMP EXCEPTION", "scott.sproule@cure.com.ph","Thread: #{ctmp} :exception messag #{e.message}", result)
|
149
|
+
rescue Exception => e
|
150
|
+
puts "Can not send email, please check smtp host setting"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
# Thread.pass
|
154
|
+
end
|
155
|
+
}
|
156
|
+
}
|
157
|
+
monitor_queue_status
|
158
|
+
self.mythreads.each { |t| t.join }
|
159
|
+
|
160
|
+
|
161
|
+
# msg = self.conn.receive
|
162
|
+
# puts "after receive"
|
163
|
+
# self.msg_count+=1
|
164
|
+
# begin
|
165
|
+
# handle_message(msg)
|
166
|
+
# rescue Exception => e
|
167
|
+
# self.exception_count+=1
|
168
|
+
# puts "exception found #{e.backtrace}"
|
169
|
+
# puts "exception messag #{e.message}"
|
170
|
+
# end
|
171
|
+
# end # while
|
172
|
+
|
173
|
+
# t.join # wait for t to die..
|
174
|
+
end #run
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# basic format for stomp messages
|
2
|
+
require 'rexml/document'
|
3
|
+
# basic statistics class for listening to topics
|
4
|
+
module StompMessage
|
5
|
+
# statistics listening class. Updates the statistics at every message/event
|
6
|
+
class StompStatisticsServer < StompMessage::StompServer
|
7
|
+
attr_accessor :tags, :statistics
|
8
|
+
def setup_var
|
9
|
+
self.tags = %w(hour day week month)
|
10
|
+
self.statistics = Hash.new
|
11
|
+
self.tags.each { |tagv| statistics[tagv] = Hash.new(0) }
|
12
|
+
@old_exception_count=0
|
13
|
+
end
|
14
|
+
def initialize(options={})
|
15
|
+
super(options)
|
16
|
+
setup_var
|
17
|
+
end
|
18
|
+
# update the statistics by tag value (eg hour)
|
19
|
+
def increment_stats(tag, element)
|
20
|
+
self.statistics[tag][element]+=1
|
21
|
+
end
|
22
|
+
# reset element to zero (eg reset hour to zero)
|
23
|
+
def reset_element(tag, element)
|
24
|
+
self.statistics[tag][element]=0
|
25
|
+
end
|
26
|
+
# increment all the tags with a new element value . Hash is zero if not found
|
27
|
+
def tag_increment(element)
|
28
|
+
self.tags.each {|tagv| puts "incrementing #{tagv} element: #{element}" if @debug
|
29
|
+
increment_stats(tagv,element)}
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
def handle_message(msg)
|
34
|
+
puts "in handle message stomp stat server" if @debug
|
35
|
+
m=StompMessage::Message.load_xml(msg.body)
|
36
|
+
tag_increment(m.command)
|
37
|
+
super(msg)
|
38
|
+
tag_increment('msg_count')
|
39
|
+
tag_increment('exception_count') if @old_exception_count!= self.exception_count
|
40
|
+
@old_exception_count= self.exception_count
|
41
|
+
|
42
|
+
end
|
43
|
+
def stomp_PING(msg, stomp_msg)
|
44
|
+
puts "stomp PING: #{msg.body}" if @debug
|
45
|
+
#do not reply as statistic servers do no respond to pings. they respond to stomp_REPORT
|
46
|
+
end
|
47
|
+
#def create_statistics(msg) # k[it]=0 if !k.key?(it)
|
48
|
+
# self.tags.each { |tagv| self.statistics[tagv].each {|k|
|
49
|
+
# internal_tags = %w(msg_count, exception_count )
|
50
|
+
# internal_tags.each { |it|
|
51
|
+
# data= eval("self.#{it}")
|
52
|
+
# k[it]= data-k[it]
|
53
|
+
# puts "it is #{it}: data is #{data} k[it] is #{k[it]}"
|
54
|
+
# }
|
55
|
+
# }
|
56
|
+
# }
|
57
|
+
#
|
58
|
+
#end
|
59
|
+
def stomp_REPORT(msg, stomp_msg)
|
60
|
+
|
61
|
+
result= " Stomp Report #{Time.now}\n"
|
62
|
+
result << " Messages processed: #{self.msg_count} \n"
|
63
|
+
flag = self.exception_count!=nil ? '' : 'IMPORTANT'
|
64
|
+
result << "#{flag} Exceptions processed: #{self.exception_count}\n "
|
65
|
+
self.tags.each { |tagv| # run through each tag (hour, day etc)
|
66
|
+
result << "#{tagv} Latests Statistics\n"
|
67
|
+
self.statistics[tagv].each {|k,v| result << " ----- #{k}: #{v}\n"}
|
68
|
+
}
|
69
|
+
puts result if @debug
|
70
|
+
reply_msg = StompMessage::Message.new('stomp_REPLY', "#{result}")
|
71
|
+
send_reply(stomp_msg.headers,reply_msg) if stomp_msg.headers['reply-to']!=nil
|
72
|
+
result
|
73
|
+
end
|
74
|
+
def stomp_RESET(msg, stomp_msg)
|
75
|
+
puts "stomp reset: #{msg.body}" if @debug
|
76
|
+
reset_tag = msg.body.to_s if self.tags.include?(msg.body.to_s)
|
77
|
+
puts " --- RESET TAG: #{reset_tag}"
|
78
|
+
self.statistics[reset_tag].each { |k,v| self.statistics[reset_tag][k]=0
|
79
|
+
puts "RESET: tag #{k} value is zero"
|
80
|
+
} if self.tags.include?(msg.body.to_s)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
data/test/test_stomp_message.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
-
|
2
|
+
class OpenWFE::StompParticipant
|
3
|
+
def reply_to_engine(workitem)
|
4
|
+
puts "hello from test reply to engine"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
require 'rubygems'
|
8
|
+
gem 'openwferu'
|
9
|
+
require 'openwfe/workitem'
|
3
10
|
class TestStompMessage < Test::Unit::TestCase
|
4
11
|
|
5
12
|
def setup
|
@@ -10,6 +17,66 @@ class TestStompMessage < Test::Unit::TestCase
|
|
10
17
|
m2=StompMessage::Message.new("command")
|
11
18
|
assert m1.to_xml==m2.to_xml, "xml generation wrong"
|
12
19
|
end
|
20
|
+
def test_object_create2
|
21
|
+
m1=StompMessage::Message.new("command",true)
|
22
|
+
m2=StompMessage::Message.new("command",true)
|
23
|
+
assert m1.to_xml==m2.to_xml, "xml generation wrong"
|
24
|
+
m1=StompMessage::Message.new("command",false)
|
25
|
+
m2=StompMessage::Message.new("command",false)
|
26
|
+
assert m1.to_xml==m2.to_xml, "xml generation wrong"
|
27
|
+
end
|
28
|
+
def test_object_nil
|
29
|
+
begin
|
30
|
+
m1=StompMessage::Message.new(nil)
|
31
|
+
rescue Exception => e
|
32
|
+
assert true, 'raised exception'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
class M3 < StompMessage::Message
|
36
|
+
attr_accessor :msisdns, :bad , :s
|
37
|
+
def initialize(cmd)
|
38
|
+
super(cmd)
|
39
|
+
self.msisdns=[]
|
40
|
+
self.s= []
|
41
|
+
self.bad = []
|
42
|
+
self.msisdns << "test"
|
43
|
+
self.msisdns << "test2"
|
44
|
+
self.bad << "test"
|
45
|
+
self.s << "test"
|
46
|
+
end
|
47
|
+
end # class M3
|
48
|
+
class M4 < StompMessage::Message
|
49
|
+
attr_accessor :msisdns
|
50
|
+
def initialize(cmd)
|
51
|
+
super(cmd, "body")
|
52
|
+
self.msisdns=[]
|
53
|
+
self.msisdns << "test"
|
54
|
+
self.msisdns << "test2"
|
55
|
+
end
|
56
|
+
end # class M3
|
57
|
+
def test_xml1_helper
|
58
|
+
puts "XML Helper test"
|
59
|
+
m2=M3.new("command")
|
60
|
+
begin
|
61
|
+
res=m2.to_xml
|
62
|
+
# puts "m2 xml is #{res}"
|
63
|
+
rescue Exception => e
|
64
|
+
puts "found exception #{e.message}"
|
65
|
+
assert e.message=="not terminate in s or too short", "bad message"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
def test_xml2_helper
|
69
|
+
puts "XML2 Helper test"
|
70
|
+
m2=M4.new("command")
|
71
|
+
begin
|
72
|
+
res=m2.to_xml
|
73
|
+
puts "m2 xml is #{res}"
|
74
|
+
rescue Exception => e
|
75
|
+
puts "found exception #{e.message}"
|
76
|
+
assert false, "bad message #{e.message}"
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
13
80
|
def test_object_duplication
|
14
81
|
m1=StompMessage::Message.new("command")
|
15
82
|
m2=StompMessage::Message.new("command")
|
@@ -17,8 +84,131 @@ class TestStompMessage < Test::Unit::TestCase
|
|
17
84
|
assert m1.to_xml==m2.to_xml, "xml generation wrong"
|
18
85
|
assert m3.to_xml==m2.to_xml, "xml generation wrong"
|
19
86
|
m2=StompMessage::Message.new("command","body")
|
20
|
-
assert m3.to_xml!=m2.to_xml, "xml generation wrong"
|
87
|
+
assert m3.to_xml!=m2.to_xml, "xml generation wrong"
|
21
88
|
m4=StompMessage::Message.load_xml(m2.to_xml)
|
22
|
-
|
89
|
+
puts "CHECK THIS m2 is: #{m2.to_xml} m4 is #{m4.to_xml}"
|
90
|
+
assert m4.body==m2.body, "xml generation wrong"
|
91
|
+
end
|
92
|
+
def test_statistics_server
|
93
|
+
#note activemq or stomp message bus needs to be running
|
94
|
+
args={:topic => '/topic/test'}
|
95
|
+
ss=StompMessage::StompStatisticsServer.new(args)
|
96
|
+
ss_thread = Thread.new {
|
97
|
+
ss.run }
|
98
|
+
assert ss.topic=='/topic/test', "topic not set properly"
|
99
|
+
sleep(1)
|
100
|
+
msg=StompMessage::Message.new('stomp_REPORT', "body")
|
101
|
+
assert msg.command=='stomp_REPORT', "message command not correct"
|
102
|
+
puts "creating send topic"
|
103
|
+
send_topic=StompMessage::StompSendTopic.new(args)
|
104
|
+
puts "send topic NO ack"
|
105
|
+
send_topic.send_topic(msg,{ :msisdn => "639999"})
|
106
|
+
puts "send topic WITH ack"
|
107
|
+
msg_reply=''
|
108
|
+
send_topic.send_topic_acknowledge(msg,{ :msisdn => "639999"}) { |m| assert true
|
109
|
+
puts "#{m.to_s}"
|
110
|
+
msg_reply=StompMessage::Message.load_xml(m)
|
111
|
+
|
112
|
+
}
|
113
|
+
sleep(3)
|
114
|
+
assert msg_reply.command== 'stomp_REPLY', "command wrong"
|
115
|
+
ss_thread.kill
|
116
|
+
end
|
117
|
+
def test_base_server
|
118
|
+
#note activemq or stomp message bus needs to be running
|
119
|
+
args={:topic => '/topic/test'}
|
120
|
+
ss=StompMessage::StompServer.new(args)
|
121
|
+
ss_thread = Thread.new {
|
122
|
+
ss.run }
|
123
|
+
sleep(3)
|
124
|
+
assert ss.topic=='/topic/test', "topic not set properly"
|
125
|
+
msg=StompMessage::Message.new('stomp_PING', "body")
|
126
|
+
assert msg.command=='stomp_PING', "message command not correct"
|
127
|
+
puts "creating ping messager topic"
|
128
|
+
send_topic=StompMessage::StompSendTopic.new(args)
|
129
|
+
puts "send ping WITH ack"
|
130
|
+
msg_reply=''
|
131
|
+
send_topic.send_topic_acknowledge(msg,{ :msisdn => "639999"}) { |m| assert true
|
132
|
+
puts "#{m.to_s}"
|
133
|
+
msg_reply=StompMessage::Message.load_xml(m)
|
134
|
+
assert msg_reply.body.split[0]== 'ALIVE', "ping not ok #{msg_reply.body}"
|
135
|
+
}
|
136
|
+
sleep(3)
|
137
|
+
assert msg_reply.command== 'stomp_REPLY', "command wrong"
|
138
|
+
send_topic.close_topic
|
139
|
+
ss_thread.kill
|
140
|
+
end
|
141
|
+
def test_statistics_reset
|
142
|
+
#note activemq or stomp message bus needs to be running
|
143
|
+
args={:topic => '/topic/test'}
|
144
|
+
ss=StompMessage::StompStatisticsServer.new(args)
|
145
|
+
ss_thread = Thread.new {
|
146
|
+
ss.run }
|
147
|
+
assert ss.topic=='/topic/test', "topic not set properly"
|
148
|
+
msg=StompMessage::Message.new('stomp_REPORT', "body")
|
149
|
+
assert msg.command=='stomp_REPORT', "message command not correct"
|
150
|
+
puts "creating send topic"
|
151
|
+
send_topic=StompMessage::StompSendTopic.new(args)
|
152
|
+
puts "send topic NO ack"
|
153
|
+
send_topic.send_topic(msg,{ :msisdn => "639999"})
|
154
|
+
puts "send topic WITH ack"
|
155
|
+
msg_reply = ""
|
156
|
+
send_topic.setup_auto_close
|
157
|
+
send_topic.send_topic_acknowledge(msg,{ :msisdn => "639999"}) { |m| assert true
|
158
|
+
puts "#{m.to_s}"
|
159
|
+
msg_reply=StompMessage::Message.load_xml(m)
|
160
|
+
|
161
|
+
}
|
162
|
+
sleep(3)
|
163
|
+
assert msg_reply.command== 'stomp_REPLY', "command wrong"
|
164
|
+
send_topic.send_topic_acknowledge(msg,{ :msisdn => "639999"}) { |m| assert true
|
165
|
+
puts "#{m.to_s}"
|
166
|
+
msg_reply=StompMessage::Message.load_xml(m)
|
167
|
+
|
168
|
+
}
|
169
|
+
sleep(3)
|
170
|
+
assert msg_reply.command== 'stomp_REPLY', "command wrong"
|
171
|
+
response = msg_reply.body.to_s
|
172
|
+
assert response.include?("stomp_REPORT: 3"), "Stomp_Report 3 not included"
|
173
|
+
assert !response.to_s.include?("stomp_REPORT: 0"), "Stomp_Report: 0 included"
|
174
|
+
# reset hour statistics
|
175
|
+
msg2=StompMessage::Message.new('stomp_RESET', "hour")
|
176
|
+
assert msg2.command=='stomp_RESET', "message command not correct"
|
177
|
+
puts "creating send msg2 topic"
|
178
|
+
send_topic.send_topic(msg2,{ :msisdn => "639999"})
|
179
|
+
send_topic.send_topic_acknowledge(msg,{ :msisdn => "639999"}) { |m| assert true
|
180
|
+
puts "#{m.to_s}"
|
181
|
+
msg_reply=StompMessage::Message.load_xml(m)
|
182
|
+
|
183
|
+
}
|
184
|
+
sleep(3)
|
185
|
+
assert msg_reply.command== 'stomp_REPLY', "command wrong"
|
186
|
+
response = msg_reply.body.to_s
|
187
|
+
assert response.include?("stomp_REPORT: 1"), "Stomp_Report 0 not included"
|
188
|
+
assert response.include?("stomp_RESET: 1"), "Stomp_RESET 1 not included"
|
189
|
+
assert !response.to_s.include?("stomp_REPORT: 2"), "Stomp_Report: 2 included"
|
190
|
+
ss_thread.kill
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_stomp_parti
|
194
|
+
#note activemq or stomp message bus needs to be running
|
195
|
+
args={}
|
196
|
+
args[:topic] = '/topic/test'
|
197
|
+
ss=StompMessage::StompServer.new(args)
|
198
|
+
ss_thread = Thread.new {
|
199
|
+
ss.run }
|
200
|
+
assert ss.topic=='/topic/test', "topic not set properly"
|
201
|
+
participant=OpenWFE::StompParticipant.new('/topic/test') { puts "hello from block"}
|
202
|
+
wi = OpenWFE::WorkItem.new()
|
203
|
+
wi[:command] = 'stomp_PING'
|
204
|
+
wi[:body] = 'body'
|
205
|
+
wi[:msisdn] = '63999999'
|
206
|
+
m2=StompMessage::Message.new(wi[:command].to_s,wi[:body].to_s)
|
207
|
+
puts "m2: #{m2.to_xml}"
|
208
|
+
assert m2.to_xml==StompMessage::Message.load_xml(m2.to_xml).to_xml, "problems in wi xml"
|
209
|
+
wi['sms'] = "hello there"
|
210
|
+
participant.consume(wi)
|
211
|
+
ss_thread.kill
|
212
|
+
|
23
213
|
end
|
24
214
|
end
|
metadata
CHANGED
@@ -3,15 +3,15 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: stomp_message
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-
|
8
|
-
summary:
|
6
|
+
version: 0.1.2
|
7
|
+
date: 2007-10-17 00:00:00 +08:00
|
8
|
+
summary: handling stomp messages and servers
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
|
-
email:
|
12
|
-
homepage: http://
|
13
|
-
rubyforge_project:
|
14
|
-
description:
|
11
|
+
email: scott dot sproule at ficonab dot com
|
12
|
+
homepage: http://stompmessage.rubyforge.org
|
13
|
+
rubyforge_project: stompmessage
|
14
|
+
description: handling stomp messages and servers
|
15
15
|
autorequire:
|
16
16
|
default_executable:
|
17
17
|
bindir: bin
|
@@ -27,7 +27,7 @@ signing_key:
|
|
27
27
|
cert_chain:
|
28
28
|
post_install_message:
|
29
29
|
authors:
|
30
|
-
-
|
30
|
+
- scott sproule
|
31
31
|
files:
|
32
32
|
- History.txt
|
33
33
|
- License.txt
|
@@ -38,6 +38,10 @@ files:
|
|
38
38
|
- config/requirements.rb
|
39
39
|
- lib/stomp_message.rb
|
40
40
|
- lib/stomp_message/version.rb
|
41
|
+
- lib/stomp_message/stomp_server.rb
|
42
|
+
- lib/stomp_message/stomp_statistics_server.rb
|
43
|
+
- lib/stomp_message/stomp_send_topic.rb
|
44
|
+
- lib/stomp_message/stomp_participant.rb
|
41
45
|
- lib/stomp_message/message.rb
|
42
46
|
- log/debug.log
|
43
47
|
- bin/stomp_message_send.rb
|