uat-discovery 0.0.1.pre

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.
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: