jsparrow 1.1.1 → 1.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/README.rdoc CHANGED
@@ -70,7 +70,7 @@ jsparrow rocks! =)
70
70
 
71
71
  Or, if you don't want write code, only do it:
72
72
 
73
- jruby sample/sample.rb
73
+ jruby sample/sample_queue.rb
74
74
 
75
75
  == Copyright
76
76
 
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
- :patch: 1
3
2
  :major: 1
4
- :build:
5
3
  :minor: 1
4
+ :patch: 2
5
+ :build:
data/lib/client.rb CHANGED
@@ -9,9 +9,8 @@ module JSparrow
9
9
  # que prove o servico JMS.
10
10
  #
11
11
  class Client
12
- def initialize(connection_config, jndi_context_builder)
13
- @connection_config = connection_config
14
- @jndi_context_builder = jndi_context_builder
12
+ def initialize(connection)
13
+ @connection = connection
15
14
 
16
15
  # Conexoes, filas, topicos, senders e receivers que serao habilitados
17
16
  @connection_factories = {}
@@ -21,51 +20,28 @@ module JSparrow
21
20
  @topics = {}
22
21
  @topic_senders = {}
23
22
  @topic_receivers = {}
24
-
25
- # Foi iniciado?
26
- @started = false
27
23
  end
28
24
 
29
25
  def is_started?
30
- @started
26
+ @connection.is_opened?
31
27
  end
32
28
 
33
29
  def start
34
- raise InvalidClientStateError.new('started', 'start') if is_started?
35
-
36
- begin
37
- @jndi_context = @jndi_context_builder.build
38
- rescue => cause
39
- raise ClientInitializationError.new(@connection_config, cause)
40
- end
30
+ @connection.open
41
31
 
42
32
  @connection_factories, @queues, @topics = lookup_resources
43
-
44
- @started = true
45
33
  end
46
34
 
47
35
  def is_stoped?
48
- !@started
36
+ @connection.is_closed?
49
37
  end
50
38
 
51
39
  def stop
52
- raise InvalidClientStateError.new('stoped', 'stop') if is_stoped?
53
-
54
- @jndi_context.close
55
-
56
- @started = false
57
- end
58
-
59
- def queue_connection_factory_enabled?
60
- @connection_config.enabled_connection_factories.include?(:queue_connection_factory)
40
+ @connection.close
61
41
  end
62
42
 
63
- def queue_connection_factory
64
- @connection_factories[:queue_connection_factory]
65
- end
66
-
67
43
  def queue_enabled?(queue_name)
68
- @connection_config.enabled_queues.include?(queue_name)
44
+ @connection.configuration.enabled_queues.include?(queue_name)
69
45
  end
70
46
 
71
47
  def queue(queue_name)
@@ -84,16 +60,8 @@ module JSparrow
84
60
  Messaging::Receiver.new(queue_connection_factory, queue(queue_name))
85
61
  end
86
62
 
87
- def topic_connection_factory_enabled?
88
- @connection_config.enabled_connection_factories.include?(:topic_connection_factory)
89
- end
90
-
91
- def topic_connection_factory
92
- @connection_factories[:topic_connection_factory]
93
- end
94
-
95
63
  def topic_enabled?(topic_name)
96
- @connection_config.enabled_topics.include?(topic_name)
64
+ @connection.configuration.enabled_topics.include?(topic_name)
97
65
  end
98
66
 
99
67
  def topic(topic_name)
@@ -115,47 +83,21 @@ module JSparrow
115
83
  # -- Private methods -- #
116
84
  private
117
85
 
118
- def lookup_resources
119
- @lookuped_connection_factories = lookup_resource(@connection_config.enabled_connection_factories)
120
- @lookuped_queues = lookup_resource(@connection_config.enabled_queues)
121
- @lookuped_topic = lookup_resource(@connection_config.enabled_topics)
122
-
123
- return @lookuped_connection_factories, @lookuped_queues, @lookuped_topic
86
+ def queue_connection_factory
87
+ @connection_factories[:queue_connection_factory]
124
88
  end
125
89
 
126
- def lookup_resource(jndi_names = {})
127
- lookuped = {}
128
-
129
- return lookuped unless jndi_names
130
-
131
- jndi_names.each do |key, jndi_name|
132
- lookuped[key] = @jndi_context.lookup(jndi_name)
133
- end
134
-
135
- lookuped
90
+ def topic_connection_factory
91
+ @connection_factories[:topic_connection_factory]
136
92
  end
137
- end
138
-
139
- class ClientInitializationError < StandardError
140
- attr_reader :config, :cause
141
-
142
- def initialize(config, cause)
143
- super("Could not open connection to server. Verify the config's config.")
144
-
145
- @config = config
146
- @cause = cause
147
- end
148
- end
149
-
150
- class InvalidClientStateError < StandardError
151
- attr_reader :state, :operation
152
93
 
153
- def initialize(state, operation)
154
- super("Could not did #{operation} because client is #{state}.")
155
-
156
- @state = state
157
- @operation = operation
158
- end
94
+ def lookup_resources
95
+ lookuped_connection_factories = @connection.lookup_resources(@connection.configuration.enabled_connection_factories)
96
+ lookuped_queues = @connection.lookup_resources(@connection.configuration.enabled_queues)
97
+ lookuped_topic = @connection.lookup_resources(@connection.configuration.enabled_topics)
98
+
99
+ return lookuped_connection_factories, lookuped_queues, lookuped_topic
100
+ end
159
101
  end
160
102
  end
161
103
  end
data/lib/connection.rb CHANGED
@@ -9,27 +9,97 @@ module JSparrow
9
9
  # Metodo usado para configurar a conexao com o provedor de JMS.
10
10
  #
11
11
  def self.configure
12
- @@config = Configuration.new
12
+ @@configuration = Configuration.new
13
13
 
14
- yield @@config
14
+ yield @@configuration
15
15
 
16
- @@config
16
+ @@jndi_context_builder = JNDI::ContextBuilder.new(@@configuration.jms_client_jar, @@configuration.jndi_properties)
17
+
18
+ @@configuration
17
19
  end
18
20
 
19
21
  #
20
22
  # Metodo usado para obter a configuracao para conexao com o provedor de JMS.
21
23
  #
22
24
  def self.configuration
23
- @@config
25
+ @@configuration
24
26
  end
25
27
 
26
28
  #
27
29
  # Metodo usado para criar um novo Client JMS.
28
30
  #
29
31
  def self.new_client
30
- jndi_context_builder = JNDI::ContextBuilder.new(@@config.jms_client_jar, @@config.jndi_properties)
32
+ connection = Base.new(@@configuration, @@jndi_context_builder)
33
+
34
+ Client.new(connection)
35
+ end
36
+
37
+ #
38
+ # Metodo usado para criar um novo Listener de mensagens JMS.
39
+ #
40
+ def self.new_listener(listener_spec)
41
+ connection = Base.new(@@configuration, @@jndi_context_builder)
31
42
 
32
- Client.new(@@config, jndi_context_builder)
43
+ listener_spec[:as].new(connection)
44
+ end
45
+
46
+ #
47
+ # Classe base para estabelecer conexao com o provedor JMS via JNDI.
48
+ #
49
+ class Base
50
+ attr_reader :configuration
51
+
52
+ def initialize(configuration, jndi_context_builder)
53
+ @configuration = configuration
54
+ @jndi_context_builder = jndi_context_builder
55
+
56
+ # Foi estabelecida?
57
+ @opened = false
58
+ end
59
+
60
+ def is_opened?
61
+ @opened
62
+ end
63
+
64
+ def open
65
+ raise InvalidStateError.new('opened', 'open') if is_opened?
66
+
67
+ begin
68
+ @jndi_context = @jndi_context_builder.build
69
+ rescue => cause
70
+ raise InitializationError.new(@configuration, cause)
71
+ end
72
+
73
+ @opened = true
74
+ end
75
+
76
+ def is_closed?
77
+ not @opened
78
+ end
79
+
80
+ def close
81
+ raise InvalidStateError.new('closed', 'close') if is_closed?
82
+
83
+ @jndi_context.close
84
+
85
+ @opened = false
86
+ end
87
+
88
+ def lookup_resources(resources = {})
89
+ lookuped_resource = {}
90
+
91
+ return lookuped_resource unless resources
92
+
93
+ resources.each do |name, jndi_name|
94
+ lookuped_resource[name] = lookup_resource(jndi_name)
95
+ end
96
+
97
+ lookuped_resource
98
+ end
99
+
100
+ def lookup_resource(jndi_name)
101
+ @jndi_context.lookup(jndi_name)
102
+ end
33
103
  end
34
104
 
35
105
  #
@@ -40,26 +110,83 @@ module JSparrow
40
110
  attr_reader :jms_client_jar, :jndi_properties,
41
111
  :enabled_connection_factories, :enabled_queues, :enabled_topics
42
112
 
113
+ #
114
+ # Use:
115
+ #
116
+ # use_jms_client_jar "path/to/name_of_the_client_jar_file.jar"
117
+ #
43
118
  def use_jms_client_jar(client_jar)
44
119
  @jms_client_jar = client_jar
45
120
  end
46
121
 
122
+ #
123
+ # Use:
124
+ #
125
+ # use_jndi_properties :a_jndi_property_name_in_lower_case => "a_value_of_property",
126
+ # :other_jndi_property_name_in_lower_case => "other_value_of_property"
127
+ #
47
128
  def use_jndi_properties(jndi_properties = {})
48
129
  @jndi_properties = jndi_properties
49
130
  end
50
131
 
132
+ #
133
+ # Use:
134
+ #
135
+ # enable_connection_factories :queue_connection_factory => "jndi_name_of_queue_connection_factory",
136
+ # :topic_connection_factory => "jndi_name_of_topic_connection_factory"
137
+ #
51
138
  def enable_connection_factories(jndi_names = {})
52
139
  @enabled_connection_factories = jndi_names
53
140
  end
54
141
 
142
+ #
143
+ # Use:
144
+ #
145
+ # enable_queues :a_queue_name_in_lower_case => "jndi_name_of_a_queue",
146
+ # :other_queue_name_in_lower_case => "jndi_name_of_other_queue"
147
+ #
55
148
  def enable_queues(jndi_names = {})
56
149
  @enabled_queues = jndi_names
57
150
  end
58
151
 
152
+ #
153
+ # Use:
154
+ #
155
+ # enable_topics :a_topic_name_in_lower_case => "jndi_name_of_a_topic",
156
+ # :other_topic_name_in_lower_case => "jndi_name_of_other_topic"
157
+ #
59
158
  def enable_topics(jndi_names = {})
60
159
  @enabled_topics = jndi_names
61
160
  end
62
161
  end
162
+
163
+ #
164
+ # Erro para quando uma conexao esta num estado invalido para uma operacao (open ou close).
165
+ #
166
+ class InvalidStateError < StandardError
167
+ attr_reader :state, :operation
168
+
169
+ def initialize(state, operation)
170
+ super("Could not did #{operation} because connection is #{state}.")
171
+
172
+ @state = state
173
+ @operation = operation
174
+ end
175
+ end
176
+
177
+ #
178
+ # Erro para quando nao for possivel estabelecer conexao com o provedor JMS.
179
+ #
180
+ class InitializationError < StandardError
181
+ attr_reader :configuration, :cause
182
+
183
+ def initialize(configuration, cause)
184
+ super("Could not open connection to JMS provider. Verify the config's config.")
185
+
186
+ @configuration = configuration
187
+ @cause = cause
188
+ end
189
+ end
63
190
  end
64
191
 
65
192
  module JNDI
data/lib/jsparrow.rb CHANGED
@@ -6,5 +6,6 @@ require 'jms.rb'
6
6
  # Bibliotecas do JSparrow
7
7
  require 'connection.rb'
8
8
  require 'client.rb'
9
+ require 'listener.rb'
9
10
  require 'messaging.rb'
10
11
  require 'error.rb'
data/lib/listener.rb ADDED
@@ -0,0 +1,146 @@
1
+ # Classes Java usadas nesse arquivo
2
+ import 'javax.naming.InitialContext'
3
+ import 'javax.jms.MessageListener'
4
+
5
+ module JSparrow
6
+ module Connection
7
+
8
+ #
9
+ # Ouvintes de mensagens.
10
+ #
11
+ # Sao como clientes JMS, mas apenas para recebimento de mensagens.
12
+ #
13
+ class Listener
14
+ 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'"
36
+ #
37
+ def self.receive_only_in_criteria(criteria = {:selector => ''})
38
+ configure(:criteria_to_receiving, criteria)
39
+ end
40
+
41
+ def initialize(connection)
42
+ @connection = connection
43
+ end
44
+
45
+ def is_listening?
46
+ @connection.is_opened?
47
+ end
48
+
49
+ #
50
+ # Inicia a escuta de mensagens.
51
+ #
52
+ def start_listening
53
+ @connection.open
54
+
55
+ connection_factory, destination = lookup_resources
56
+
57
+ selector = criteria_to_receiving[:selector] if respond_to? :criteria_to_receiving
58
+
59
+ # Cria uma conexao para escuta de mensagens
60
+ @listening_connection = connection_factory.create_connection
61
+
62
+ # Cria uma sessao e um consumidor de qualquer tipo de mensagem
63
+ session = @listening_connection.create_session(false, Session::AUTO_ACKNOWLEDGE)
64
+ consumer = session.create_consumer(destination, selector)
65
+
66
+ # Registra-se como ouvinte
67
+ consumer.message_listener = self
68
+
69
+ # Inicia a escuta de mensagens
70
+ @listening_connection.start
71
+ end
72
+
73
+ #
74
+ # Finaliza a escuta de mensagens.
75
+ #
76
+ def stop_listening
77
+ @listening_connection.close
78
+
79
+ @connection.close
80
+ 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.
85
+ #
86
+ # Nao deve ser re-implementado por subclasses.
87
+ #
88
+ def on_message(received_message)
89
+ class << received_message
90
+ include Messaging::MessageType
91
+ end
92
+
93
+ on_receive_message(received_message)
94
+ end
95
+
96
+ #
97
+ # E executado todas as vezes que chega uma mensagem que atenda aos criterios
98
+ # definido para este listener (na variavel de instancia @criteria_for_receiving).
99
+ #
100
+ # Invariavelmente deve ser re-implementado nas subclasses.
101
+ #
102
+ def on_receive_message(received_message)
103
+ raise Error::AbstractMethodError.new(self.class.superclass, 'on_receive_message')
104
+ end
105
+
106
+ # --- Private methods --- #
107
+ private
108
+
109
+ def self.configure(attribute, value)
110
+ self.instance_eval do
111
+ send(:define_method, attribute) do
112
+ value
113
+ end
114
+ end
115
+ end
116
+
117
+ def lookup_resources
118
+ destination_type, destination_name = get_destination_info
119
+
120
+ jndi_name_of_connection_factory = get_jndi_name_of_connection_factory(destination_type, destination_name)
121
+ jndi_name_of_destination = get_jndi_name_of_destination(destination_type, destination_name)
122
+
123
+ lookuped_connection_factory = @connection.lookup_resource(jndi_name_of_connection_factory)
124
+ lookuped_destination = @connection.lookup_resource(jndi_name_of_destination)
125
+
126
+ return lookuped_connection_factory, lookuped_destination
127
+ end
128
+
129
+ def get_destination_info
130
+ return listen_to_destination.keys[0], listen_to_destination.values[0]
131
+ end
132
+
133
+ def get_jndi_name_of_connection_factory(destination_type, destination_name)
134
+ connection_factory_name = "#{destination_type}_connection_factory".to_sym
135
+
136
+ @connection.configuration.enabled_connection_factories[connection_factory_name]
137
+ end
138
+
139
+ def get_jndi_name_of_destination(destination_type, destination_name)
140
+ enabled_method_for_destinations = "enabled_#{destination_type}s"
141
+
142
+ @connection.configuration.send(enabled_method_for_destinations)[destination_name]
143
+ end
144
+ end
145
+ end
146
+ end
data/lib/messaging.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # Classes Java usadas nesse arquivo
2
2
  import 'javax.jms.Session'
3
- import 'javax.jms.MessageListener'
4
3
 
5
4
  module JSparrow
6
5
  module Messaging
@@ -80,22 +79,22 @@ module JSparrow
80
79
  # --- Private methods --- #
81
80
  private
82
81
 
83
- def send_message(&message_creator)
84
- # Cria uma conexao, uma sessao e um emissor de qualquer tipo de mensagem
85
- connection = @connection_factory.create_connection
86
- session = connection.create_session(true, Session::AUTO_ACKNOWLEDGE)
87
- producer = session.create_producer(@destination)
82
+ def send_message(&message_creator)
83
+ # Cria uma conexao, uma sessao e um emissor de qualquer tipo de mensagem
84
+ connection = @connection_factory.create_connection
85
+ session = connection.create_session(true, Session::AUTO_ACKNOWLEDGE)
86
+ producer = session.create_producer(@destination)
88
87
 
89
- # Obtem uma mensagem (TextMessage, ObjectMessage ou MapMessage) do criador especifico
90
- message = message_creator.call(session)
88
+ # Obtem uma mensagem (TextMessage, ObjectMessage ou MapMessage) do criador especifico
89
+ message = message_creator.call(session)
91
90
 
92
- # Envia a mensagem
93
- producer.send(message)
91
+ # Envia a mensagem
92
+ producer.send(message)
94
93
 
95
- # Commita a sessao e fecha a conexao
96
- session.commit
97
- connection.close
98
- end
94
+ # Commita a sessao e fecha a conexao
95
+ session.commit
96
+ connection.close
97
+ end
99
98
  end
100
99
 
101
100
  #
@@ -128,117 +127,22 @@ module JSparrow
128
127
  connection.close
129
128
  end
130
129
  end
131
-
132
- #
133
- # Ouvintes de mensagens.
130
+
134
131
  #
135
- # TODO: Completar a implementacao. Ainda nao esta legal. (Ja dei um tapinha,
136
- # acho que agora ta bem proximo do que deve ser.)
132
+ # Identifica o tipo de uma mensagem.
137
133
  #
138
- class Listener < Base
139
- include MessageListener
140
-
141
- attr_reader :connection_factory_name, :destination_name, :criteria_to_receiving
142
-
143
- #
144
- # Estes parametros serao injetados pelo listener manager de acordo com o
145
- # que houver sido definido pelos metodos connection_factory_name e destination_name.
146
- #
147
- def initialize(connection_factory, destination)
148
- super(connection_factory, destination)
149
-
150
- @connection_factory_name = 'undefined'
151
- @destination_name = 'undefined'
152
- @criteria_to_receiving = {}
153
- end
154
-
155
- #
156
- # Nome JNDI da connection factory que ser usada para criar conexoes JMS.
157
- #
158
- # Invariavelmente deve ser usado pelas subclasses para informar qual devera
159
- # ser a connection factory usada por esse listener.
160
- #
161
- def use_connection_factory(jndi_name)
162
- @connection_factory_name = jndi_name
134
+ module MessageType
135
+ def is_text_message?
136
+ respond_to? :get_text
163
137
  end
164
-
165
- #
166
- # Nome JNDI do destino JMS que sera escutado.
167
- #
168
- # Invariavelmente deve ser usado pelas subclasses, para informar o nome
169
- # da queue ou topico que sera escutado.
170
- #
171
- def listen_to_destination(jndi_name)
172
- @destination_name = jndi_name
173
- end
174
-
175
- #
176
- # Criterios de selecao de mensagens, seguindo o padrao JMS.
177
- #
178
- # Invariavelmente as subclasses precisam usar esse metodo para definir
179
- # os criterios de recebimento que este listener levara em conta.
180
- #
181
- def receive_only_in_criteria(criteria = {:timeout => DEFAULT_RECEIVER_TIMEOUT, :selector => ''})
182
- # Valor default para timeout, caso nao tenha sido informado
183
- @criteria_to_receiving[:timeout] = criteria[:timeout] || DEFAULT_RECEIVER_TIMEOUT
184
- end
185
-
186
- #
187
- # Inicia a escuta de mensagens.
188
- #
189
- def start_listening
190
- # Cria uma conexao, uma sessao e um consumidor de qualquer tipo de mensagem
191
- connection = @connection_factory.create_connection
192
- session = connection.create_session(false, Session::AUTO_ACKNOWLEDGE)
193
- consumer = session.create_consumer(@destination, @criteria_for_receiving[:selector])
194
-
195
- # Registra-se como ouvinte
196
- consumer.message_listener = self
197
-
198
- # Inicia a escuta de mensagens
199
- connection.start
200
- end
201
-
202
- #
203
- # Faz o enriquecimento do objeto mensagem e delega para o metodo on_receive_message
204
- # que, implementado pelas subclasses, efetivamente trata a mensagem.
205
- #
206
- # Nao deve ser re-implementado por subclasses.
207
- #
208
- def on_message(received_message)
209
- class << received_message
210
- include MessageType
211
- end
212
-
213
- on_receive_message(received_message)
214
- end
215
-
216
- #
217
- # E executado todas as vezes que chega uma mensagem que atenda aos criterios
218
- # definido para este listener (na variavel de instancia @criteria_for_receiving).
219
- #
220
- # Invariavelmente deve ser re-implementado nas subclasses.
221
- #
222
- def on_receive_message(received_message)
223
- raise Error::AbstractMethodError.new('on_receive_message')
224
- end
225
- end
226
- end
227
-
228
- #
229
- # Identifica o tipo de uma mensagem.
230
- #
231
- module MessageType
232
- def is_text_message?
233
- respond_to? :get_text
234
- end
235
138
 
236
- def is_object_message?
237
- (respond_to? :get_object and !(respond_to? :get_long))
238
- end
139
+ def is_object_message?
140
+ (respond_to? :get_object and !(respond_to? :get_long))
141
+ end
239
142
 
240
- def is_map_message?
241
- respond_to? :get_long
143
+ def is_map_message?
144
+ respond_to? :get_long
145
+ end
242
146
  end
243
147
  end
244
148
  end
File without changes