jsparrow 1.1.3 → 1.1.4
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/README.rdoc +3 -3
- data/Rakefile +5 -0
- data/VERSION.yml +1 -1
- data/lib/connection.rb +2 -250
- data/lib/connection/configuration.rb +88 -0
- data/lib/connection/provider.rb +91 -0
- data/lib/interaction.rb +4 -0
- data/lib/{client.rb → interaction/client.rb} +17 -21
- data/lib/interaction/interactors.rb +70 -0
- data/lib/{listener.rb → interaction/listener.rb} +65 -77
- data/lib/{messaging.rb → interaction/messaging.rb} +20 -48
- data/lib/javaee.rb +164 -0
- data/lib/{jms → javaee}/javaee-1.5.jar +0 -0
- data/lib/{jms → javaee}/jms.jar +0 -0
- data/lib/{jms → javaee}/jsparrow-essential.jar +0 -0
- data/lib/jsparrow.rb +4 -8
- data/sample/sample_queue.rb +2 -2
- data/sample/sample_topic.rb +2 -2
- data/spec/client_spec.rb +4 -4
- data/spec/connection_spec.rb +13 -6
- data/spec/listener_spec.rb +43 -8
- data/spec/messaging_spec.rb +9 -9
- data/spec/spec_helper.rb +34 -18
- metadata +13 -9
- data/lib/jms.rb +0 -14
data/lib/interaction.rb
ADDED
@@ -1,18 +1,15 @@
|
|
1
|
-
# Classes Java usadas nesse arquivo
|
2
1
|
import 'javax.naming.InitialContext'
|
3
2
|
|
4
3
|
module JSparrow
|
5
|
-
module
|
6
|
-
|
4
|
+
module Interactors
|
5
|
+
|
7
6
|
#
|
8
|
-
#
|
9
|
-
# que prove o servico JMS.
|
7
|
+
# Client to send and receive messages to/from the JMS provider.
|
10
8
|
#
|
11
9
|
class Client
|
12
10
|
def initialize(connection)
|
13
11
|
@connection = connection
|
14
|
-
|
15
|
-
# Conexoes, filas, topicos, senders e receivers que serao habilitados
|
12
|
+
|
16
13
|
@connection_factories = {}
|
17
14
|
@queues = {}
|
18
15
|
@queue_senders = {}
|
@@ -21,21 +18,21 @@ module JSparrow
|
|
21
18
|
@topic_senders = {}
|
22
19
|
@topic_receivers = {}
|
23
20
|
end
|
24
|
-
|
21
|
+
|
25
22
|
def is_started?
|
26
23
|
@connection.is_opened?
|
27
24
|
end
|
28
|
-
|
25
|
+
|
29
26
|
def start
|
30
27
|
@connection.open
|
31
|
-
|
28
|
+
|
32
29
|
@connection_factories, @queues, @topics = lookup_resources
|
33
30
|
end
|
34
|
-
|
31
|
+
|
35
32
|
def is_stoped?
|
36
33
|
@connection.is_closed?
|
37
34
|
end
|
38
|
-
|
35
|
+
|
39
36
|
def stop
|
40
37
|
@connection.close
|
41
38
|
end
|
@@ -43,10 +40,10 @@ module JSparrow
|
|
43
40
|
def queue_enabled?(queue_name)
|
44
41
|
@connection.configuration.enabled_queues.include?(queue_name)
|
45
42
|
end
|
46
|
-
|
43
|
+
|
47
44
|
def queue(queue_name)
|
48
45
|
raise NameError, "Queue '#{queue_name}' does not exist." unless queue_enabled?(queue_name)
|
49
|
-
|
46
|
+
|
50
47
|
@queues[queue_name]
|
51
48
|
end
|
52
49
|
|
@@ -63,10 +60,10 @@ module JSparrow
|
|
63
60
|
def topic_enabled?(topic_name)
|
64
61
|
@connection.configuration.enabled_topics.include?(topic_name)
|
65
62
|
end
|
66
|
-
|
63
|
+
|
67
64
|
def topic(topic_name)
|
68
65
|
raise NameError, "Topic '#{topic_name}' does not exist." unless topic_enabled?(topic_name)
|
69
|
-
|
66
|
+
|
70
67
|
@topics[topic_name]
|
71
68
|
end
|
72
69
|
|
@@ -79,23 +76,22 @@ module JSparrow
|
|
79
76
|
@topic_receivers[topic_name] ||=
|
80
77
|
Messaging::Receiver.new(topic_connection_factory, topic(topic_name))
|
81
78
|
end
|
82
|
-
|
83
|
-
# -- Private methods -- #
|
79
|
+
|
84
80
|
private
|
85
81
|
|
86
82
|
def queue_connection_factory
|
87
83
|
@connection_factories[:queue_connection_factory]
|
88
84
|
end
|
89
|
-
|
85
|
+
|
90
86
|
def topic_connection_factory
|
91
87
|
@connection_factories[:topic_connection_factory]
|
92
88
|
end
|
93
|
-
|
89
|
+
|
94
90
|
def lookup_resources
|
95
91
|
lookuped_connection_factories = @connection.lookup_resources(@connection.configuration.enabled_connection_factories)
|
96
92
|
lookuped_queues = @connection.lookup_resources(@connection.configuration.enabled_queues)
|
97
93
|
lookuped_topic = @connection.lookup_resources(@connection.configuration.enabled_topics)
|
98
|
-
|
94
|
+
|
99
95
|
return lookuped_connection_factories, lookuped_queues, lookuped_topic
|
100
96
|
end
|
101
97
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module JSparrow
|
2
|
+
module Interactors
|
3
|
+
|
4
|
+
#
|
5
|
+
# Class methods to build interactors (Client and Listener).
|
6
|
+
#
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def new_client
|
10
|
+
Client.new(new_connection)
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Example:
|
15
|
+
#
|
16
|
+
# new_listener :as => ListenerClass
|
17
|
+
#
|
18
|
+
# ou
|
19
|
+
#
|
20
|
+
# new_listener(
|
21
|
+
# :listen_to => { :queue => :registered_name_of_queue },
|
22
|
+
# :receive_only_in_criteria => { :selector => "recipient = 'jsparrow-spec'" }
|
23
|
+
# ) do |received_message|
|
24
|
+
|
25
|
+
# # do something
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
def new_listener(listener_spec, &on_receive_message)
|
29
|
+
is_anonymous_listener = listener_spec[:as].nil?
|
30
|
+
|
31
|
+
if is_anonymous_listener
|
32
|
+
new_anonymous_listener(listener_spec, &on_receive_message)
|
33
|
+
else
|
34
|
+
new_named_listener(listener_spec)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def new_named_listener(listener_spec)
|
41
|
+
listener_spec[:as].new(new_connection)
|
42
|
+
end
|
43
|
+
|
44
|
+
def new_anonymous_listener(listener_spec, &on_receive_message)
|
45
|
+
listener = Listener.new(new_connection)
|
46
|
+
|
47
|
+
(class << listener; self; end;).class_eval do
|
48
|
+
listen_to listener_spec[:listen_to] if listener_spec[:listen_to]
|
49
|
+
receive_only_in_criteria listener_spec[:receive_only_in_criteria] if listener_spec[:receive_only_in_criteria]
|
50
|
+
|
51
|
+
define_method(:on_receive_message, &on_receive_message)
|
52
|
+
end
|
53
|
+
|
54
|
+
listener
|
55
|
+
end
|
56
|
+
|
57
|
+
def new_connection
|
58
|
+
JSparrow::Connection.new
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def new_jsparrow_client
|
65
|
+
JSparrow::Interactors.new_client
|
66
|
+
end
|
67
|
+
|
68
|
+
def new_jsparrow_listener(listener_spec, &on_receive_message)
|
69
|
+
JSparrow::Interactors.new_listener(listener_spec, &on_receive_message)
|
70
|
+
end
|
@@ -3,41 +3,52 @@ import 'javax.naming.InitialContext'
|
|
3
3
|
import 'javax.jms.MessageListener'
|
4
4
|
|
5
5
|
module JSparrow
|
6
|
-
module
|
7
|
-
|
8
|
-
#
|
9
|
-
# Ouvintes de mensagens.
|
6
|
+
module Interactors
|
7
|
+
|
10
8
|
#
|
11
|
-
#
|
9
|
+
# Message listener.
|
12
10
|
#
|
13
11
|
class Listener
|
14
12
|
include MessageListener
|
15
|
-
|
16
|
-
#
|
17
|
-
# Nome (configurado no setup da conexao) do destino JMS que sera escutado.
|
18
|
-
#
|
19
|
-
# Invariavelmente deve ser usado pelas subclasses, para informar o nome da queue
|
20
|
-
# ou topico que sera escutado.
|
21
|
-
#
|
22
|
-
# listen_to :queue => :registered_name_of_queue
|
23
|
-
# listen_to :topic => :registered_name_of_topic
|
24
|
-
#
|
25
|
-
def self.listen_to(destination)
|
26
|
-
configure(:listen_to_destination, destination)
|
27
|
-
end
|
28
|
-
|
29
|
-
#
|
30
|
-
# Criterios de selecao de mensagens, seguindo o padrao JMS.
|
31
|
-
#
|
32
|
-
# Invariavelmente as subclasses precisam usar esse metodo, se quiserem definir
|
33
|
-
# os criterios de recebimento que este listener levara em conta.
|
34
|
-
#
|
35
|
-
# receive_only_in_criteria :selector => "recipient = 'jsparrow-spec' and to_listener = 'TestQueueListener'"
|
13
|
+
|
36
14
|
#
|
37
|
-
|
38
|
-
|
15
|
+
# Class methods to configure subclasses.
|
16
|
+
#
|
17
|
+
class << self
|
18
|
+
#
|
19
|
+
# Name (configured in connection setup) of JMS destination to listen to.
|
20
|
+
#
|
21
|
+
# Must be used by subclasses to configure destination.
|
22
|
+
#
|
23
|
+
# listen_to :queue => :registered_name_of_queue
|
24
|
+
# listen_to :topic => :registered_name_of_topic
|
25
|
+
#
|
26
|
+
def listen_to(destination)
|
27
|
+
configure(:listen_to_destination, destination)
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Selector criteria to receive the messages, following the JMS pattern.
|
32
|
+
#
|
33
|
+
# Should be used by subclasses when want to set criterias to message selection.
|
34
|
+
#
|
35
|
+
# receive_only_in_criteria :selector => "recipient = 'jsparrow-spec' and to_listener = 'TestQueueListener'"
|
36
|
+
#
|
37
|
+
def receive_only_in_criteria(criteria = {:selector => ''})
|
38
|
+
configure(:criteria_to_receiving, criteria)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def configure(attribute, value)
|
44
|
+
instance_eval do
|
45
|
+
send(:define_method, attribute) do
|
46
|
+
value
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
39
50
|
end
|
40
|
-
|
51
|
+
|
41
52
|
def initialize(connection)
|
42
53
|
@connection = connection
|
43
54
|
end
|
@@ -46,99 +57,76 @@ module JSparrow
|
|
46
57
|
@connection.is_opened?
|
47
58
|
end
|
48
59
|
|
49
|
-
#
|
50
|
-
# Inicia a escuta de mensagens.
|
51
|
-
#
|
52
60
|
def start_listening
|
53
61
|
@connection.open
|
54
|
-
|
62
|
+
|
55
63
|
connection_factory, destination = lookup_resources
|
56
|
-
|
64
|
+
|
57
65
|
selector = criteria_to_receiving[:selector] if respond_to? :criteria_to_receiving
|
58
|
-
|
59
|
-
# Cria uma conexao para escuta de mensagens
|
66
|
+
|
60
67
|
@listening_connection = connection_factory.create_connection
|
61
|
-
|
62
|
-
# Cria uma sessao e um consumidor de qualquer tipo de mensagem
|
68
|
+
|
63
69
|
session = @listening_connection.create_session(false, Session::AUTO_ACKNOWLEDGE)
|
64
70
|
consumer = session.create_consumer(destination, selector)
|
65
|
-
|
66
|
-
# Registra-se como ouvinte
|
71
|
+
|
67
72
|
consumer.message_listener = self
|
68
|
-
|
69
|
-
# Inicia a escuta de mensagens
|
73
|
+
|
70
74
|
@listening_connection.start
|
71
75
|
end
|
72
|
-
|
73
|
-
#
|
74
|
-
# Finaliza a escuta de mensagens.
|
75
|
-
#
|
76
|
+
|
76
77
|
def stop_listening
|
77
78
|
@listening_connection.close
|
78
|
-
|
79
|
+
|
79
80
|
@connection.close
|
80
81
|
end
|
81
|
-
|
82
|
-
#
|
83
|
-
# Faz o enriquecimento do objeto mensagem e delega para o metodo on_receive_message
|
84
|
-
# que, implementado pelas subclasses, efetivamente trata a mensagem.
|
82
|
+
|
85
83
|
#
|
86
|
-
#
|
84
|
+
# It's part of JMS Listener interface. Shouldn't be overrided by subclasses.
|
87
85
|
#
|
88
86
|
def on_message(received_message)
|
89
87
|
class << received_message
|
90
|
-
include
|
88
|
+
include JMS::Message::TypingMethods
|
91
89
|
end
|
92
|
-
|
90
|
+
|
93
91
|
on_receive_message(received_message)
|
94
92
|
end
|
95
|
-
|
93
|
+
|
96
94
|
#
|
97
|
-
#
|
98
|
-
# definido para este listener (na variavel de instancia @criteria_for_receiving).
|
95
|
+
# Callback mathod to receive enriched messages.
|
99
96
|
#
|
100
|
-
#
|
97
|
+
# Must be overrided by subclasses.
|
101
98
|
#
|
102
99
|
def on_receive_message(received_message)
|
103
100
|
raise Error::AbstractMethodError.new(self.class.superclass, 'on_receive_message')
|
104
101
|
end
|
105
|
-
|
106
|
-
# --- Private methods --- #
|
107
|
-
private
|
108
102
|
|
109
|
-
|
110
|
-
|
111
|
-
send(:define_method, attribute) do
|
112
|
-
value
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
103
|
+
private
|
104
|
+
|
117
105
|
def lookup_resources
|
118
106
|
destination_type, destination_name = get_destination_info
|
119
|
-
|
107
|
+
|
120
108
|
jndi_name_of_connection_factory = get_jndi_name_of_connection_factory(destination_type, destination_name)
|
121
109
|
jndi_name_of_destination = get_jndi_name_of_destination(destination_type, destination_name)
|
122
|
-
|
110
|
+
|
123
111
|
lookuped_connection_factory = @connection.lookup_resource(jndi_name_of_connection_factory)
|
124
112
|
lookuped_destination = @connection.lookup_resource(jndi_name_of_destination)
|
125
|
-
|
113
|
+
|
126
114
|
return lookuped_connection_factory, lookuped_destination
|
127
115
|
end
|
128
|
-
|
116
|
+
|
129
117
|
def get_destination_info
|
130
118
|
return listen_to_destination.keys[0], listen_to_destination.values[0]
|
131
119
|
end
|
132
|
-
|
120
|
+
|
133
121
|
def get_jndi_name_of_connection_factory(destination_type, destination_name)
|
134
122
|
connection_factory_name = "#{destination_type}_connection_factory".to_sym
|
135
|
-
|
123
|
+
|
136
124
|
@connection.configuration.enabled_connection_factories[connection_factory_name]
|
137
125
|
end
|
138
|
-
|
126
|
+
|
139
127
|
def get_jndi_name_of_destination(destination_type, destination_name)
|
140
128
|
enabled_method_for_destinations = "enabled_#{destination_type}s"
|
141
|
-
|
129
|
+
|
142
130
|
@connection.configuration.send(enabled_method_for_destinations)[destination_name]
|
143
131
|
end
|
144
132
|
end
|
@@ -1,30 +1,25 @@
|
|
1
|
-
# Classes Java usadas nesse arquivo
|
2
1
|
import 'javax.jms.Session'
|
3
2
|
|
4
3
|
module JSparrow
|
5
4
|
module Messaging
|
6
5
|
|
7
6
|
#
|
8
|
-
#
|
7
|
+
# Default timeout to receive messages = 1 millisecond.
|
9
8
|
#
|
10
9
|
DEFAULT_RECEIVER_TIMEOUT = 1000
|
11
10
|
|
12
11
|
#
|
13
|
-
#
|
14
|
-
# para filas ou topicos.
|
12
|
+
# Base class to define messangers (for queues and topics).
|
15
13
|
#
|
16
14
|
class Base
|
17
15
|
def initialize(connection_factory, destination)
|
18
|
-
# Fabrica de conexoes JMS
|
19
16
|
@connection_factory = connection_factory
|
20
|
-
|
21
|
-
# Destino JMS para envio ou recebimento de mensagens
|
22
|
-
@destination = destination
|
17
|
+
@destination = destination
|
23
18
|
end
|
24
19
|
end
|
25
20
|
|
26
21
|
#
|
27
|
-
#
|
22
|
+
# Message sender.
|
28
23
|
#
|
29
24
|
class Sender < Base
|
30
25
|
def send_text_message(text)
|
@@ -64,41 +59,41 @@ module JSparrow
|
|
64
59
|
end
|
65
60
|
|
66
61
|
def send_messages(&message_sender)
|
67
|
-
# Cria uma conexao, uma sessao e um emissor de qualquer tipo de mensagem
|
68
62
|
connection = @connection_factory.create_connection
|
69
63
|
session = connection.create_session(true, Session::AUTO_ACKNOWLEDGE)
|
70
64
|
producer = session.create_producer(@destination)
|
71
65
|
|
72
|
-
|
66
|
+
class << session
|
67
|
+
include JMS::Session::OverrideMethods
|
68
|
+
end
|
69
|
+
|
73
70
|
message_sender.call(session, producer)
|
74
71
|
|
75
|
-
# Fecha a conexao
|
76
72
|
connection.close
|
77
73
|
end
|
78
74
|
|
79
|
-
# --- Private methods --- #
|
80
75
|
private
|
81
76
|
|
82
77
|
def send_message(&message_creator)
|
83
|
-
# Cria uma conexao, uma sessao e um emissor de qualquer tipo de mensagem
|
84
78
|
connection = @connection_factory.create_connection
|
85
79
|
session = connection.create_session(true, Session::AUTO_ACKNOWLEDGE)
|
86
80
|
producer = session.create_producer(@destination)
|
87
81
|
|
88
|
-
|
82
|
+
class << session
|
83
|
+
include JMS::Session::OverrideMethods
|
84
|
+
end
|
85
|
+
|
89
86
|
message = message_creator.call(session)
|
90
87
|
|
91
|
-
# Envia a mensagem
|
92
88
|
producer.send(message)
|
93
89
|
|
94
|
-
# Commita a sessao e fecha a conexao
|
95
90
|
session.commit
|
96
91
|
connection.close
|
97
92
|
end
|
98
93
|
end
|
99
94
|
|
100
95
|
#
|
101
|
-
#
|
96
|
+
# Message receiver.
|
102
97
|
#
|
103
98
|
class Receiver < Base
|
104
99
|
def receive_message(criteria_for_receiving = {:timeout => DEFAULT_RECEIVER_TIMEOUT, :selector => ''}, &message_handler)
|
@@ -109,56 +104,33 @@ module JSparrow
|
|
109
104
|
receive(:many_messages, criteria_for_receiving, &message_handler)
|
110
105
|
end
|
111
106
|
|
112
|
-
# --- Private methods --- #
|
113
107
|
private
|
114
108
|
|
115
109
|
def receive(how_much_messages, criteria_for_receiving, &message_handler)
|
116
|
-
# Cria uma conexao, uma sessao e um consumidor de qualquer tipo de mensagem
|
117
110
|
connection = @connection_factory.create_connection
|
118
111
|
session = connection.create_session(false, Session::AUTO_ACKNOWLEDGE)
|
119
|
-
|
112
|
+
|
113
|
+
class << session
|
114
|
+
include JMS::Session::OverrideMethods
|
115
|
+
end
|
116
|
+
|
117
|
+
consumer = session.create_consumer(@destination, criteria_for_receiving[:selector])
|
120
118
|
|
121
|
-
# Prepara a conexao para receber mensagens
|
122
119
|
connection.start
|
123
120
|
|
124
|
-
# Inicia o recebimento de mensagens
|
125
121
|
timeout = criteria_for_receiving[:timeout] || DEFAULT_RECEIVER_TIMEOUT
|
126
122
|
|
127
|
-
#
|
123
|
+
# One message (if) or many masseges (while)
|
128
124
|
conditional_keyword = (how_much_messages.eql? :one_message) ? 'if' : 'while'
|
129
125
|
|
130
126
|
eval %Q{
|
131
127
|
#{conditional_keyword} (received_message = consumer.receive(timeout))
|
132
|
-
# Inclui o modulo de identificacao de mensagem, util para o message_handler
|
133
|
-
class << received_message
|
134
|
-
include MessageType
|
135
|
-
end
|
136
|
-
|
137
|
-
# Delega o tratamento da mensagem para o bloco recebido
|
138
128
|
message_handler.call(received_message)
|
139
129
|
end
|
140
130
|
}
|
141
131
|
|
142
|
-
# Fecha a conexao
|
143
132
|
connection.close
|
144
133
|
end
|
145
134
|
end
|
146
|
-
|
147
|
-
#
|
148
|
-
# Identifica o tipo de uma mensagem.
|
149
|
-
#
|
150
|
-
module MessageType
|
151
|
-
def is_text_message?
|
152
|
-
respond_to? :get_text
|
153
|
-
end
|
154
|
-
|
155
|
-
def is_object_message?
|
156
|
-
(respond_to? :get_object and !(respond_to? :get_long))
|
157
|
-
end
|
158
|
-
|
159
|
-
def is_map_message?
|
160
|
-
respond_to? :get_long
|
161
|
-
end
|
162
|
-
end
|
163
135
|
end
|
164
136
|
end
|