redstorm 0.6.3 → 0.6.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/CHANGELOG.md +10 -1
- data/README.md +61 -32
- data/examples/simple/kafka_topology.rb +55 -0
- data/ivy/settings.xml +11 -0
- data/lib/red_storm/application.rb +8 -2
- data/lib/red_storm/loggable.rb +3 -1
- data/lib/red_storm/proxy/bolt.rb +0 -1
- data/lib/red_storm/proxy/spout.rb +0 -1
- data/lib/red_storm/simple_bolt.rb +2 -1
- data/lib/red_storm/simple_spout.rb +2 -1
- data/lib/red_storm/simple_topology.rb +1 -1
- data/lib/red_storm/version.rb +1 -1
- data/lib/tasks/red_storm.rake +134 -84
- metadata +6 -21
- data/examples/simple/Gemfile +0 -2
data/CHANGELOG.md
CHANGED
@@ -62,4 +62,13 @@
|
|
62
62
|
- issue #28, allow specification of output_fields in topology DSL
|
63
63
|
- issue #41, add support for ShellBolt and ShellSpout
|
64
64
|
- issue #49, redstorm bundle not picking up default group in Gemfile
|
65
|
-
- support constructor parameters for Java spout/bolt in topology DSL
|
65
|
+
- support constructor parameters for Java spout/bolt in topology DSL
|
66
|
+
|
67
|
+
# 0.6.4, 10-19-2012
|
68
|
+
- Storm 0.8.1 and JRuby 1.6.8
|
69
|
+
- improved and more flexible jar dependencies handling
|
70
|
+
- issue #36, fix slf4j-api-1.6.3 and slf4j-log4j12-1.5.8 version conflict
|
71
|
+
- issue #37, fix dependencies xml files naming
|
72
|
+
- issue #47, Log4j Logger class conflict
|
73
|
+
- issue #48, add support for external Jars
|
74
|
+
- issue #50, update RedStorm to target Storm 0.8
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
# RedStorm v0.6.
|
1
|
+
# RedStorm v0.6.4 - JRuby on Storm
|
2
2
|
|
3
3
|
[](http://travis-ci.org/colinsurprenant/redstorm)
|
4
4
|
|
5
|
-
RedStorm provides a Ruby DSL using JRuby integration for the [Storm]
|
5
|
+
RedStorm provides a Ruby DSL using JRuby integration for the [Storm](https://github.com/nathanmarz/storm/) distributed realtime computation system.
|
6
6
|
|
7
7
|
## Documentation
|
8
8
|
|
@@ -13,10 +13,11 @@ Chances are new versions of RedStorm will introduce changes that will break comp
|
|
13
13
|
- [RedStorm Gem v0.4.x Documentation](https://github.com/colinsurprenant/redstorm/wiki/RedStorm-Gem-v0.4.x-Documentation)
|
14
14
|
- [RedStorm Gem v0.5.0 Documentation](https://github.com/colinsurprenant/redstorm/wiki/RedStorm-Gem-v0.5.0-Documentation)
|
15
15
|
- [RedStorm Gem v0.5.1 Documentation](https://github.com/colinsurprenant/redstorm/wiki/RedStorm-Gem-v0.5.1-Documentation)
|
16
|
+
- [RedStorm Gem v0.6.3 Documentation](https://github.com/colinsurprenant/redstorm/wiki/RedStorm-Gem-v0.6.3-Documentation)
|
16
17
|
|
17
18
|
## Dependencies
|
18
19
|
|
19
|
-
Tested on OSX 10.
|
20
|
+
Tested on **OSX 10.8.2** and **Linux 12.04** using **Storm 0.8.1** and **JRuby 1.6.8** and **OpenJDK 7**
|
20
21
|
|
21
22
|
## Notes about 1.8/1.9 JRuby compatibility
|
22
23
|
|
@@ -58,7 +59,7 @@ $ redstorm local|cluster [--1.8|--1.9] ...
|
|
58
59
|
|
59
60
|
``` ruby
|
60
61
|
source :rubygems
|
61
|
-
gem "redstorm", "~> 0.6.
|
62
|
+
gem "redstorm", "~> 0.6.4"
|
62
63
|
```
|
63
64
|
|
64
65
|
## Usage overview
|
@@ -81,7 +82,7 @@ or if your default JRuby mode is 1.8 but you want to use 1.9 for your topology d
|
|
81
82
|
$ jruby --1.9 -S redstorm install
|
82
83
|
```
|
83
84
|
|
84
|
-
This will basically install
|
85
|
+
This will basically install default Java jar dependencies in `target/dependency`, generate & compile the Java bindings in `target/classes`.
|
85
86
|
|
86
87
|
### Create a topology
|
87
88
|
|
@@ -113,6 +114,42 @@ Basically, the `redstorm bundle` command copy the gems specified in the Gemfile
|
|
113
114
|
|
114
115
|
This has an important consequence: the gems will not be *installed* on the cluster target machines, they are already *installed* in the jar file. This **could lead to problems** if the machine used to *install* the gems is of a different architecture than the cluster target machines **and** some of these gems have **C or FFI** extensions.
|
115
116
|
|
117
|
+
### Custom Jar dependencies in your topology
|
118
|
+
|
119
|
+
By defaut, RedStorm installs Storm and JRuby jars dependencies. If you require custom dependencies, these can be specified by creating the `Dependencies` file in the root of your project. Note that this file overwrites the defaults dependencies so you must also include the Storm and JRuby dependencies. Here's an example of a `Dependencies` file which included the jars required to run the `KafkaTopology` in the examples.
|
120
|
+
|
121
|
+
``` ruby
|
122
|
+
{
|
123
|
+
:storm_artifacts => [
|
124
|
+
"storm:storm:0.8.1, transitive=true",
|
125
|
+
],
|
126
|
+
:topology_artifacts => [
|
127
|
+
"org.jruby:jruby-complete:1.6.8, transitive=false",
|
128
|
+
"org.scala-lang:scala-library:2.8.0, transitive=false",
|
129
|
+
"storm:kafka:0.7.0-incubating, transitive=false",
|
130
|
+
"storm:storm-kafka:0.8.0-wip4, transitive=false",
|
131
|
+
],
|
132
|
+
}
|
133
|
+
```
|
134
|
+
|
135
|
+
Basically the dependendencies are speified as Maven artifacts. There are two sections, the `:storm_artifacts =>` contains the dependencies for running storm in local mode and the `:topology_artifacts =>` are the dependencies specific for your topology. The format is self explainatory and the attribute `transitive=[true|false]` controls the recursive dependencies resolution (using `true`).
|
136
|
+
|
137
|
+
The jars repositories can be configured by adding the `ivy/setting.xml` file in the root of your project. For information on the Ivy settings format, see the [Ivy Settings Documentation](http://ant.apache.org/ivy/history/2.2.0/settings.html). I will try my best to eliminate all XML :) but for now I haven't figured how to get rid of this one. For an example Ivy settings file, RedStorm is using the following settings by default:
|
138
|
+
|
139
|
+
``` xml
|
140
|
+
<ivysettings>
|
141
|
+
<settings defaultResolver="repositories"/>
|
142
|
+
<resolvers>
|
143
|
+
<chain name="repositories">
|
144
|
+
<ibiblio name="ibiblio" m2compatible="true"/>
|
145
|
+
<ibiblio name="maven2" root="http://repo.maven.apache.org/maven2/" m2compatible="true"/>
|
146
|
+
<ibiblio name="sonatype" root="http://repo.maven.apache.org/maven2/" m2compatible="true"/>
|
147
|
+
<ibiblio name="clojars" root="http://clojars.org/repo/" m2compatible="true"/>
|
148
|
+
</chain>
|
149
|
+
</resolvers>
|
150
|
+
</ivysettings>
|
151
|
+
```
|
152
|
+
|
116
153
|
### Run in local mode
|
117
154
|
|
118
155
|
``` sh
|
@@ -125,7 +162,7 @@ By defaut, a topology will be executed in the **same mode** as the interpreter r
|
|
125
162
|
|
126
163
|
### Run on production cluster
|
127
164
|
|
128
|
-
1. download and unpack the [Storm 0.
|
165
|
+
1. download and unpack the [Storm 0.8.1 distribution](https://github.com/downloads/nathanmarz/storm/storm-0.8.1.zip) locally and **add** the Storm `bin/` directory to your `$PATH`.
|
129
166
|
|
130
167
|
2. generate `target/cluster-topology.jar`. This jar file will include your sources directory plus the required dependencies
|
131
168
|
|
@@ -158,14 +195,14 @@ All examples using the [simple DSL](https://github.com/colinsurprenant/redstorm/
|
|
158
195
|
#### Example topologies without gems
|
159
196
|
|
160
197
|
``` sh
|
161
|
-
$ redstorm local
|
162
|
-
$ redstorm local
|
163
|
-
$ redstorm local
|
198
|
+
$ redstorm local examples/simple/exclamation_topology.rb
|
199
|
+
$ redstorm local examples/simple/exclamation_topology2.rb
|
200
|
+
$ redstorm local examples/simple/word_count_topology.rb
|
164
201
|
```
|
165
202
|
|
166
203
|
#### Example topologies with gems
|
167
204
|
|
168
|
-
For `examples/simple/redis_word_count_topology.rb` the `redis` gem is required and you need a [Redis]
|
205
|
+
For `examples/simple/redis_word_count_topology.rb` the `redis` gem is required and you need a [Redis](http://redis.io/) server running on `localhost:6379`
|
169
206
|
|
170
207
|
1. create a `Gemfile`
|
171
208
|
|
@@ -173,21 +210,21 @@ For `examples/simple/redis_word_count_topology.rb` the `redis` gem is required a
|
|
173
210
|
source :rubygems
|
174
211
|
|
175
212
|
group :word_count do
|
176
|
-
|
213
|
+
gem "redis"
|
177
214
|
end
|
178
215
|
```
|
179
216
|
|
180
217
|
2. install the topology gems
|
181
218
|
|
182
219
|
``` sh
|
183
|
-
$
|
220
|
+
$ bundle install
|
184
221
|
$ redstorm bundle word_count
|
185
222
|
```
|
186
223
|
|
187
224
|
3. run the topology in local mode
|
188
225
|
|
189
226
|
``` sh
|
190
|
-
$ redstorm local
|
227
|
+
$ redstorm local examples/simple/redis_word_count_topology.rb
|
191
228
|
```
|
192
229
|
|
193
230
|
Using `redis-cli` push words into the `test` list and watch Storm pick them up
|
@@ -208,15 +245,15 @@ All examples using the [simple DSL](https://github.com/colinsurprenant/redstorm/
|
|
208
245
|
2. submit the cluster topology jar file to the cluster, assuming you have the Storm distribution installed and the Storm `bin/` directory in your path:
|
209
246
|
|
210
247
|
``` sh
|
211
|
-
$ redstorm cluster
|
212
|
-
$ redstorm cluster
|
213
|
-
$ redstorm cluster
|
248
|
+
$ redstorm cluster examples/simple/exclamation_topology.rb
|
249
|
+
$ redstorm cluster examples/simple/exclamation_topology2.rb
|
250
|
+
$ redstorm cluster examples/simple/word_count_topology.rb
|
214
251
|
```
|
215
252
|
|
216
253
|
|
217
254
|
#### Topologies with gems
|
218
255
|
|
219
|
-
For `examples/simple/redis_word_count_topology.rb` the `redis` gem is required and you need a [Redis]
|
256
|
+
For `examples/simple/redis_word_count_topology.rb` the `redis` gem is required and you need a [Redis](http://redis.io/) server running on `localhost:6379`
|
220
257
|
|
221
258
|
1. create a `Gemfile`
|
222
259
|
|
@@ -231,7 +268,7 @@ For `examples/simple/redis_word_count_topology.rb` the `redis` gem is required a
|
|
231
268
|
2. install the topology gems
|
232
269
|
|
233
270
|
``` sh
|
234
|
-
$
|
271
|
+
$ bundle install
|
235
272
|
$ redstorm bundle word_count
|
236
273
|
```
|
237
274
|
|
@@ -244,7 +281,7 @@ For `examples/simple/redis_word_count_topology.rb` the `redis` gem is required a
|
|
244
281
|
4. submit the cluster topology jar file to the cluster, assuming you have the Storm distribution installed and the Storm `bin/` directory in your path:
|
245
282
|
|
246
283
|
``` sh
|
247
|
-
$ redstorm cluster
|
284
|
+
$ redstorm cluster examples/simple/redis_word_count_topology.rb
|
248
285
|
```
|
249
286
|
|
250
287
|
Using `redis-cli` push words into the `test` list and watch Storm pick them up
|
@@ -280,7 +317,7 @@ It is possible to fork the RedStorm project and run local and remote/cluster top
|
|
280
317
|
|
281
318
|
### Requirements
|
282
319
|
|
283
|
-
- JRuby 1.6.
|
320
|
+
- JRuby 1.6.8
|
284
321
|
|
285
322
|
### Workflow
|
286
323
|
|
@@ -289,7 +326,7 @@ It is possible to fork the RedStorm project and run local and remote/cluster top
|
|
289
326
|
- install RedStorm required gems
|
290
327
|
|
291
328
|
```sh
|
292
|
-
$
|
329
|
+
$ bundle install
|
293
330
|
```
|
294
331
|
|
295
332
|
- install dependencies in `target/dependencies`
|
@@ -301,7 +338,7 @@ It is possible to fork the RedStorm project and run local and remote/cluster top
|
|
301
338
|
- generate and build Java source into `target/classes`
|
302
339
|
|
303
340
|
```sh
|
304
|
-
$
|
341
|
+
$ bin/redstorm build
|
305
342
|
```
|
306
343
|
|
307
344
|
**if you modify any of the RedStorm Ruby code or Java binding code**, you need to run this to refresh code and rebuild the bindings
|
@@ -326,21 +363,13 @@ Some ways you can contribute:
|
|
326
363
|
|
327
364
|
If you want to list your RedStorm project here, contact me.
|
328
365
|
|
329
|
-
- [Tweigeist](https://github.com/colinsurprenant/tweitgeist) - realtime computation of the top trending hashtags on Twitter. Live Demo
|
366
|
+
- [Tweigeist](https://github.com/colinsurprenant/tweitgeist) - realtime computation of the top trending hashtags on Twitter. See [Live Demo](http://tweitgeist.colinsurprenant.com/).
|
330
367
|
|
331
368
|
## Author
|
332
|
-
Colin Surprenant
|
369
|
+
***Colin Surprenant***, [@colinsurprenant](http://twitter.com/colinsurprenant/), [http://github.com/colinsurprenant/](http://github.com/colinsurprenant/), colin.surprenant@gmail.com, [http://colinsurprenant.com/](http://colinsurprenant.com/)
|
333
370
|
|
334
371
|
## Contributors
|
335
372
|
Theo Hultberg, https://github.com/iconara
|
336
373
|
|
337
374
|
## License
|
338
375
|
Apache License, Version 2.0. See the LICENSE.md file.
|
339
|
-
|
340
|
-
[twitter]: http://twitter.com/colinsurprenant
|
341
|
-
[github]: http://github.com/colinsurprenant
|
342
|
-
[rvm]: http://beginrescueend.com/
|
343
|
-
[storm]: https://github.com/nathanmarz/storm
|
344
|
-
[jruby]: http://jruby.org/
|
345
|
-
[ruby-maven]: https://github.com/mkristian/ruby-maven
|
346
|
-
[redis]: http://redis.io/
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'red_storm'
|
2
|
+
java_import 'storm.kafka.KafkaConfig'
|
3
|
+
java_import 'storm.kafka.SpoutConfig'
|
4
|
+
java_import 'storm.kafka.StringScheme'
|
5
|
+
java_import 'storm.kafka.KafkaSpout'
|
6
|
+
|
7
|
+
# the KafkaTopology obviously requires a Kafka server running, you can ajust the
|
8
|
+
# host and port below.
|
9
|
+
#
|
10
|
+
# custom dependencies are required for the Kafka and Scala jars. put the following
|
11
|
+
# dependencies in the "Dependencies" file in the root of your RedStorm project:
|
12
|
+
#
|
13
|
+
# {
|
14
|
+
# :storm_artifacts => [
|
15
|
+
# "storm:storm:0.8.1, transitive=true",
|
16
|
+
# ],
|
17
|
+
# :topology_artifacts => [
|
18
|
+
# "org.jruby:jruby-complete:1.6.8, transitive=false",
|
19
|
+
# "org.scala-lang:scala-library:2.8.0, transitive=false",
|
20
|
+
# "storm:kafka:0.7.0-incubating, transitive=false",
|
21
|
+
# "storm:storm-kafka:0.8.0-wip4, transitive=false",
|
22
|
+
# ],
|
23
|
+
# }
|
24
|
+
|
25
|
+
class KafkaTopology < RedStorm::SimpleTopology
|
26
|
+
spout_config = SpoutConfig.new(
|
27
|
+
KafkaConfig::ZkHosts.new("localhost:2181", "/brokers"),
|
28
|
+
"words", # topic to read from
|
29
|
+
"/kafkastorm", # Zookeeper root path to store the consumer offsets
|
30
|
+
"discovery" # Zookeeper consumer id to store the consumer offsets
|
31
|
+
)
|
32
|
+
spout_config.scheme = StringScheme.new
|
33
|
+
|
34
|
+
class SplitStringBolt < RedStorm::SimpleBolt
|
35
|
+
on_receive {|tuple| tuple.getString(0).split.map{|w| [w]}}
|
36
|
+
end
|
37
|
+
|
38
|
+
spout KafkaSpout, [spout_config]
|
39
|
+
|
40
|
+
bolt SplitStringBolt do
|
41
|
+
output_fields :word
|
42
|
+
source KafkaSpout, :shuffle
|
43
|
+
end
|
44
|
+
|
45
|
+
configure do |env|
|
46
|
+
debug true
|
47
|
+
end
|
48
|
+
|
49
|
+
on_submit do |env|
|
50
|
+
if env == :local
|
51
|
+
sleep(10)
|
52
|
+
cluster.shutdown
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/ivy/settings.xml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
<ivysettings>
|
2
|
+
<settings defaultResolver="repositories"/>
|
3
|
+
<resolvers>
|
4
|
+
<chain name="repositories">
|
5
|
+
<ibiblio name="ibiblio" m2compatible="true"/>
|
6
|
+
<ibiblio name="maven2" root="http://repo.maven.apache.org/maven2/" m2compatible="true"/>
|
7
|
+
<ibiblio name="sonatype" root="http://repo.maven.apache.org/maven2/" m2compatible="true"/>
|
8
|
+
<ibiblio name="clojars" root="http://clojars.org/repo/" m2compatible="true"/>
|
9
|
+
</chain>
|
10
|
+
</resolvers>
|
11
|
+
</ivysettings>
|
@@ -18,6 +18,12 @@ REDSTORM_LIB_DIR = "#{RedStorm::REDSTORM_HOME}/lib"
|
|
18
18
|
SRC_EXAMPLES = "#{RedStorm::REDSTORM_HOME}/examples"
|
19
19
|
DST_EXAMPLES = "#{CWD}/examples"
|
20
20
|
|
21
|
+
SRC_IVY_DIR = "#{RedStorm::REDSTORM_HOME}/ivy"
|
22
|
+
DST_IVY_DIR = "#{CWD}/ivy"
|
23
|
+
CUSTOM_DEPENDENCIES = "#{CWD}/Dependencies"
|
24
|
+
DEFAULT_IVY_SETTINGS = "#{SRC_IVY_DIR}/settings.xml"
|
25
|
+
CUSTOM_IVY_SETTINGS = "#{DST_IVY_DIR}/settings.xml"
|
26
|
+
|
21
27
|
|
22
28
|
module RedStorm
|
23
29
|
|
@@ -26,7 +32,7 @@ module RedStorm
|
|
26
32
|
|
27
33
|
def self.local_storm_command(class_file, ruby_mode = nil)
|
28
34
|
src_dir = File.expand_path(File.dirname(class_file))
|
29
|
-
"java -Djruby.compat.version=#{RedStorm.jruby_mode_token(ruby_mode)} -cp \"#{TARGET_CLASSES_DIR}:#{TARGET_DEPENDENCY_DIR}/*:#{src_dir}/\" redstorm.TopologyLauncher local #{class_file}"
|
35
|
+
"java -Djruby.compat.version=#{RedStorm.jruby_mode_token(ruby_mode)} -cp \"#{TARGET_CLASSES_DIR}:#{TARGET_DEPENDENCY_DIR}/storm/default/*:#{TARGET_DEPENDENCY_DIR}/topology/default/*:#{src_dir}/\" redstorm.TopologyLauncher local #{class_file}"
|
30
36
|
end
|
31
37
|
|
32
38
|
def self.cluster_storm_command(class_file, ruby_mode = nil)
|
@@ -70,7 +76,7 @@ module RedStorm
|
|
70
76
|
end
|
71
77
|
|
72
78
|
def self.subshell(command)
|
73
|
-
out = IO.popen(
|
79
|
+
out = IO.popen(command, {:err => [:child, :out]}) {|io| io.read}
|
74
80
|
[!!$?.success?, out]
|
75
81
|
end
|
76
82
|
|
data/lib/red_storm/loggable.rb
CHANGED
data/lib/red_storm/proxy/bolt.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'java'
|
1
2
|
require 'red_storm/configurator'
|
2
3
|
|
3
4
|
module RedStorm
|
@@ -8,7 +9,7 @@ module RedStorm
|
|
8
9
|
# DSL class methods
|
9
10
|
|
10
11
|
def self.log
|
11
|
-
@log ||= Logger.getLogger(self.name)
|
12
|
+
@log ||= Java::OrgApacheLog4j::Logger.getLogger(self.name)
|
12
13
|
end
|
13
14
|
|
14
15
|
def self.output_fields(*fields)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'java'
|
1
2
|
require 'red_storm/configurator'
|
2
3
|
|
3
4
|
module RedStorm
|
@@ -12,7 +13,7 @@ module RedStorm
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def self.log
|
15
|
-
@log ||= Logger.getLogger(self.name)
|
16
|
+
@log ||= Java::OrgApacheLog4j::Logger.getLogger(self.name)
|
16
17
|
end
|
17
18
|
|
18
19
|
def self.output_fields(*fields)
|
@@ -101,7 +101,7 @@ module RedStorm
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def self.log
|
104
|
-
@log ||=
|
104
|
+
@log ||= Java::OrgApacheLog4j::Logger.getLogger(self.name)
|
105
105
|
end
|
106
106
|
|
107
107
|
# def self.spout(spout_class, contructor_args = [], options = {}, &spout_block)
|
data/lib/red_storm/version.rb
CHANGED
data/lib/tasks/red_storm.rake
CHANGED
@@ -1,15 +1,27 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require 'ant'
|
3
|
+
rescue
|
4
|
+
puts("error: unable to load Ant, make sure Ant is installed and in your PATH")
|
5
|
+
puts("\nerror detail:\n#{$!}")
|
6
|
+
exit(1)
|
7
|
+
end
|
8
|
+
|
2
9
|
require 'jruby/jrubyc'
|
3
|
-
require 'pompompom'
|
4
10
|
require 'red_storm'
|
5
11
|
require 'red_storm/application'
|
6
12
|
|
7
|
-
|
8
|
-
|
13
|
+
DEP_STORM_VERSION = "0.8.1"
|
14
|
+
DEP_JRUBY_VERSION = "1.6.8"
|
15
|
+
INSTALL_IVY_VERSION = "2.2.0"
|
9
16
|
|
10
|
-
|
11
|
-
|
12
|
-
|
17
|
+
DEFAULT_DEPENDENCIES = {
|
18
|
+
:storm_artifacts => [
|
19
|
+
"storm:storm:#{DEP_STORM_VERSION}, transitive=true",
|
20
|
+
],
|
21
|
+
:topology_artifacts => [
|
22
|
+
"org.jruby:jruby-complete:#{DEP_JRUBY_VERSION}, transitive=false",
|
23
|
+
],
|
24
|
+
}
|
13
25
|
|
14
26
|
task :launch, :env, :ruby_mode, :class_file do |t, args|
|
15
27
|
# use ruby mode parameter or default to current interpreter version
|
@@ -20,7 +32,7 @@ task :launch, :env, :ruby_mode, :class_file do |t, args|
|
|
20
32
|
RedStorm::Application.local_storm_command(args[:class_file], args[:ruby_mode])
|
21
33
|
when "cluster"
|
22
34
|
unless File.exist?(TARGET_CLUSTER_JAR)
|
23
|
-
puts("cluster jar file #{TARGET_CLUSTER_JAR} not found. Generate it
|
35
|
+
puts("error: cluster jar file #{TARGET_CLUSTER_JAR} not found. Generate it usingw $redstorm jar DIR1 [DIR2, ...]")
|
24
36
|
exit(1)
|
25
37
|
end
|
26
38
|
RedStorm::Application.cluster_storm_command(args[:class_file], args[:ruby_mode])
|
@@ -58,61 +70,6 @@ task :install => [:deps, :build] do
|
|
58
70
|
puts("\nRedStorm install completed. All dependencies installed in #{TARGET_DIR}")
|
59
71
|
end
|
60
72
|
|
61
|
-
task :unpack do
|
62
|
-
unpack_artifacts = %w[jruby-complete]
|
63
|
-
unpack_glob = "#{TARGET_DEPENDENCY_DIR}/{#{unpack_artifacts.join(',')}}-*-jar.jar"
|
64
|
-
Dir[unpack_glob].each do |jar|
|
65
|
-
puts("Extracting #{jar}")
|
66
|
-
zf = JavaZip::ZipFile.new(jar)
|
67
|
-
zf.entries.each do |entry|
|
68
|
-
next if entry.directory?
|
69
|
-
destination = "#{TARGET_DEPENDENCY_UNPACKED_DIR}/#{entry.name}"
|
70
|
-
in_io = zf.get_input_stream(entry).to_io
|
71
|
-
FileUtils.mkdir_p(File.dirname(destination))
|
72
|
-
File.open(destination, 'w') { |out_io| out_io.write(in_io.read) }
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
task :jar, [:include_dir] => [:unpack, :clean_jar] do |t, args|
|
78
|
-
puts("\n--> Generating JAR file #{TARGET_CLUSTER_JAR}")
|
79
|
-
ant.jar :destfile => TARGET_CLUSTER_JAR do
|
80
|
-
fileset :dir => TARGET_DEPENDENCY_UNPACKED_DIR
|
81
|
-
fileset :dir => TARGET_DIR do
|
82
|
-
include :name => "gems/**"
|
83
|
-
end
|
84
|
-
fileset :dir => TARGET_CLASSES_DIR
|
85
|
-
# red_storm.rb and red_storm/* must be in root of jar so that "require 'red_storm'"
|
86
|
-
# in bolts/spouts works in jar context
|
87
|
-
fileset :dir => TARGET_LIB_DIR do
|
88
|
-
exclude :name => "tasks/**"
|
89
|
-
end
|
90
|
-
if args[:include_dir]
|
91
|
-
dirs = args[:include_dir].split(":")
|
92
|
-
|
93
|
-
# first add any resources/ dir in the tree in the jar root - requirement for ShellBolt multilang resources
|
94
|
-
dirs.each do |dir|
|
95
|
-
resources_dirs = Dir.glob("#{dir}/**/resources")
|
96
|
-
resources_dirs.each do |resources_dir|
|
97
|
-
resources_parent = resources_dir.gsub("/resources", "")
|
98
|
-
fileset :dir => resources_parent do
|
99
|
-
include :name => "resources/**/*"
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# include complete source dir tree (note we don't care about potential duplicated resources dir)
|
105
|
-
fileset :dir => CWD do
|
106
|
-
dirs.each{|dir| include :name => "#{dir}/**/*"}
|
107
|
-
end
|
108
|
-
end
|
109
|
-
manifest do
|
110
|
-
attribute :name => "Main-Class", :value => "redstorm.TopologyLauncher"
|
111
|
-
end
|
112
|
-
end
|
113
|
-
puts("\nRedStorm generated JAR file #{TARGET_CLUSTER_JAR}")
|
114
|
-
end
|
115
|
-
|
116
73
|
task :examples do
|
117
74
|
if File.identical?(SRC_EXAMPLES, DST_EXAMPLES)
|
118
75
|
STDERR.puts("error: cannot copy examples into itself")
|
@@ -132,26 +89,6 @@ task :copy_red_storm do
|
|
132
89
|
FileUtils.cp_r(REDSTORM_LIB_DIR, TARGET_DIR)
|
133
90
|
end
|
134
91
|
|
135
|
-
task :deps => :setup do
|
136
|
-
puts("\n--> Installing dependencies")
|
137
|
-
|
138
|
-
configuration = {
|
139
|
-
:repositories => {:clojars => 'http://clojars.org/repo/', :sonatype => "http://oss.sonatype.org/content/groups/public/"},
|
140
|
-
:dependencies => [
|
141
|
-
"storm:storm:#{INSTALL_STORM_VERSION}|type_filter=jar",
|
142
|
-
"org.slf4j:slf4j-log4j12:1.5.8|type_filter=jar",
|
143
|
-
"org.jruby:jruby-complete:#{INSTALL_JRUBY_VERSION}|transitive=false,type_filter=jar",
|
144
|
-
],
|
145
|
-
:destination => TARGET_DEPENDENCY_DIR
|
146
|
-
}
|
147
|
-
|
148
|
-
installer = PomPomPom::Runner.new(configuration)
|
149
|
-
installer.run
|
150
|
-
|
151
|
-
# tmp hack to clenup a dependency weirdness (issue #36)
|
152
|
-
FileUtils.rm("#{TARGET_DEPENDENCY_DIR}/slf4j-api-1.6.3-jar.jar")
|
153
|
-
end
|
154
|
-
|
155
92
|
task :build => [:setup, :copy_red_storm] do
|
156
93
|
# compile the JRuby proxy classes to Java
|
157
94
|
build_jruby("#{REDSTORM_LIB_DIR}/red_storm/proxy")
|
@@ -189,6 +126,90 @@ task :bundle, [:groups] => :setup do |t, args|
|
|
189
126
|
end
|
190
127
|
end
|
191
128
|
|
129
|
+
namespace :ivy do
|
130
|
+
task :download do
|
131
|
+
mkdir_p DST_IVY_DIR
|
132
|
+
ant.get({
|
133
|
+
:src => "http://repo1.maven.org/maven2/org/apache/ivy/ivy/#{INSTALL_IVY_VERSION}/ivy-#{INSTALL_IVY_VERSION}.jar",
|
134
|
+
:dest => "#{DST_IVY_DIR}/ivy-#{INSTALL_IVY_VERSION}.jar",
|
135
|
+
:usetimestamp => true,
|
136
|
+
})
|
137
|
+
end
|
138
|
+
|
139
|
+
task :install => :download do
|
140
|
+
ant.path :id => 'ivy.lib.path' do
|
141
|
+
fileset :dir => DST_IVY_DIR, :includes => '*.jar'
|
142
|
+
end
|
143
|
+
|
144
|
+
ant.taskdef({
|
145
|
+
:resource => "org/apache/ivy/ant/antlib.xml",
|
146
|
+
:classpathref => "ivy.lib.path",
|
147
|
+
#:uri => "antlib:org.apache.ivy.ant",
|
148
|
+
})
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
task :deps => "ivy:install" do
|
153
|
+
puts("\n--> Installing dependencies")
|
154
|
+
|
155
|
+
dependencies = File.exists?(CUSTOM_DEPENDENCIES) ? eval(File.read(CUSTOM_DEPENDENCIES)) : DEFAULT_DEPENDENCIES
|
156
|
+
ant.configure :file => File.exists?(CUSTOM_IVY_SETTINGS) ? CUSTOM_IVY_SETTINGS : DEFAULT_IVY_SETTINGS
|
157
|
+
|
158
|
+
dependencies[:storm_artifacts].each do |dependency|
|
159
|
+
artifact, transitive = dependency.split(/\s*,\s*/)
|
160
|
+
ivy_retrieve(*artifact.split(':').concat([transitive.split(/\s*=\s*/).last, "#{TARGET_DEPENDENCY_DIR}/storm", "default"]))
|
161
|
+
end
|
162
|
+
|
163
|
+
dependencies[:topology_artifacts].each do |dependency|
|
164
|
+
artifact, transitive = dependency.split(/\s*,\s*/)
|
165
|
+
ivy_retrieve(*artifact.split(':').concat([transitive.split(/\s*=\s*/).last, "#{TARGET_DEPENDENCY_DIR}/topology", "default"]))
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
task :jar, [:include_dir] => [:clean_jar] do |t, args|
|
170
|
+
puts("\n--> Generating JAR file #{TARGET_CLUSTER_JAR}")
|
171
|
+
|
172
|
+
ant.jar :destfile => TARGET_CLUSTER_JAR do
|
173
|
+
# rejar all topology jars
|
174
|
+
Dir["target/dependency/topology/default/*.jar"].each do |jar|
|
175
|
+
puts("Extracting #{jar}")
|
176
|
+
zipfileset :src => jar, :includes => "**/*"
|
177
|
+
end
|
178
|
+
fileset :dir => TARGET_DIR do
|
179
|
+
include :name => "gems/**"
|
180
|
+
end
|
181
|
+
fileset :dir => TARGET_CLASSES_DIR
|
182
|
+
# red_storm.rb and red_storm/* must be in root of jar so that "require 'red_storm'"
|
183
|
+
# in bolts/spouts works in jar context
|
184
|
+
fileset :dir => TARGET_LIB_DIR do
|
185
|
+
exclude :name => "tasks/**"
|
186
|
+
end
|
187
|
+
if args[:include_dir]
|
188
|
+
dirs = args[:include_dir].split(":")
|
189
|
+
|
190
|
+
# first add any resources/ dir in the tree in the jar root - requirement for ShellBolt multilang resources
|
191
|
+
dirs.each do |dir|
|
192
|
+
resources_dirs = Dir.glob("#{dir}/**/resources")
|
193
|
+
resources_dirs.each do |resources_dir|
|
194
|
+
resources_parent = resources_dir.gsub("/resources", "")
|
195
|
+
fileset :dir => resources_parent do
|
196
|
+
include :name => "resources/**/*"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
# include complete source dir tree (note we don't care about potential duplicated resources dir)
|
202
|
+
fileset :dir => CWD do
|
203
|
+
dirs.each{|dir| include :name => "#{dir}/**/*"}
|
204
|
+
end
|
205
|
+
end
|
206
|
+
manifest do
|
207
|
+
attribute :name => "Main-Class", :value => "redstorm.TopologyLauncher"
|
208
|
+
end
|
209
|
+
end
|
210
|
+
puts("\nRedStorm generated JAR file #{TARGET_CLUSTER_JAR}")
|
211
|
+
end
|
212
|
+
|
192
213
|
def build_java_dir(source_folder)
|
193
214
|
puts("\n--> Compiling Java")
|
194
215
|
ant.javac(
|
@@ -213,9 +234,38 @@ def build_jruby(source_path)
|
|
213
234
|
argv << '-t' << TARGET_SRC_DIR
|
214
235
|
argv << '--verbose'
|
215
236
|
argv << '--java'
|
216
|
-
|
237
|
+
Dir["#{TARGET_DEPENDENCY_DIR}/storm/default/*.jar"].each do |jar|
|
238
|
+
argv << '-c' << %("#{jar}")
|
239
|
+
end
|
217
240
|
argv << '-c' << %("#{TARGET_CLASSES_DIR}")
|
218
241
|
argv << source_path
|
219
242
|
status = JRuby::Compiler::compile_argv(argv)
|
220
243
|
end
|
221
244
|
end
|
245
|
+
|
246
|
+
def truefalse(s)
|
247
|
+
return true if s.to_s.downcase =~ /1|yes|true/
|
248
|
+
return false if s.to_s.downcase =~ /0|no|false/
|
249
|
+
nil
|
250
|
+
end
|
251
|
+
|
252
|
+
def ivy_retrieve(org, mod, rev, transitive, dir, conf)
|
253
|
+
ant.resolve({
|
254
|
+
:organisation => org,
|
255
|
+
:module => mod,
|
256
|
+
:revision => rev,
|
257
|
+
:inline => true,
|
258
|
+
:transitive => truefalse(transitive),
|
259
|
+
:conf => conf,
|
260
|
+
})
|
261
|
+
|
262
|
+
ant.retrieve({
|
263
|
+
:organisation => org,
|
264
|
+
:module => mod,
|
265
|
+
:revision => rev,
|
266
|
+
:pattern => "#{dir}/[conf]/[artifact]-[revision].[ext]",
|
267
|
+
:inline => true,
|
268
|
+
:transitive => truefalse(transitive),
|
269
|
+
:conf => conf,
|
270
|
+
})
|
271
|
+
end
|
metadata
CHANGED
@@ -2,14 +2,14 @@
|
|
2
2
|
name: redstorm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.6.
|
5
|
+
version: 0.6.4
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Colin Surprenant
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -17,13 +17,13 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 2.
|
20
|
+
version: 2.11.0
|
21
21
|
none: false
|
22
22
|
requirement: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.
|
26
|
+
version: 2.11.0
|
27
27
|
none: false
|
28
28
|
prerelease: false
|
29
29
|
type: :development
|
@@ -43,22 +43,6 @@ dependencies:
|
|
43
43
|
none: false
|
44
44
|
prerelease: false
|
45
45
|
type: :runtime
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: pompompom
|
48
|
-
version_requirements: !ruby/object:Gem::Requirement
|
49
|
-
requirements:
|
50
|
-
- - '='
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: 2.0.0.b2
|
53
|
-
none: false
|
54
|
-
requirement: !ruby/object:Gem::Requirement
|
55
|
-
requirements:
|
56
|
-
- - '='
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
version: 2.0.0.b2
|
59
|
-
none: false
|
60
|
-
prerelease: false
|
61
|
-
type: :runtime
|
62
46
|
description: JRuby integration & DSL for the Storm distributed realtime computation system
|
63
47
|
email:
|
64
48
|
- colin.surprenant@gmail.com
|
@@ -81,6 +65,7 @@ files:
|
|
81
65
|
- lib/red_storm/proxy/bolt.rb
|
82
66
|
- lib/red_storm/proxy/spout.rb
|
83
67
|
- lib/tasks/red_storm.rake
|
68
|
+
- ivy/settings.xml
|
84
69
|
- examples/native/cluster_word_count_topology.rb
|
85
70
|
- examples/native/exclamation_bolt.rb
|
86
71
|
- examples/native/Gemfile
|
@@ -97,7 +82,7 @@ files:
|
|
97
82
|
- examples/simple/exclamation_bolt.rb
|
98
83
|
- examples/simple/exclamation_topology.rb
|
99
84
|
- examples/simple/exclamation_topology2.rb
|
100
|
-
- examples/simple/
|
85
|
+
- examples/simple/kafka_topology.rb
|
101
86
|
- examples/simple/random_sentence_spout.rb
|
102
87
|
- examples/simple/redis_word_count_topology.rb
|
103
88
|
- examples/simple/ruby_version_topology.rb
|
data/examples/simple/Gemfile
DELETED