pact_broker 2.27.2 → 2.27.3

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.
Files changed (61) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +32 -0
  4. data/DEVELOPER_SETUP.md +1 -0
  5. data/example/config.ru +1 -1
  6. data/lib/pact_broker.rb +1 -0
  7. data/lib/pact_broker/api.rb +1 -0
  8. data/lib/pact_broker/api/decorators/pact_version_decorator.rb +0 -5
  9. data/lib/pact_broker/api/decorators/tagged_pact_versions_decorator.rb +46 -0
  10. data/lib/pact_broker/api/renderers/html_pact_renderer.rb +1 -1
  11. data/lib/pact_broker/api/resources/error_handler.rb +1 -0
  12. data/lib/pact_broker/api/resources/index.rb +6 -0
  13. data/lib/pact_broker/api/resources/tagged_pact_versions.rb +38 -0
  14. data/lib/pact_broker/app.rb +12 -6
  15. data/lib/pact_broker/certificates/service.rb +1 -0
  16. data/lib/pact_broker/configuration.rb +11 -16
  17. data/lib/pact_broker/db/log_quietener.rb +38 -0
  18. data/lib/pact_broker/doc/views/index/tagged-pact-versions.markdown +7 -0
  19. data/lib/pact_broker/logging.rb +25 -20
  20. data/lib/pact_broker/logging/default_formatter.rb +16 -0
  21. data/lib/pact_broker/matrix/deployment_status_summary.rb +3 -1
  22. data/lib/pact_broker/pacticipants/service.rb +1 -1
  23. data/lib/pact_broker/pacts/all_pact_publications.rb +1 -1
  24. data/lib/pact_broker/pacts/repository.rb +18 -4
  25. data/lib/pact_broker/pacts/service.rb +4 -0
  26. data/lib/pact_broker/ui/views/index/show-with-tags.haml +34 -33
  27. data/lib/pact_broker/ui/views/index/show.haml +28 -27
  28. data/lib/pact_broker/ui/views/layouts/main.haml +2 -2
  29. data/lib/pact_broker/ui/views/matrix/show.haml +126 -127
  30. data/lib/pact_broker/verifications/service.rb +3 -1
  31. data/lib/pact_broker/version.rb +1 -1
  32. data/lib/pact_broker/versions/repository.rb +3 -1
  33. data/lib/pact_broker/webhooks/job.rb +1 -0
  34. data/pact_broker.gemspec +1 -0
  35. data/script/db-spec.sh +2 -0
  36. data/spec/features/delete_tagged_pact_versions_spec.rb +28 -0
  37. data/spec/features/get_tagged_pact_versions_spec.rb +26 -0
  38. data/spec/integration/ui/index_spec.rb +2 -2
  39. data/spec/lib/pact_broker/api/decorators/pact_version_decorator_spec.rb +0 -3
  40. data/spec/lib/pact_broker/api/decorators/tagged_pact_versions_decorator_spec.rb +79 -0
  41. data/spec/lib/pact_broker/api/renderers/html_pact_renderer_spec.rb +5 -6
  42. data/spec/lib/pact_broker/api/resources/error_handler_spec.rb +7 -1
  43. data/spec/lib/pact_broker/api/resources/tagged_pact_versions_spec.rb +88 -0
  44. data/spec/lib/pact_broker/badges/service_spec.rb +3 -2
  45. data/spec/lib/pact_broker/certificates/service_spec.rb +8 -3
  46. data/spec/lib/pact_broker/db/log_quietener_spec.rb +42 -0
  47. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +17 -12
  48. data/spec/lib/pact_broker/domain/webhook_spec.rb +7 -2
  49. data/spec/lib/pact_broker/matrix/deployment_status_summary_spec.rb +8 -1
  50. data/spec/lib/pact_broker/pacticipants/service_spec.rb +5 -3
  51. data/spec/lib/pact_broker/pacts/repository_spec.rb +44 -3
  52. data/spec/lib/pact_broker/verifications/service_spec.rb +6 -2
  53. data/spec/lib/pact_broker/webhooks/job_spec.rb +2 -0
  54. data/spec/lib/pact_broker/webhooks/service_spec.rb +6 -1
  55. data/spec/spec_helper.rb +13 -13
  56. data/spec/support/database.rb +5 -0
  57. data/spec/support/fixture_pact.rb +34 -0
  58. data/spec/support/logging.rb +5 -0
  59. data/spec/support/shared_context.rb +10 -0
  60. data/tasks/development.rake +12 -3
  61. metadata +40 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: e67bad7e9a3ecb1e2ecd911350a937615bf9b2f90ac811ad48acf16185ffee41
4
- data.tar.gz: e55c77c181b1d2e37e20a6b0a4f6b500ebdba7b0c861597c8f80b580915d9a3c
2
+ SHA1:
3
+ metadata.gz: 8b120fc3afe15b42e4b97ca8eee39afe2f7f3070
4
+ data.tar.gz: 00ba1080e2f72e2fe27ed72a4adda5819cc0149a
5
5
  SHA512:
6
- metadata.gz: 3fcd28aeb22cee45696bee504bb1c6b49cec7faa83185df24c5854e9a22fd2023bee57f62fbea2fad54f5c4f590e1de91febab56f3baa1a15a7656d692a0d816
7
- data.tar.gz: 18a6fe1f7dd9c61143ea1fe7bf031576c8d1d615d0a212dc2b8e833ad5fd14de39c606e92ea021f82f8b64015ba3e12a7f8cccc317fd5979c30a965b153cb773
6
+ metadata.gz: c98ee07fa57d47767ce6a17d4d158082a9dd4b966a38a308836e11347d2909e3782fab0758ab7ffd2e05eb6d8cbe8c4844debfef6d19da73f7ed7d5cd8194aa6
7
+ data.tar.gz: 3b120a72072e2f5363ba35a3c3467fd41facb6fd26fb2cbe65e4c6d0a8c4448ac7eb8c7f8ea640881f5a32a99af2fe4c6f1b9a08c726188ce3d1492334c8687a
@@ -26,5 +26,5 @@ before_script:
26
26
  script:
27
27
  - bundle exec rake
28
28
  - if [ "$DATABASE_ADAPTER" == "postgres" ]; then ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT || true; fi
29
- - if [ ! -z "$(ruby --version | grep '2\.4\.')" ]; then ./script/db-spec.sh; fi
29
+ # - if [ ! -z "$(ruby --version | grep '2\.4\.')" ]; then ./script/db-spec.sh; fi
30
30
  - bundle exec bundle-audit update && bundle exec bundle-audit
@@ -1,3 +1,35 @@
1
+ <a name="v2.27.3"></a>
2
+ ### v2.27.3 (2018-11-01)
3
+
4
+
5
+ #### Features
6
+
7
+ * add LogQuietener to example config.ru ([2f014f07](/../../commit/2f014f07))
8
+ * Rename database logger delegate to LogQuietener ([34f44bcb](/../../commit/34f44bcb))
9
+ * create delegate for database logger to tone down the 'table does not exist' errors that freak people out at startup ([573d204b](/../../commit/573d204b))
10
+
11
+ * **semantic-logging**
12
+ * set logger for SuckerPunch and tests ([201eb331](/../../commit/201eb331))
13
+ * allow ruby standard logger to be configured to ensure backwards compatibility ([cfbb704c](/../../commit/cfbb704c))
14
+
15
+ * **tagged-pact-versions**
16
+ * ensure triggered webhooks are deleted when pact versions are deleted ([288475f1](/../../commit/288475f1))
17
+ * add endpoint to view and delete a collection of pact versions by tag ([615025e9](/../../commit/615025e9))
18
+
19
+ * **logging**
20
+ * implement structured logging ([a9133bd5](/../../commit/a9133bd5))
21
+
22
+
23
+ #### Bug Fixes
24
+
25
+ * correct foreign key between AllPactPublications and PactVersion ([59f76c74](/../../commit/59f76c74))
26
+ * ensure bundle install for pact_broker:dev:setup uses correct Gemfile ([94f3a5f2](/../../commit/94f3a5f2))
27
+ * Fix some invalid HTML ([0c9a08a8](/../../commit/0c9a08a8))
28
+
29
+ * **openssl**
30
+ * simplify certificate test for latest LibreSSL/OpenSSL libs ([cce79390](/../../commit/cce79390))
31
+
32
+
1
33
  <a name="v2.27.2"></a>
2
34
  ### v2.27.2 (2018-09-14)
3
35
 
@@ -8,6 +8,7 @@
8
8
  * To run the example:
9
9
 
10
10
  cd dev
11
+ bundle install
11
12
  bundle exec rackup
12
13
 
13
14
  * The application will be available on `http://localhost:9292`
@@ -27,7 +27,7 @@ app = PactBroker::App.new do | config |
27
27
  # change these from their default values if desired
28
28
  # config.log_dir = "./log"
29
29
  # config.auto_migrate_db = true
30
- config.database_connection = Sequel.connect(DATABASE_CREDENTIALS.merge(:logger => config.logger))
30
+ config.database_connection = Sequel.connect(DATABASE_CREDENTIALS.merge(:logger => PactBroker::DB::LogQuietener.new(config.logger)))
31
31
  end
32
32
 
33
33
  run app
@@ -4,6 +4,7 @@ require 'reform/form/dry'
4
4
  require 'pact_broker/version'
5
5
  require 'pact_broker/logging'
6
6
  require 'pact_broker/app'
7
+ require 'pact_broker/db/log_quietener'
7
8
 
8
9
  module PactBroker
9
10
  Reform::Form.class_eval do
@@ -11,6 +11,7 @@ module PactBroker
11
11
 
12
12
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'versions'], Api::Resources::PactVersions, {resource_name: "pact_publications"}
13
13
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'versions', :consumer_version_number], Api::Resources::Pact, {resource_name: "pact_publication", deprecated: true} # Not the standard URL, but keep for backwards compatibility
14
+ add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'tag', :tag], Api::Resources::TaggedPactVersions, {resource_name: "tagged_pact_publications"}
14
15
 
15
16
  # Pacts
16
17
  add ['pacts', 'provider', :provider_name, 'consumer', :consumer_name, 'version', :consumer_version_number], Api::Resources::Pact, {resource_name: "pact_publication"}
@@ -3,13 +3,9 @@ require_relative 'pact_pacticipant_decorator'
3
3
  require 'pact_broker/api/decorators/timestamps'
4
4
 
5
5
  module PactBroker
6
-
7
6
  module Api
8
-
9
7
  module Decorators
10
-
11
8
  class PactVersionDecorator < BaseDecorator
12
-
13
9
  include Timestamps
14
10
 
15
11
  property :consumer_version, as: :consumerVersion, embedded: true, decorator: EmbeddedVersionDecorator
@@ -20,7 +16,6 @@ module PactBroker
20
16
  title: represented.name
21
17
  }
22
18
  end
23
-
24
19
  end
25
20
  end
26
21
  end
@@ -0,0 +1,46 @@
1
+ require_relative 'base_decorator'
2
+ require_relative 'pact_version_decorator'
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Decorators
7
+ class TaggedPactVersionsDecorator < BaseDecorator
8
+
9
+ collection :entries, as: :pacts, embedded: true, :extend => PactBroker::Api::Decorators::PactVersionDecorator
10
+
11
+ link :self do | context |
12
+ {
13
+ href: context[:resource_url],
14
+ title: "All versions of the pact between #{context[:consumer_name]} and #{context[:provider_name]} with tag #{context[:tag]}"
15
+ }
16
+ end
17
+
18
+ link :'pb:consumer' do | context |
19
+ {
20
+ href: pacticipant_url(context[:base_url], OpenStruct.new(name: context[:consumer_name])),
21
+ title: "Consumer",
22
+ name: context[:consumer_name]
23
+ }
24
+ end
25
+
26
+ link :'pb:provider' do | context |
27
+ {
28
+ href: pacticipant_url(context[:base_url], OpenStruct.new(name: context[:provider_name])),
29
+ title: "Provider",
30
+ name: context[:provider_name]
31
+ }
32
+ end
33
+
34
+ links :'pb:pact-versions' do | context |
35
+ represented.collect do | pact |
36
+ {
37
+ :href => pact_url(context[:base_url], pact),
38
+ :title => "Pact version",
39
+ :name => pact.version_and_updated_date
40
+ }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -167,4 +167,4 @@ module PactBroker
167
167
  end
168
168
  end
169
169
  end
170
- end
170
+ end
@@ -7,6 +7,7 @@ module PactBroker
7
7
  class ErrorHandler
8
8
 
9
9
  include PactBroker::Logging
10
+ include PactBroker::Logging
10
11
 
11
12
  def self.call e, request, response
12
13
  logger.error e
@@ -38,6 +38,12 @@ module PactBroker
38
38
  title: 'Latest pact versions',
39
39
  templated: false
40
40
  },
41
+ 'pb:tagged-pact-versions' =>
42
+ {
43
+ href: base_url + '/pacts/provider/{provider}/consumer/{consumer}/tag/{tag}',
44
+ title: 'All versions of a pact for a given consumer, provider and consumer version tag',
45
+ templated: false
46
+ },
41
47
  'pb:pacticipants' =>
42
48
  {
43
49
  href: base_url + '/pacticipants',
@@ -0,0 +1,38 @@
1
+ require 'pact_broker/api/resources/base_resource'
2
+ require 'pact_broker/configuration'
3
+ require 'pact_broker/api/decorators/tagged_pact_versions_decorator'
4
+
5
+ module PactBroker
6
+ module Api
7
+ module Resources
8
+ class TaggedPactVersions < BaseResource
9
+
10
+ def content_types_provided
11
+ [["application/hal+json", :to_json]]
12
+ end
13
+
14
+ def allowed_methods
15
+ ["GET", "DELETE", "OPTIONS"]
16
+ end
17
+
18
+ def resource_exists?
19
+ pacticipant_service.find_pacticipant_by_name(consumer_name) &&
20
+ pacticipant_service.find_pacticipant_by_name(provider_name)
21
+ end
22
+
23
+ def to_json
24
+ PactBroker::Api::Decorators::TaggedPactVersionsDecorator.new(pacts).to_json(user_options: decorator_context(identifier_from_path))
25
+ end
26
+
27
+ def delete_resource
28
+ pact_service.delete_all_pact_versions_between consumer_name, and: provider_name, tag: identifier_from_path[:tag]
29
+ true
30
+ end
31
+
32
+ def pacts
33
+ pact_service.find_all_pact_versions_between consumer_name, and: provider_name, tag: identifier_from_path[:tag]
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,6 +1,7 @@
1
1
  require 'pact_broker/configuration'
2
2
  require 'pact_broker/db'
3
3
  require 'pact_broker/project_root'
4
+ require 'pact_broker/logging/default_formatter'
4
5
  require 'rack-protection'
5
6
  require 'rack/hal_browser'
6
7
  require 'rack/pact_broker/store_base_url'
@@ -18,6 +19,7 @@ require 'sucker_punch'
18
19
  module PactBroker
19
20
 
20
21
  class App
22
+ include PactBroker::Logging
21
23
 
22
24
  attr_accessor :configuration
23
25
 
@@ -58,13 +60,9 @@ module PactBroker
58
60
 
59
61
  private
60
62
 
61
- def logger
62
- PactBroker.logger
63
- end
64
-
65
63
  def post_configure
66
- PactBroker.logger = configuration.logger
67
- SuckerPunch.logger = configuration.logger
64
+ configure_logger
65
+ SuckerPunch.logger = configuration.custom_logger || SemanticLogger['SuckerPunch']
68
66
  configure_database_connection
69
67
  configure_sucker_punch
70
68
  end
@@ -166,6 +164,14 @@ module PactBroker
166
164
  end
167
165
  end
168
166
 
167
+ def configure_logger
168
+ if SemanticLogger.appenders.empty?
169
+ path = configuration.log_dir + "/pact_broker.log"
170
+ FileUtils.mkdir_p(configuration.log_dir)
171
+ SemanticLogger.add_appender(file_name: path, formatter: PactBroker::Logging::DefaultFormatter.new)
172
+ end
173
+ end
174
+
169
175
  def running_app
170
176
  @running_app ||= begin
171
177
  apps = @cascade_apps
@@ -8,6 +8,7 @@ module PactBroker
8
8
 
9
9
  extend self
10
10
  extend PactBroker::Logging
11
+ include PactBroker::Logging
11
12
 
12
13
  def cert_store
13
14
  cert_store = OpenSSL::X509::Store.new
@@ -1,5 +1,6 @@
1
1
  require 'pact_broker/error'
2
2
  require 'pact_broker/config/space_delimited_string_list'
3
+ require 'semantic_logger'
3
4
 
4
5
  module PactBroker
5
6
 
@@ -42,7 +43,7 @@ module PactBroker
42
43
  attr_accessor :disable_ssl_verification
43
44
  attr_accessor :base_equality_only_on_content_that_affects_verification_results
44
45
  attr_reader :api_error_reporters
45
- attr_writer :logger
46
+ attr_reader :custom_logger
46
47
 
47
48
  def initialize
48
49
  @before_resource_hook = ->(resource){}
@@ -50,10 +51,7 @@ module PactBroker
50
51
  @authenticate_with_basic_auth = nil
51
52
  @authorize = nil
52
53
  @api_error_reporters = []
53
- end
54
-
55
- def logger
56
- @logger ||= create_logger log_path
54
+ @semantic_logger = SemanticLogger["root"]
57
55
  end
58
56
 
59
57
  def self.default_configuration
@@ -85,6 +83,14 @@ module PactBroker
85
83
  config
86
84
  end
87
85
 
86
+ def logger
87
+ custom_logger || @semantic_logger
88
+ end
89
+
90
+ def logger= logger
91
+ @custom_logger = logger
92
+ end
93
+
88
94
  def self.default_html_pact_render
89
95
  lambda { |pact, options|
90
96
  require 'pact_broker/api/renderers/html_pact_renderer'
@@ -201,16 +207,5 @@ module PactBroker
201
207
  raise ConfigurationError.new("Pact Broker configuration property `#{property_name}` must be a space delimited String or an Array")
202
208
  end
203
209
  end
204
-
205
- def create_logger path
206
- FileUtils::mkdir_p File.dirname(path)
207
- logger = Logger.new(path)
208
- logger.level = Logger::DEBUG
209
- logger
210
- end
211
-
212
- def log_path
213
- log_dir + "/pact_broker.log"
214
- end
215
210
  end
216
211
  end
@@ -0,0 +1,38 @@
1
+ # To reduce the noise of the SQL logs, this class changes INFO
2
+ # logs to DEBUG, and changes the ERROR logs that occur when
3
+ # Sequel doesn't know if a table/view exists or not to DEBUG,
4
+ # so that they don't freak newbies out when they start up the
5
+ # broker for the first time.
6
+
7
+ require 'delegate'
8
+
9
+ module PactBroker
10
+ module DB
11
+ class LogQuietener < SimpleDelegator
12
+ def info *args
13
+ __getobj__().debug(*args)
14
+ end
15
+
16
+ def error *args
17
+ if error_is_about_table_not_existing?(args)
18
+ __getobj__().debug(*reassure_people_that_this_is_expected(args))
19
+ else
20
+ __getobj__().error(*args)
21
+ end
22
+ end
23
+
24
+ def error_is_about_table_not_existing?(args)
25
+ args.first.is_a?(String) &&
26
+ ( args.first.include?("PG::UndefinedTable") ||
27
+ args.first.include?("no such table") ||
28
+ args.first.include?("no such view"))
29
+ end
30
+
31
+ def reassure_people_that_this_is_expected(args)
32
+ message = args.shift
33
+ message = message + " Don't panic. This happens when Sequel doesn't know if a table/view exists or not."
34
+ [message] + args
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ # Tagged pact versions
2
+
3
+ Allowed methods: `GET`, `DELETE`
4
+
5
+ Lists all the pact versions with the specified consumer, provider and consumer version tag.
6
+
7
+ Send a `DELETE` request to the resource to batch delete all the versions.
@@ -1,20 +1,34 @@
1
- require 'logger'
2
1
  require 'pathname'
2
+ require 'semantic_logger'
3
3
 
4
4
  module PactBroker
5
-
6
5
  module Logging
7
6
 
8
- # Need to make this configurable based on the calling app!
9
- LOG_DIR = Pathname.new(File.join(File.dirname(__FILE__), '..', '..', 'log')).cleanpath
10
- LOG_FILE_NAME = "#{ENV['RACK_ENV'] || 'development'}.log"
11
-
12
7
  def self.included(base)
13
- base.extend(self)
14
- end
15
-
16
- def logger= logger
17
- @@logger = logger
8
+ base.extend self
9
+ base.extend SemanticLogger::Loggable::ClassMethods
10
+ base.class_eval do
11
+ # Returns [SemanticLogger::Logger] class level logger
12
+ def self.logger
13
+ require 'pact_broker/configuration'
14
+ @logger ||= PactBroker.configuration.custom_logger || SemanticLogger[self]
15
+ end
16
+
17
+ # Replace instance class level logger
18
+ def self.logger=(logger)
19
+ @logger = logger
20
+ end
21
+
22
+ # Returns [SemanticLogger::Logger] instance level logger
23
+ def logger
24
+ @logger ||= self.class.logger
25
+ end
26
+
27
+ # Replace instance level logger
28
+ def logger=(logger)
29
+ @logger = logger
30
+ end
31
+ end
18
32
  end
19
33
 
20
34
  def log_error e, description = nil
@@ -22,15 +36,6 @@ module PactBroker
22
36
  message = "#{description} - #{message}" if description
23
37
  logger.error message
24
38
  end
25
-
26
- def logger
27
- @@logger ||= begin
28
- FileUtils.mkdir_p(LOG_DIR)
29
- logger = Logger.new(File.join(LOG_DIR, LOG_FILE_NAME))
30
- logger.level = Logger::DEBUG
31
- logger
32
- end
33
- end
34
39
  end
35
40
 
36
41
  include Logging