maestro_common 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+
15
+ # YARD artifacts
16
+ .yardoc
17
+ _yardoc
18
+ doc/
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use jruby-1.6.8
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,43 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ maestro_common (0.0.1)
5
+ json (>= 1.4.6)
6
+ logging (= 1.8.0)
7
+ onstomp
8
+ rubyzip (= 0.9.8)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ bouncy-castle-java (1.5.0147)
14
+ diff-lcs (1.2.4)
15
+ jruby-openssl (0.8.8)
16
+ bouncy-castle-java (>= 1.5.0147)
17
+ json (1.8.0-java)
18
+ little-plugger (1.1.3)
19
+ logging (1.8.0)
20
+ little-plugger (>= 1.1.3)
21
+ multi_json (>= 1.3.6)
22
+ multi_json (1.7.6)
23
+ onstomp (1.0.5)
24
+ rake (10.0.4)
25
+ rspec (2.13.0)
26
+ rspec-core (~> 2.13.0)
27
+ rspec-expectations (~> 2.13.0)
28
+ rspec-mocks (~> 2.13.0)
29
+ rspec-core (2.13.1)
30
+ rspec-expectations (2.13.0)
31
+ diff-lcs (>= 1.1.3, < 2.0)
32
+ rspec-mocks (2.13.1)
33
+ rubyzip (0.9.8)
34
+
35
+ PLATFORMS
36
+ java
37
+
38
+ DEPENDENCIES
39
+ bundler (~> 1.3)
40
+ jruby-openssl
41
+ maestro_common!
42
+ rake
43
+ rspec (~> 2.13.0)
data/README.md ADDED
@@ -0,0 +1,8 @@
1
+ maestro-ruby-common
2
+ ===================
3
+
4
+ Common classes used by multiple Maestro Ruby apps
5
+
6
+ Currently contains code shared by both MaestroAgent and CEE.
7
+ If some code currently exists in both of those locations then it may be eligible to be moved here.
8
+ There can be no updward dependencies on MA or CEE
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rake/clean'
4
+
5
+ require File.expand_path('../lib/maestro_common/version', __FILE__)
6
+
7
+ CLEAN.include('pkg')
8
+ CLOBBER.include('.bundle', '.config', 'coverage', 'InstalledFiles', 'spec/reports', 'rdoc', 'test', 'tmp')
9
+
10
+ task :default => [:clean, :bundle, :spec, :build]
11
+
12
+ RSpec::Core::RakeTask.new
13
+
14
+ desc 'Get dependencies with Bundler'
15
+ task :bundle do
16
+ sh %{bundle install}
17
+ end
@@ -0,0 +1,2 @@
1
+ require File.join(File.dirname(__FILE__), 'utils', 'retryable.rb')
2
+ require File.join(File.dirname(__FILE__), 'helpers', 'mq_helper.rb')
@@ -0,0 +1,156 @@
1
+ # Copyright 2012© MaestroDev. All rights reserved.
2
+ require 'onstomp'
3
+ require 'onstomp/failover'
4
+
5
+ module Maestro
6
+
7
+ module MQHelper
8
+ @@INFINITE_RETRIES = 2**32-1
9
+ @@stomp = nil
10
+ @@subs = {}
11
+ @@tries = 0
12
+ @@sleep = 20
13
+ @@uri = nil
14
+
15
+ def MQHelper.reset
16
+ Maestro.log.info "Resetting MQHelper"
17
+ @@stomp = nil
18
+ @@subs = {}
19
+ @@tries = 0
20
+ @@sleep = 20
21
+ @@uri = nil
22
+ end
23
+
24
+ def MQHelper.connection
25
+ if @@stomp.nil?
26
+ Maestro.log.warn "Request for stomp connection, but not set up yet!"
27
+ end
28
+ @@stomp
29
+ end
30
+
31
+ def MQHelper.connect
32
+ if @@stomp.nil?
33
+ Maestro.log.info "Request for stomp connection - creating"
34
+
35
+ # retry info - the retryable below doesn't support 'unlimited' but if we give it a really big number...
36
+ if @@tries == 0
37
+ @@tries = Maestro.stomp_config['max_retries']
38
+
39
+ if @@tries.nil?
40
+ @@tries = @@INFINITE_RETRIES
41
+ Maestro.log.info "Connect retry attempt count not specified, using ~INFINITE (really big number)"
42
+ else
43
+ Maestro.log.info "Connect retry attempt count not specified, using config file setting #{@@tries}"
44
+ end
45
+ end
46
+
47
+ @@sleep = Maestro.stomp_config['retry_seconds'] || 20
48
+
49
+ # New form is config.url = some_url
50
+ # Old form is config.user, config.passcode, config.host, config.port,
51
+ # config.ssl
52
+ # Check for new config first, it overrides
53
+ url = Maestro.stomp_config['url']
54
+
55
+ if url && !url.empty?
56
+ # New form
57
+ is_failover = url.start_with?('failover:')
58
+ options = {}
59
+
60
+ if url.include?('+ssl')
61
+ options[:ssl] = { :ca_file => Maestro.stomp_config['cert'] || nil, :verify_mode => OpenSSL::SSL::VERIFY_NONE }
62
+ end
63
+
64
+ @@uri = url
65
+
66
+ if is_failover
67
+ Maestro.log.info "Using OnStomp Failover Client"
68
+ client = OnStomp::Failover::Client.new(url, options)
69
+ else
70
+ client = OnStomp::Client.new(url, options)
71
+ end
72
+ else
73
+ # Old form
74
+ Maestro.log.debug "Old-form stomp config being used"
75
+ user = Maestro.stomp_config['user']
76
+ passcode = Maestro.stomp_config['passcode']
77
+ host = Maestro.stomp_config['host']
78
+ port = Maestro.stomp_config['port'].to_s
79
+ ssl = Maestro.stomp_config['ssl'] ? "+ssl" : ""
80
+ cert = Maestro.stomp_config['cert'] || nil
81
+
82
+ # construct the connection URI
83
+ user_and_password = [user,passcode].reject{ |e| e.nil? || e.empty? }.join(":")
84
+ host_and_port = [host,port].reject{|e| e.nil? || e.empty?}.join(":")
85
+ protocol = ['stomp', ssl, '://'].reject{|e| e.nil? || e.empty?}.join
86
+ @@uri = protocol + [host_and_port, user_and_password].reject{|e| e.nil? || e.empty?}.reverse.join("@")
87
+
88
+ if (!ssl.nil? && ssl == "+ssl")
89
+ client = OnStomp::Client.new(@@uri, :ssl => {:ca_file => cert, :verify_mode => OpenSSL::SSL::VERIFY_NONE})
90
+ else
91
+ client = OnStomp::Client.new(@@uri)
92
+ end
93
+ end
94
+
95
+ @@stomp = client
96
+ reconnect
97
+ raise "Failed To Connect To Maestro" unless client.connected?
98
+ end
99
+
100
+ @@stomp
101
+ end
102
+
103
+ def MQHelper.reconnect
104
+ if !@@stomp
105
+ raise Maestro::MQError, "Cannot reconnect, no existing MQ instance. Call 'connect' to create initial connection, then use 'reconnect' if connection fails"
106
+ end
107
+
108
+ if !@@stomp.connected?
109
+ Maestro::Utils.retryable(:tries => @@tries, :sleep => @@sleep) do
110
+ Maestro.log.info "Connecting To stomp At #{@@uri}"
111
+ @@stomp.connect
112
+ end
113
+
114
+ if @@stomp.connected?
115
+ oldsubs = @@subs.dup
116
+ @@subs.clear
117
+ oldsubs.each do |dest, info|
118
+ Maestro.log.info "Resubscribing to #{dest}"
119
+ do_subscribe(dest, info['headers'], &info['callback'])
120
+ end
121
+ else
122
+ Maestro.log.warn "Unable to reconnect to subscriptions because no MQ Connection"
123
+ end
124
+ end
125
+
126
+ @@stomp.connected?
127
+ end
128
+
129
+ def MQHelper.disconnect
130
+ if !@@stomp.nil?
131
+ @@stomp.disconnect
132
+ end
133
+ end
134
+
135
+ def MQHelper.subscribe(dest, headers={}, &cb)
136
+ Maestro.log.info "MQHelper: Subscribing to #{dest}"
137
+ do_subscribe(dest, headers, &cb)
138
+ end
139
+
140
+ def MQHelper.unsubscribe(dest, &cb)
141
+ if @@subs.has_key?(dest)
142
+ Maestro.log.info "MQHelper: Unsubscribing from #{dest}"
143
+ @@stomp.unsubscribe(@@subs[dest]['frame'])
144
+ @@subs.delete(dest)
145
+ end
146
+ end
147
+
148
+ private
149
+
150
+ def MQHelper.do_subscribe(dest, headers, &cb)
151
+ sub = @@stomp.subscribe(dest, headers, &cb)
152
+ @@subs[dest] = { 'frame' => sub, 'callback' => cb, 'headers' => headers }
153
+ sub
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,23 @@
1
+ module Maestro
2
+ module Utils
3
+
4
+ def Utils.retryable(options = {}, &block)
5
+ options[:on] = [options[:on]] unless options[:on].nil? or options[:on].is_a?(Array)
6
+ opts = { :tries => 1, :on => [StandardError], :sleep => 20 }.merge(options)
7
+
8
+ retry_exception, retries, snooze = opts[:on], opts[:tries], opts[:sleep]
9
+ count = 0
10
+
11
+ begin
12
+ count += 1
13
+ return yield
14
+ rescue *retry_exception => e
15
+ Maestro.log.warn "Attempt ##{count}: Failed with #{e.class} #{e}, retrying in #{opts[:sleep]} seconds."
16
+ sleep snooze
17
+ retry if count < retries
18
+ end
19
+ yield
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ module Maestro
2
+ module Common
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'maestro_common/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'maestro_common'
8
+ spec.version = Maestro::Common::VERSION
9
+ spec.authors = ['Doug Henderson']
10
+ spec.email = ['dhenderson@maestrodev.com']
11
+ spec.description = %q{A bunch of utility classes that are used in multiple places}
12
+ spec.summary = %q{Maestro common classes}
13
+ spec.homepage = 'https://github.com/maestrodev/maestro-ruby-common'
14
+ spec.license = 'Apache 2.0'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'onstomp'
22
+ spec.add_dependency 'logging', '1.8.0'
23
+ spec.add_dependency 'rubyzip', '0.9.8'
24
+ spec.add_dependency 'json', '>= 1.4.6'
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.3'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'jruby-openssl'
29
+ spec.add_development_dependency 'rspec', '~> 2.13.0'
30
+
31
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: maestro_common
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Doug Henderson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2013-06-12 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: onstomp
17
+ version_requirements: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ requirement: *id001
24
+ prerelease: false
25
+ type: :runtime
26
+ - !ruby/object:Gem::Dependency
27
+ name: logging
28
+ version_requirements: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - "="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.0
34
+ requirement: *id002
35
+ prerelease: false
36
+ type: :runtime
37
+ - !ruby/object:Gem::Dependency
38
+ name: rubyzip
39
+ version_requirements: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - "="
43
+ - !ruby/object:Gem::Version
44
+ version: 0.9.8
45
+ requirement: *id003
46
+ prerelease: false
47
+ type: :runtime
48
+ - !ruby/object:Gem::Dependency
49
+ name: json
50
+ version_requirements: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: 1.4.6
56
+ requirement: *id004
57
+ prerelease: false
58
+ type: :runtime
59
+ - !ruby/object:Gem::Dependency
60
+ name: bundler
61
+ version_requirements: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: "1.3"
67
+ requirement: *id005
68
+ prerelease: false
69
+ type: :development
70
+ - !ruby/object:Gem::Dependency
71
+ name: rake
72
+ version_requirements: &id006 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ requirement: *id006
79
+ prerelease: false
80
+ type: :development
81
+ - !ruby/object:Gem::Dependency
82
+ name: jruby-openssl
83
+ version_requirements: &id007 !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: "0"
89
+ requirement: *id007
90
+ prerelease: false
91
+ type: :development
92
+ - !ruby/object:Gem::Dependency
93
+ name: rspec
94
+ version_requirements: &id008 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ~>
98
+ - !ruby/object:Gem::Version
99
+ version: 2.13.0
100
+ requirement: *id008
101
+ prerelease: false
102
+ type: :development
103
+ description: A bunch of utility classes that are used in multiple places
104
+ email:
105
+ - dhenderson@maestrodev.com
106
+ executables: []
107
+
108
+ extensions: []
109
+
110
+ extra_rdoc_files: []
111
+
112
+ files:
113
+ - .gitignore
114
+ - .rvmrc
115
+ - Gemfile
116
+ - Gemfile.lock
117
+ - README.md
118
+ - Rakefile
119
+ - lib/maestro_common/common.rb
120
+ - lib/maestro_common/helpers/mq_helper.rb
121
+ - lib/maestro_common/utils/retryable.rb
122
+ - lib/maestro_common/version.rb
123
+ - maestro_common.gemspec
124
+ homepage: https://github.com/maestrodev/maestro-ruby-common
125
+ licenses:
126
+ - Apache 2.0
127
+ post_install_message:
128
+ rdoc_options: []
129
+
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ hash: 2
138
+ segments:
139
+ - 0
140
+ version: "0"
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ hash: 2
147
+ segments:
148
+ - 0
149
+ version: "0"
150
+ requirements: []
151
+
152
+ rubyforge_project:
153
+ rubygems_version: 1.8.24
154
+ signing_key:
155
+ specification_version: 3
156
+ summary: Maestro common classes
157
+ test_files: []
158
+