pact_broker 2.27.2 → 2.27.3

Sign up to get free protection for your applications and to get access to all the features.
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