uat-discovery 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 97ca4955b3d8e9b62e2bdb81704477408ad27026
4
+ data.tar.gz: 130dbadc2dcb9d1d8cce88bfdf370e857173a90b
5
+ SHA512:
6
+ metadata.gz: 962e62bc8e89950afc96577b917dc4c84e5fea363717d0a664f1f126c0d20d61e94800a1d15503b51fdb01847af43145ba373f451add9cbdcd703be3d70cae34
7
+ data.tar.gz: 3a302aa33e59fd7523fbd07a7001bc6fb857c783b3db768435e90ce42fe7cff63caad2225e80cda8994468cc4e28895a502ce2d32dccc8f3d93d6e8ccbb4d5ef
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper --format documentation --color true
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in uat-discovery.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ UAT::Discovery
2
+ -----------
3
+
4
+ Interact with, or simulate, discovery using this gem.
5
+
6
+ # Usage
7
+
8
+ The behavior for how a client provides the urls for a given named service is determined by how the API was configured.
9
+ See below for example configuration hashes for different desired behaviors.
10
+
11
+ ```
12
+ config = UAT::Discovery::Configuration.new(config_hash)
13
+ api = UAT::Discovery::API.new(config)
14
+
15
+ client = api.new_client
16
+ client.urls_for_service('service_name')
17
+ ```
18
+
19
+ # Configuration Options
20
+
21
+ Local Mode
22
+
23
+ ```
24
+ {
25
+ "local_mode": true,
26
+ "local_service_urls_keyed_by_service_name": {
27
+ "service1": [
28
+ "url1",
29
+ "url2"
30
+ ]
31
+ }
32
+ }
33
+ ```
34
+
35
+ Server Mode
36
+
37
+ Append a locally configured path to the end of the host/port (support for multiple service N/A)
38
+
39
+ ```
40
+ {
41
+ "local_mode": false,
42
+ "url": "http://discovery-server:8080",
43
+ "protocol": "http",
44
+ "discover_paths": false,
45
+ "append_service_path": "/path/to/append/after/host"
46
+ }
47
+ ```
48
+
49
+ Discover the pathing information via Discovery's Key/Value store:
50
+
51
+ ```
52
+ {
53
+ "local_mode": false,
54
+ "url": "http://discovery-server:8080",
55
+ "protocol": "http",
56
+ "discover_paths": true,
57
+ "service_metadata_key_value_prefix": "chef/services/",
58
+ "metadata_property_for_path": "root_url_path"
59
+ }
60
+ ```
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #-*- mode: ruby -*-
2
+
3
+ require "rspec/core/rake_task"
4
+ RSpec::Core::RakeTask.new
5
+ task :default => [ :spec ]
6
+
7
+ # vim: syntax=Ruby
@@ -0,0 +1,81 @@
1
+ module UAT
2
+ module Discovery
3
+ # An instance of this API should be used to create all objects needed from this gem
4
+ # The configuration with which it is instantiated controls all instances
5
+ class API
6
+ # @param configuration [UAT::Discovery::Configuration]
7
+ def initialize(configuration)
8
+ @configuration = configuration
9
+ end
10
+
11
+ # @return [UAT::Discovery::Interfaces::IClient] returns a client implementation based on configuration
12
+ def new_client
13
+ @configuration.local_mode? ? new_mock_client : new_real_client
14
+ end
15
+
16
+ # @return [UAT::Discovery::Client]
17
+ def new_real_client
18
+ Client.new(
19
+ new_diplomat_service,
20
+ @configuration.protocol,
21
+ self,
22
+ new_path_provider
23
+ )
24
+ end
25
+
26
+ # @return [UAT::Discovery::MockClient]
27
+ def new_mock_client
28
+ MockClient.new(
29
+ @configuration.local_service_urls_keyed_by_service_name,
30
+ self
31
+ )
32
+ end
33
+
34
+ # @param uri_string the uri string that should be converted to a URI object
35
+ # @return [URI::Generic]
36
+ def new_uri(uri_string)
37
+ URI(uri_string)
38
+ end
39
+
40
+ private
41
+
42
+ # @return [UAT::Discovery::Interfaces::IPathProvider]
43
+ # @private
44
+ def new_path_provider
45
+ @configuration.discover_paths? ? new_discovery_path_provider : new_configured_path_provider
46
+ end
47
+
48
+ # @return [UAT::Discovery::ConsulPathProvider]
49
+ # @private
50
+ def new_discovery_path_provider
51
+ ConsulPathProvider.new(
52
+ Diplomat,
53
+ @configuration.service_metadata_key_value_prefix,
54
+ JSON,
55
+ @configuration.metadata_property_for_path
56
+ )
57
+ end
58
+
59
+ # @return [UAT::Discovery::ConfiguredSinglePathProvider]
60
+ # @private
61
+ def new_configured_path_provider
62
+ ConfiguredSinglePathProvider.new(@configuration.append_service_path)
63
+ end
64
+
65
+ # @return [Diplomat::Service]
66
+ # @private
67
+ def new_diplomat_service
68
+ configure_diplomat
69
+ Diplomat::Service
70
+ end
71
+
72
+ # @return [Void] configures diplomat to use the configured discovery_url
73
+ # @private
74
+ def configure_diplomat
75
+ Diplomat.configure do |config|
76
+ config.url = @configuration.url
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,31 @@
1
+ module UAT
2
+ module Discovery
3
+ # A discovery client that uses Diplomat to get urls for a named service
4
+ # @see [UAT::Discovery::IClient]
5
+ class Client < Interfaces::IClient
6
+ # @param diplomat_service [Class<Diplomat::Service>] the diplomat service class reference
7
+ # @param protocol [String] the protocol that should be prepended to urls_for_service
8
+ # @param api [#new_uri] a factory method for creating new URIs
9
+ # @param path_provider [UAT::Discovery::Interfaces::IPathProvider] provides path for after host/port
10
+ def initialize(diplomat_service, protocol, api, path_provider)
11
+ @diplomat_service = diplomat_service
12
+ @protocol = protocol
13
+ @api = api
14
+ @path_provider = path_provider
15
+ end
16
+
17
+ # @see [UAT::Discovery::IClient]
18
+ def urls_for_service(service_name)
19
+ diplomat_services = @diplomat_service.get(service_name, :all)
20
+ path = @path_provider.path_to_append_for(service_name)
21
+ diplomat_services.uniq.map {|diplomat_service| @api.new_uri(uri_string(diplomat_service, path)) }
22
+ end
23
+
24
+ private
25
+
26
+ def uri_string(diplomat_service, path)
27
+ "#{@protocol}://#{diplomat_service.Address.to_s}:#{diplomat_service.ServicePort}#{path}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,50 @@
1
+ module UAT
2
+ module Discovery
3
+ class Configuration
4
+ # @param config_hash [Hash]
5
+ def initialize(config_hash)
6
+ @config_hash = config_hash
7
+ end
8
+
9
+ # @return [Hash<String, Array<String>>]
10
+ def local_service_urls_keyed_by_service_name
11
+ @config_hash['local_service_urls_keyed_by_service_name']
12
+ end
13
+
14
+ # @return [Boolean]
15
+ def local_mode?
16
+ @config_hash['local_mode']
17
+ end
18
+
19
+ # @return [Boolean]
20
+ def discover_paths?
21
+ @config_hash['discover_paths']
22
+ end
23
+
24
+ # @return [String]
25
+ def protocol
26
+ @config_hash['protocol']
27
+ end
28
+
29
+ # @return [String] path that will be appended to discovery host/port, no matter what service name
30
+ def append_service_path
31
+ @config_hash['append_service_path']
32
+ end
33
+
34
+ # @return [String] the prefix to prepend to a service name, used to retrieve discovery key value requests for a service
35
+ def service_metadata_key_value_prefix
36
+ @config_hash['service_metadata_key_value_prefix']
37
+ end
38
+
39
+ # @return [String] the property name in discovery key/value metadata hash containing a service's path
40
+ def metadata_property_for_path
41
+ @config_hash['metadata_property_for_path']
42
+ end
43
+
44
+ # @return [String]
45
+ def url
46
+ @config_hash['url']
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,16 @@
1
+ module UAT
2
+ module Discovery
3
+ class ConfiguredSinglePathProvider < Interfaces::IPathProvider
4
+ # @param append_service_path [String] the path (if any) to append after the domain and port. Should include leading slash /
5
+ def initialize(append_service_path)
6
+ @append_service_path = append_service_path
7
+ end
8
+
9
+ # @param service_name [String] the name of the service for which one would like to get the path - ignored
10
+ # @return [String]
11
+ def path_to_append_for(service_name)
12
+ @append_service_path
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ module UAT
2
+ module Discovery
3
+ class ConsulPathProvider < Interfaces::IPathProvider
4
+ # @param diplomat_service [Module<Diplomat>] the diplomat module
5
+ # @param service_metadata_key_value_prefix [String] the key value prefix that comes before a service name
6
+ # @param json_parser [JSON] native JSON module or compatible parser
7
+ # @param metadata_property_for_path [String] the property on the metadata node containing the path
8
+ def initialize(diplomat_module, service_metadata_key_value_prefix, json_parser, metadata_property_for_path)
9
+ @diplomat_module = diplomat_module
10
+ @service_metadata_key_value_prefix = service_metadata_key_value_prefix
11
+ @json_parser = json_parser
12
+ @metadata_property_for_path = metadata_property_for_path
13
+ end
14
+
15
+ # @param service_name [String] the name of the service for which one would like to get the path - ignored
16
+ # @return [String]
17
+ def path_to_append_for(service_name)
18
+ #'chef/services/lookout-bluffdale'
19
+ metadata = @diplomat_module.get("#{@service_metadata_key_value_prefix}#{service_name}")
20
+ metadata_hash = @json_parser.parse(metadata)
21
+ metadata_hash['metadata'][@metadata_property_for_path]
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ module UAT
2
+ module Discovery
3
+ module Interfaces
4
+ # @abstract
5
+ class IClient
6
+ # @abstract
7
+ # @param service_name [String] the name of the service for which one would like to retrieve the host urls
8
+ # @return [Array<URI::Generic>]
9
+ def urls_for_service(service_name) raise NotImplementedError end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module UAT
2
+ module Discovery
3
+ module Interfaces
4
+ # @abstract
5
+ class IPathProvider
6
+ # @abstract
7
+ # @param service_name [String] the name of the service for which one would like to get the path
8
+ # @return [String]
9
+ def path_to_append_for(service_name) raise NotImplementedError end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ module UAT
2
+ module Discovery
3
+ # A mock discovery client, mainly for use when running tests locally
4
+ # Allows one to locally configure the hosts associated with a service name
5
+ # @see [UAT::Discovery::IClient]
6
+ class MockClient < Interfaces::IClient
7
+ # @param hash_of_service_urls_keyed_by_service_name [Hash]
8
+ # @param api [UAT::Discovery::API]
9
+ def initialize(hash_of_service_urls_keyed_by_service_name, api)
10
+ @hash_of_service_urls = hash_of_service_urls_keyed_by_service_name
11
+ @api = api
12
+ end
13
+
14
+ # @see [UAT::Discovery::IClient#urls_for_service]
15
+ def urls_for_service(service_name)
16
+ if @hash_of_service_urls.has_key? service_name
17
+ @hash_of_service_urls[service_name].map {|service_url| @api.new_uri(service_url)}
18
+ else
19
+ raise "URL for service #{service_name} could not be found"
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ module UAT
2
+ module Discovery
3
+ VERSION = "0.0.1.pre"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ require 'diplomat'
2
+ require 'uri'
3
+
4
+ Dir["#{File.dirname(__FILE__)}/discovery/interfaces/**/*.rb"].each { |f| require(f) }
5
+ Dir["#{File.dirname(__FILE__)}/discovery/**/*.rb"].each { |f| require(f) }
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'uat/discovery/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "uat-discovery"
8
+ spec.version = UAT::Discovery::VERSION
9
+ spec.authors = ["Tommy Sullivan", "Blaine Schanfeldt"]
10
+ spec.email = ["thomas.sullivan@lookout.com", "blaine.schanfeldt@lookout.com"]
11
+
12
+ spec.summary = "helper for discovery / service discovery during testing"
13
+ spec.homepage = "https://github.com/lookout/uat"
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = "exe"
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency 'rspec', '~> 3.2.0'
22
+ spec.add_development_dependency 'simplecov', '~> 0.9.2'
23
+ spec.add_development_dependency 'ipaddress', '~> 0.8.0'
24
+ spec.add_development_dependency 'yard', '~> 0.8.7'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'webmock', '~> 1.21.0'
27
+
28
+ spec.add_dependency 'diplomat', '~> 0.5.1'
29
+ end
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uat-discovery
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.pre
5
+ platform: ruby
6
+ authors:
7
+ - Tommy Sullivan
8
+ - Blaine Schanfeldt
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2015-04-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 3.2.0
20
+ name: rspec
21
+ prerelease: false
22
+ type: :development
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: 3.2.0
28
+ - !ruby/object:Gem::Dependency
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.2
34
+ name: simplecov
35
+ prerelease: false
36
+ type: :development
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: 0.9.2
42
+ - !ruby/object:Gem::Dependency
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.8.0
48
+ name: ipaddress
49
+ prerelease: false
50
+ type: :development
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 0.8.0
56
+ - !ruby/object:Gem::Dependency
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.7
62
+ name: yard
63
+ prerelease: false
64
+ type: :development
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.8.7
70
+ - !ruby/object:Gem::Dependency
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ name: rake
77
+ prerelease: false
78
+ type: :development
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: '10.0'
84
+ - !ruby/object:Gem::Dependency
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 1.21.0
90
+ name: webmock
91
+ prerelease: false
92
+ type: :development
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ~>
96
+ - !ruby/object:Gem::Version
97
+ version: 1.21.0
98
+ - !ruby/object:Gem::Dependency
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 0.5.1
104
+ name: diplomat
105
+ prerelease: false
106
+ type: :runtime
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ version: 0.5.1
112
+ description:
113
+ email:
114
+ - thomas.sullivan@lookout.com
115
+ - blaine.schanfeldt@lookout.com
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - .gitignore
121
+ - .rspec
122
+ - Gemfile
123
+ - README.md
124
+ - Rakefile
125
+ - lib/uat/discovery.rb
126
+ - lib/uat/discovery/api.rb
127
+ - lib/uat/discovery/client.rb
128
+ - lib/uat/discovery/configuration.rb
129
+ - lib/uat/discovery/configured_path_provider.rb
130
+ - lib/uat/discovery/consul_path_provider.rb
131
+ - lib/uat/discovery/interfaces/i_client.rb
132
+ - lib/uat/discovery/interfaces/i_path_provider.rb
133
+ - lib/uat/discovery/mock_client.rb
134
+ - lib/uat/discovery/version.rb
135
+ - uat-discovery.gemspec
136
+ homepage: https://github.com/lookout/uat
137
+ licenses:
138
+ - MIT
139
+ metadata: {}
140
+ post_install_message:
141
+ rdoc_options: []
142
+ require_paths:
143
+ - lib
144
+ required_ruby_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ required_rubygems_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - '>'
152
+ - !ruby/object:Gem::Version
153
+ version: 1.3.1
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 2.1.9
157
+ signing_key:
158
+ specification_version: 4
159
+ summary: helper for discovery / service discovery during testing
160
+ test_files: []
161
+ has_rdoc: