pact_broker 2.16.1 → 2.17.0

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +22 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +9 -0
  4. data/CHANGELOG.md +28 -0
  5. data/DEVELOPER_DOCUMENTATION.md +5 -0
  6. data/db/migrations/000046_recreate_latest_verifications.rb +2 -2
  7. data/db/migrations/20180311_optimise_head_matrix.rb +80 -0
  8. data/db/migrations/20180315_create_verification_sequence.rb +14 -0
  9. data/db/migrations/migration_helper.rb +1 -1
  10. data/lib/db.rb +3 -2
  11. data/lib/pact_broker/api/resources/base_resource.rb +10 -13
  12. data/lib/pact_broker/api/resources/error_handler.rb +30 -0
  13. data/lib/pact_broker/api/resources/pact.rb +6 -1
  14. data/lib/pact_broker/api/resources/pacticipant.rb +8 -2
  15. data/lib/pact_broker/api/resources/tag.rb +4 -2
  16. data/lib/pact_broker/api/resources/verifications.rb +5 -1
  17. data/lib/pact_broker/api/resources/version.rb +3 -1
  18. data/lib/pact_broker/api.rb +1 -1
  19. data/lib/pact_broker/config/load.rb +1 -0
  20. data/lib/pact_broker/configuration.rb +16 -0
  21. data/lib/pact_broker/matrix/head_row.rb +19 -0
  22. data/lib/pact_broker/matrix/repository.rb +39 -2
  23. data/lib/pact_broker/matrix/row.rb +16 -28
  24. data/lib/pact_broker/matrix/service.rb +6 -2
  25. data/lib/pact_broker/pacticipants/service.rb +1 -0
  26. data/lib/pact_broker/ui/controllers/base_controller.rb +2 -1
  27. data/lib/pact_broker/ui/controllers/error_test.rb +0 -1
  28. data/lib/pact_broker/ui/controllers/matrix.rb +3 -4
  29. data/lib/pact_broker/ui/view_models/matrix_line.rb +6 -0
  30. data/lib/pact_broker/ui/views/matrix/show.haml +14 -10
  31. data/lib/pact_broker/ui.rb +6 -6
  32. data/lib/pact_broker/verifications/repository.rb +9 -4
  33. data/lib/pact_broker/verifications/sequence.rb +34 -0
  34. data/lib/pact_broker/verifications/service.rb +2 -2
  35. data/lib/pact_broker/version.rb +1 -1
  36. data/lib/webmachine/convert_request_to_rack_env.rb +37 -0
  37. data/script/publish.sh +13 -2
  38. data/script/recreate-mysql-db.sh +2 -1
  39. data/script/seed-matrix.rb +1 -1
  40. data/spec/features/publish_verification_spec.rb +0 -1
  41. data/spec/features/update_matrix_spec.rb +146 -0
  42. data/spec/fixtures/foo-bar.json +22 -0
  43. data/spec/lib/pact_broker/api/resources/error_handler_spec.rb +55 -0
  44. data/spec/lib/pact_broker/api/resources/verifications_spec.rb +1 -1
  45. data/spec/lib/pact_broker/configuration_spec.rb +19 -1
  46. data/spec/lib/pact_broker/matrix/head_row_spec.rb +52 -0
  47. data/spec/lib/pact_broker/matrix/repository_spec.rb +20 -0
  48. data/spec/lib/pact_broker/matrix/row_spec.rb +10 -10
  49. data/spec/lib/pact_broker/pacticipants/service_spec.rb +1 -0
  50. data/spec/lib/pact_broker/verifications/repository_spec.rb +0 -29
  51. data/spec/lib/pact_broker/verifications/sequence_spec.rb +47 -0
  52. data/spec/lib/pact_broker/verifications/service_spec.rb +0 -13
  53. data/spec/lib/webmachine/convert_request_to_rack_env_spec.rb +68 -0
  54. data/spec/support/test_data_builder.rb +2 -0
  55. data/tasks/development.rake +10 -0
  56. metadata +22 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c6d42dce83b4aaa14296c6a4121ca30a2490601d
4
- data.tar.gz: 2ba4c1581817b500fd971a3828582e97a4957542
3
+ metadata.gz: 4a081cfe7629357b678f7769d2fdcf69b75e8e27
4
+ data.tar.gz: 9c8913b7ad996fb1b7d59429cd47f3451bcb5c5e
5
5
  SHA512:
6
- metadata.gz: c2ea3e29cdcdbbc7c9317550824ecb8a908476888b591d299269414d4a6286fb8e52585ad21f2893a88a5e49f40b6b8c150c578d40a92fbf8519c2743afa710d
7
- data.tar.gz: af24759022fc72eee95eef7840cfb123af22d37f7c3a183af985391b0b0c2632f310eafe92f881b8a59517ee0b0b358b22512455078898e82c879ad951ee8e72
6
+ metadata.gz: f227bb7729f0a18640ba8faffe8432ceb8ad4d6a4e07a491dd0a8443fc351c76140c54ec31143640e37bc8dec9903297eca011bc5e5a882c6fcf74aadcf33317
7
+ data.tar.gz: d241902a991c46875e6c396ce407a135d40a2a7318039827f624d3425a53516543ff7f9c37b79f8f27bae153fb01faefa4953c52c5419fb8dce553e3498cee7d
@@ -0,0 +1,22 @@
1
+ ## Software versions
2
+
3
+ * **pact-broker gem version:** eg 2.3.1
4
+ * **pact-broker docker version:** eg 2.3.1-1
5
+ * **OS**: e.g. Mac OSX 10.11.5
6
+ * **pact broker client details:** eg. pact-ruby-standalone CLI v 1.23.0
7
+
8
+ ## Expected behaviour
9
+
10
+ TBC
11
+
12
+ ## Actual behaviour
13
+
14
+ TBC
15
+
16
+ ## Steps to reproduce
17
+
18
+ Provide a repository, gist or reproducable code snippet so that we can test the problem.
19
+
20
+ ## Relevent log files
21
+
22
+ Please ensure you set logging to `DEBUG` and attach any relevant log files here (or link from a gist).
@@ -0,0 +1,9 @@
1
+ # Pull request guidelines
2
+
3
+ * Please [squash your commits](squash) into one commit.
4
+ * Please use [semantic commit messages](semantic-commit-messages) so that your changes will show up correctly in the generated change log.
5
+ * Please ensure you have followed the guidelines in [CONTRIBUTING.md](./CONTRIBUTING.md)
6
+ * And please remove this text before opening a PR
7
+
8
+ [semantic-commit-messages]: http://karma-runner.github.io/2.0/dev/git-commit-msg.html
9
+ [squash]: https://github.com/todotxt/todo.txt-android/wiki/Squash-All-Commits-Related-to-a-Single-Issue-into-a-Single-Commit
data/CHANGELOG.md CHANGED
@@ -1,3 +1,31 @@
1
+ <a name="v2.17.0"></a>
2
+ ### v2.17.0 (2018-03-30)
3
+
4
+
5
+ #### Features
6
+
7
+ * ensure migrations in optimise_head_matrix work on mysql ([35874a9](/../../commit/35874a9))
8
+ * show verification number in matrix when viewing all results ([5693430](/../../commit/5693430))
9
+ * redact auth headers from rack env used to report errors ([94f8f13](/../../commit/94f8f13))
10
+ * add api error reporters ([579fa39](/../../commit/579fa39))
11
+ * log debug message when loading configuration setting from database ([9ffcc1a](/../../commit/9ffcc1a))
12
+ * optimise head matrix refresh when adding or deleting tags ([263c2a4](/../../commit/263c2a4))
13
+ * disable sinatra dump_errors ([d59c7e5](/../../commit/d59c7e5))
14
+ * send padrino logs to a file in the log dir by default ([7408be0](/../../commit/7408be0))
15
+
16
+ * **matrix ui**
17
+ * add tooltip explaining the situation when verification date is before pact publication date ([fd6e1c9](/../../commit/fd6e1c9))
18
+ * change default to show all results ([f7bea07](/../../commit/f7bea07))
19
+
20
+
21
+ #### Bug Fixes
22
+
23
+ * ensure publishing a verification does not cause a unique constraint violation ([ecfb385](/../../commit/ecfb385))
24
+ * optimize matrix query to speed up lengthy pact publication times ([e09d528](/../../commit/e09d528))
25
+ * ensure matrix is updated when pacticipant is deleted ([6c11cbe](/../../commit/6c11cbe))
26
+ * delete pacticipant labels before deleting pacticipant ([18b9b7e](/../../commit/18b9b7e))
27
+
28
+
1
29
  <a name="v2.16.1"></a>
2
30
  ### v2.16.1 (2018-03-08)
3
31
 
@@ -86,3 +86,8 @@ materialized_head_matrix table (is populated from...)
86
86
  -> versions table
87
87
  -> latest_verification_id_for_consumer_version_and_provider_version view
88
88
  -> latest_pact_publication_revision_numbers view
89
+
90
+ ### Useful to know stuff
91
+
92
+ * The supported database types are Postgres (recommended), MySQL (sigh) and Sqlite (just for testing, not recommended for production). Check the travis.yml file for the supported database versions.
93
+ * Any migration that uses the "order" column has to be defined using the Sequel DSL rather than pure SQL, because the word "order" is a key word, and it has to be escaped correctly and differently on each database (Postgres, MySQL, Sqlite).
@@ -5,8 +5,8 @@ Sequel.migration do
5
5
  FROM verifications
6
6
  GROUP BY pact_version_id")
7
7
 
8
- # The most recent verification for each pact version
9
- # provider_version is DEPRECATED, use provider_version_number
8
+ # The most recent verification for each pact_version
9
+ # provider_version column is DEPRECATED, use provider_version_number
10
10
  create_or_replace_view(:latest_verifications,
11
11
  "SELECT v.id, v.number, v.success, s.number as provider_version, v.build_url, v.pact_version_id, v.execution_date, v.created_at, v.provider_version_id, s.number as provider_version_number
12
12
  FROM verifications v
@@ -0,0 +1,80 @@
1
+ require_relative 'migration_helper'
2
+
3
+ Sequel.migration do
4
+ up do
5
+ pp = :pact_publications
6
+ # For each consumer_id/provider_id/tag_name, the version order of the latest version that has a pact
7
+ create_or_replace_view(:latest_tagged_pact_consumer_version_orders,
8
+ from(:pact_publications)
9
+ .select_group(
10
+ Sequel[pp][:provider_id],
11
+ Sequel[:cv][:pacticipant_id].as(:consumer_id),
12
+ Sequel[:t][:name].as(:tag_name))
13
+ .select_append{ max(order).as(latest_consumer_version_order) }
14
+ .join(:versions, { Sequel[pp][:consumer_version_id] => Sequel[:cv][:id] }, { table_alias: :cv} )
15
+ .join(:tags, { Sequel[:t][:version_id] => Sequel[pp][:consumer_version_id] }, { table_alias: :t })
16
+ )
17
+
18
+ # Add provider_version_order to original definition
19
+ v = :verifications
20
+ create_or_replace_view(:latest_verifications,
21
+ from(v)
22
+ .select(
23
+ Sequel[v][:id],
24
+ Sequel[v][:number],
25
+ Sequel[v][:success],
26
+ Sequel[:s][:number].as(:provider_version),
27
+ Sequel[v][:build_url],
28
+ Sequel[v][:pact_version_id],
29
+ Sequel[v][:execution_date],
30
+ Sequel[v][:created_at],
31
+ Sequel[v][:provider_version_id],
32
+ Sequel[:s][:number].as(:provider_version_number),
33
+ Sequel[:s][:order].as(:provider_version_order))
34
+ .join(:latest_verification_numbers,
35
+ {
36
+ Sequel[v][:pact_version_id] => Sequel[:lv][:pact_version_id],
37
+ Sequel[v][:number] => Sequel[:lv][:latest_number]
38
+ }, { table_alias: :lv })
39
+ .join(:versions,
40
+ {
41
+ Sequel[v][:provider_version_id] => Sequel[:s][:id]
42
+ }, { table_alias: :s })
43
+ )
44
+
45
+
46
+ create_or_replace_view(:head_matrix,
47
+ "
48
+ select
49
+ p.consumer_id, p.consumer_name, p.consumer_version_id, p.consumer_version_number, p.consumer_version_order,
50
+ p.id as pact_publication_id, p.pact_version_id, p.pact_version_sha, p.revision_number as pact_revision_number,
51
+ p.created_at as pact_created_at,
52
+ p.provider_id, p.provider_name, lv.provider_version_id, lv.provider_version_number, lv.provider_version_order,
53
+ lv.id as verification_id, lv.success, lv.number as verification_number, lv.execution_date as verification_executed_at,
54
+ lv.build_url as verification_build_url,
55
+ null as consumer_version_tag_name
56
+ from latest_pact_publications p
57
+ left outer join latest_verifications lv
58
+ on p.pact_version_id = lv.pact_version_id
59
+
60
+ union all
61
+
62
+ select
63
+ p.consumer_id, p.consumer_name, p.consumer_version_id, p.consumer_version_number, p.consumer_version_order,
64
+ p.id as pact_publication_id, p.pact_version_id, p.pact_version_sha, p.revision_number as pact_revision_number,
65
+ p.created_at as pact_created_at,
66
+ p.provider_id, p.provider_name, lv.provider_version_id, lv.provider_version_number, lv.provider_version_order,
67
+ lv.id as verification_id, lv.success, lv.number as verification_number, lv.execution_date as verification_executed_at,
68
+ lv.build_url as verification_build_url,
69
+ lt.tag_name as consumer_version_tag_name
70
+ from latest_tagged_pact_consumer_version_orders lt
71
+ inner join latest_pact_publications_by_consumer_versions p
72
+ on lt.consumer_id = p.consumer_id
73
+ and lt.provider_id = p.provider_id
74
+ and lt.latest_consumer_version_order = p.consumer_version_order
75
+ left outer join latest_verifications lv
76
+ on p.pact_version_id = lv.pact_version_id
77
+ "
78
+ )
79
+ end
80
+ end
@@ -0,0 +1,14 @@
1
+ Sequel.migration do
2
+ up do
3
+ create_table(:verification_sequence_number) do
4
+ Integer :value, null: false
5
+ end
6
+
7
+ start = (from(:verifications).max(:number) || 0) + 100
8
+ from(:verification_sequence_number).insert(value: start)
9
+ end
10
+
11
+ down do
12
+ drop_table(:verification_sequence_number)
13
+ end
14
+ end
@@ -24,7 +24,7 @@ module PactBroker
24
24
 
25
25
  def sqlite_safe string
26
26
  if adapter == 'sqlite'
27
- string.gsub(/\border\b/, '`order`')
27
+ string.gsub(/(?:\b|")order(?:"|\b)/, '`order`')
28
28
  else
29
29
  string
30
30
  end
data/lib/db.rb CHANGED
@@ -35,8 +35,9 @@ module DB
35
35
  end
36
36
 
37
37
  def self.connection_for_env env
38
- logger.info "Connecting to #{env} database."
39
- connect configuration_for_env(env)
38
+ config = configuration_for_env(env)
39
+ logger.info "Connecting to #{env} #{config['adapter']} database #{config['database']}."
40
+ connect config
40
41
  end
41
42
 
42
43
  def self.configuration_for_env env
@@ -1,4 +1,5 @@
1
1
  require 'webmachine'
2
+ require 'pact_broker/api/resources/error_handler'
2
3
  require 'pact_broker/services'
3
4
  require 'pact_broker/api/decorators'
4
5
  require 'pact_broker/logging'
@@ -15,17 +16,6 @@ module PactBroker
15
16
 
16
17
  class InvalidJsonError < StandardError ; end
17
18
 
18
- class ErrorHandler
19
-
20
- include PactBroker::Logging
21
-
22
- def self.handle_exception e, response
23
- logger.error e
24
- logger.error e.backtrace
25
- response.body = {:message => e.message, :backtrace => e.backtrace }.to_json
26
- end
27
- end
28
-
29
19
  class BaseResource < Webmachine::Resource
30
20
 
31
21
  include PactBroker::Services
@@ -40,8 +30,12 @@ module PactBroker
40
30
  PactBroker.configuration.before_resource.call(self)
41
31
  end
42
32
 
33
+ def update_matrix_after_request?
34
+ false
35
+ end
36
+
43
37
  def finish_request
44
- if !request.get? && !request.head?
38
+ if update_matrix_after_request?
45
39
  matrix_service.refresh(identifier_from_path)
46
40
  end
47
41
  PactBroker.configuration.after_resource.call(self)
@@ -86,7 +80,7 @@ module PactBroker
86
80
  end
87
81
 
88
82
  def handle_exception e
89
- PactBroker::Api::Resources::ErrorHandler.handle_exception(e, response)
83
+ PactBroker::Api::Resources::ErrorHandler.call(e, request, response)
90
84
  end
91
85
 
92
86
  def params
@@ -155,6 +149,9 @@ module PactBroker
155
149
  invalid
156
150
  end
157
151
 
152
+ def with_matrix_refresh &block
153
+ matrix_service.refresh(identifier_from_path, &block)
154
+ end
158
155
  end
159
156
  end
160
157
  end
@@ -0,0 +1,30 @@
1
+ require 'webmachine/convert_request_to_rack_env'
2
+ require 'pact_broker/configuration'
3
+
4
+ module PactBroker
5
+ module Api
6
+ module Resources
7
+ class ErrorHandler
8
+
9
+ include PactBroker::Logging
10
+
11
+ def self.call e, request, response
12
+ logger.error e
13
+ logger.error e.backtrace
14
+ response.body = {:message => e.message, :backtrace => e.backtrace }.to_json
15
+ report e, request
16
+ end
17
+
18
+ def self.report e, request
19
+ PactBroker.configuration.api_error_reporters.each do | error_notifier |
20
+ begin
21
+ error_notifier.call(e, env: Webmachine::ConvertRequestToRackEnv.call(request))
22
+ rescue StandardError => e
23
+ log_error(e, "Error executing api_error_reporter")
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -87,7 +87,9 @@ module PactBroker
87
87
  end
88
88
 
89
89
  def delete_resource
90
- pact_service.delete(pact_params)
90
+ with_matrix_refresh do
91
+ pact_service.delete(pact_params)
92
+ end
91
93
  true
92
94
  end
93
95
 
@@ -101,6 +103,9 @@ module PactBroker
101
103
  @pact_params ||= PactBroker::Pacts::PactParams.from_request request, path_info
102
104
  end
103
105
 
106
+ def update_matrix_after_request?
107
+ request.put? || request.patch?
108
+ end
104
109
  end
105
110
  end
106
111
  end
@@ -45,7 +45,9 @@ module PactBroker
45
45
  end
46
46
 
47
47
  def delete_resource
48
- pacticipant_service.delete pacticipant_name
48
+ with_matrix_refresh do
49
+ pacticipant_service.delete pacticipant_name
50
+ end
49
51
  true
50
52
  end
51
53
 
@@ -60,7 +62,11 @@ module PactBroker
60
62
  end
61
63
 
62
64
  def pacticipant_name
63
- identifier_from_path[:name]
65
+ identifier_from_path[:pacticipant_name]
66
+ end
67
+
68
+ def update_matrix_after_request?
69
+ request.patch?
64
70
  end
65
71
  end
66
72
  end
@@ -22,6 +22,7 @@ module PactBroker
22
22
  @tag = tag_service.create identifier_from_path
23
23
  # Make it return a 201 by setting the Location header
24
24
  response.headers["Location"] = tag_url(base_url, tag)
25
+ matrix_service.refresh_tags(identifier_from_path)
25
26
  end
26
27
  response.body = to_json
27
28
  end
@@ -39,10 +40,11 @@ module PactBroker
39
40
  end
40
41
 
41
42
  def delete_resource
42
- tag_service.delete identifier_from_path
43
+ matrix_service.refresh_tags(identifier_from_path) do
44
+ tag_service.delete identifier_from_path
45
+ end
43
46
  true
44
47
  end
45
-
46
48
  end
47
49
  end
48
50
 
@@ -55,12 +55,16 @@ module PactBroker
55
55
  end
56
56
 
57
57
  def next_verification_number
58
- @next_verification_number ||= verification_service.next_number_for(pact)
58
+ @next_verification_number ||= verification_service.next_number
59
59
  end
60
60
 
61
61
  def decorator_for model
62
62
  PactBroker::Api::Decorators::VerificationDecorator.new(model)
63
63
  end
64
+
65
+ def update_matrix_after_request?
66
+ request.post?
67
+ end
64
68
  end
65
69
  end
66
70
  end
@@ -25,7 +25,9 @@ module PactBroker
25
25
  end
26
26
 
27
27
  def delete_resource
28
- version_service.delete version
28
+ with_matrix_refresh do
29
+ version_service.delete version
30
+ end
29
31
  true
30
32
  end
31
33
 
@@ -41,7 +41,7 @@ module PactBroker
41
41
  # Pacticipants
42
42
  add ['pacticipants'], Api::Resources::Pacticipants, {resource_name: "pacticipants"}
43
43
  add ['pacticipants', 'label', :label_name], PactBroker::Api::Resources::PacticipantsForLabel, {resource_name: "pacticipants_for_label"}
44
- add ['pacticipants', :name], Api::Resources::Pacticipant, {resource_name: "pacticipant"}
44
+ add ['pacticipants', :pacticipant_name], Api::Resources::Pacticipant, {resource_name: "pacticipant"}
45
45
  add ['pacticipants', :pacticipant_name, 'versions'], Api::Resources::Versions, {resource_name: "pacticipant_versions"}
46
46
  add ['pacticipants', :pacticipant_name, 'versions', :pacticipant_version_number], Api::Resources::Version, {resource_name: "pacticipant_version"}
47
47
  add ['pacticipants', :pacticipant_name, 'latest-version', :tag], Api::Resources::Version, {resource_name: "latest_tagged_pacticipant_version"}
@@ -32,6 +32,7 @@ module PactBroker
32
32
 
33
33
  def set_value_on_configuration setting
34
34
  if configuration_attribute_exists? setting
35
+ logger.debug("Loading #{setting.name} configuration from database.")
35
36
  configuration.send("#{setting.name}=", get_value_from_setting(setting))
36
37
  else
37
38
  logger.warn("Could not load configuration setting \"#{setting.name}\" as there is no matching attribute on the Configuration class")
@@ -1,5 +1,9 @@
1
+ require 'pact_broker/error'
2
+
1
3
  module PactBroker
2
4
 
5
+ class ConfigurationError < PactBroker::Error; end
6
+
3
7
  def self.configuration
4
8
  @@configuration ||= Configuration.default_configuration
5
9
  end
@@ -30,6 +34,7 @@ module PactBroker
30
34
  attr_accessor :enable_public_badge_access, :shields_io_base_url
31
35
  attr_accessor :webhook_retry_schedule
32
36
  attr_accessor :disable_ssl_verification
37
+ attr_reader :api_error_reporters
33
38
  attr_writer :logger
34
39
 
35
40
  def initialize
@@ -37,6 +42,7 @@ module PactBroker
37
42
  @after_resource_hook = ->(resource){}
38
43
  @authenticate_with_basic_auth = nil
39
44
  @authorize = nil
45
+ @api_error_reporters = []
40
46
  end
41
47
 
42
48
  def logger
@@ -121,6 +127,16 @@ module PactBroker
121
127
  end
122
128
  end
123
129
 
130
+ def add_api_error_reporter &block
131
+ if block_given?
132
+ unless block.arity == 2
133
+ raise ConfigurationError.new("api_error_notfifier block must accept two arguments, 'error' and 'options'")
134
+ end
135
+ @api_error_reporters << block
136
+ nil
137
+ end
138
+ end
139
+
124
140
  def enable_badge_resources= enable_badge_resources
125
141
  puts "Pact Broker configuration property `enable_badge_resources` is deprecated. Please use `enable_public_badge_access`"
126
142
  self.enable_public_badge_access = enable_badge_resources
@@ -6,6 +6,25 @@ module PactBroker
6
6
  # Rows with a nil consumer_tag_name are the overall latest
7
7
  class HeadRow < Row
8
8
  set_dataset(:materialized_head_matrix)
9
+
10
+ dataset_module do
11
+ include PactBroker::Repositories::Helpers
12
+ include PactBroker::Logging
13
+
14
+ def refresh ids
15
+ return super unless ids[:tag_name]
16
+
17
+ logger.debug("Refreshing #{model.table_name} for #{ids}")
18
+ db = model.db
19
+ table_name = model.table_name
20
+ criteria = { consumer_id: ids[:pacticipant_id], consumer_version_tag_name: ids[:tag_name] }
21
+ db.transaction do
22
+ db[table_name].where(criteria).delete
23
+ new_rows = db[source_view_name].where(criteria)
24
+ db[table_name].insert(new_rows)
25
+ end
26
+ end
27
+ end
9
28
  end
10
29
  end
11
30
  end
@@ -22,9 +22,46 @@ module PactBroker
22
22
  GROUP_BY_PROVIDER = [:consumer_name, :consumer_version_number, :provider_name]
23
23
  GROUP_BY_PACT = [:consumer_name, :provider_name]
24
24
 
25
+ # Use a block when the refresh is caused by a resource deletion
26
+ # This allows us to store the correct object ids for use afterwards
25
27
  def refresh params
26
- PactBroker::Matrix::Row.refresh(params)
27
- PactBroker::Matrix::HeadRow.refresh(params)
28
+ criteria = find_ids_for_pacticipant_names(params)
29
+ yield if block_given?
30
+ PactBroker::Matrix::Row.refresh(criteria)
31
+ PactBroker::Matrix::HeadRow.refresh(criteria)
32
+ end
33
+
34
+ # Only need to update the HeadRow table when tags change
35
+ # because it only changes which rows are the latest tagged ones -
36
+ # it doesn't change the actual values in the underlying matrix.
37
+ def refresh_tags params
38
+ criteria = find_ids_for_pacticipant_names(params)
39
+ yield if block_given?
40
+ PactBroker::Matrix::HeadRow.refresh(criteria)
41
+ end
42
+
43
+ def find_ids_for_pacticipant_names params
44
+ criteria = {}
45
+
46
+ if params[:consumer_name] || params[:provider_name]
47
+ if params[:consumer_name]
48
+ pacticipant = PactBroker::Domain::Pacticipant.where(name_like(:name, params[:consumer_name])).single_record
49
+ criteria[:consumer_id] = pacticipant.id if pacticipant
50
+ end
51
+
52
+ if params[:provider_name]
53
+ pacticipant = PactBroker::Domain::Pacticipant.where(name_like(:name, params[:provider_name])).single_record
54
+ criteria[:provider_id] = pacticipant.id if pacticipant
55
+ end
56
+ end
57
+
58
+ if params[:pacticipant_name]
59
+ pacticipant = PactBroker::Domain::Pacticipant.where(name_like(:name, params[:pacticipant_name])).single_record
60
+ criteria[:pacticipant_id] = pacticipant.id if pacticipant
61
+ end
62
+
63
+ criteria[:tag_name] = params[:tag_name] if params[:tag_name].is_a?(String) # Could be a sym from resource parameters in api.rb
64
+ criteria
28
65
  end
29
66
 
30
67
  # Return the latest matrix row (pact/verification) for each consumer_version_number/provider_version_number
@@ -19,42 +19,30 @@ module PactBroker
19
19
  include PactBroker::Repositories::Helpers
20
20
  include PactBroker::Logging
21
21
 
22
- def refresh params
23
- logger.debug("Refreshing #{model.table_name} for #{params}")
22
+ def refresh ids
23
+ logger.debug("Refreshing #{model.table_name} for #{ids}")
24
24
 
25
25
  db = model.db
26
26
  table_name = model.table_name
27
27
 
28
- source_view_name = model.table_name.to_s.gsub('materialized_', '').to_sym
29
- if params[:consumer_name] || params[:provider_name]
30
- criteria = {}
31
- if params[:consumer_name]
32
- pacticipant = PactBroker::Domain::Pacticipant.where(name_like(:name, params[:consumer_name])).single_record
33
- criteria[:consumer_id] = pacticipant.id if pacticipant
28
+ if ids[:pacticipant_id]
29
+ db.transaction do
30
+ db[table_name].where(consumer_id: ids[:pacticipant_id]).or(provider_id: ids[:pacticipant_id]).delete
31
+ new_rows = db[source_view_name].where(consumer_id: ids[:pacticipant_id]).or(provider_id: ids[:pacticipant_id]).distinct
32
+ db[table_name].insert(new_rows)
34
33
  end
35
-
36
- if params[:provider_name]
37
- pacticipant = PactBroker::Domain::Pacticipant.where(name_like(:name, params[:provider_name])).single_record
38
- criteria[:provider_id] = pacticipant.id if pacticipant
39
- end
40
- if criteria.any?
41
- db.transaction do
42
- db[table_name].where(criteria).delete
43
- db[table_name].insert(db[source_view_name].where(criteria).distinct)
44
- end
34
+ elsif ids.any?
35
+ accepted_columns = [:consumer_id, :consumer_name, :provider_id, :provider_name]
36
+ criteria = ids.reject{ |k, v| !accepted_columns.include?(k) }
37
+ db.transaction do
38
+ db[table_name].where(criteria).delete
39
+ db[table_name].insert(db[source_view_name].where(criteria))
45
40
  end
46
41
  end
42
+ end
47
43
 
48
- if params[:pacticipant_name]
49
- pacticipant = PactBroker::Domain::Pacticipant.where(name_like(:name, params[:pacticipant_name])).single_record
50
- if pacticipant
51
- db.transaction do
52
- db[table_name].where(consumer_id: pacticipant.id).or(provider_id: pacticipant.id).delete
53
- new_rows = db[source_view_name].where(consumer_id: pacticipant.id).or(provider_id: pacticipant.id).distinct
54
- db[table_name].insert(new_rows)
55
- end
56
- end
57
- end
44
+ def source_view_name
45
+ model.table_name.to_s.gsub('materialized_', '').to_sym
58
46
  end
59
47
 
60
48
  def matching_selectors selectors
@@ -9,8 +9,12 @@ module PactBroker
9
9
  extend PactBroker::Repositories
10
10
  extend PactBroker::Services
11
11
 
12
- def refresh params
13
- matrix_repository.refresh params
12
+ def refresh params, &block
13
+ matrix_repository.refresh(params, &block)
14
+ end
15
+
16
+ def refresh_tags params, &block
17
+ matrix_repository.refresh_tags(params, &block)
14
18
  end
15
19
 
16
20
  def find criteria, options = {}
@@ -86,6 +86,7 @@ module PactBroker
86
86
  connection.run("delete from pact_versions where consumer_id = #{pacticipant.id}")
87
87
  connection.run("delete from versions where pacticipant_id = #{pacticipant.id}")
88
88
  version_repository.delete_by_id version_ids
89
+ label_repository.delete_by_pacticipant_id(pacticipant.id)
89
90
  connection.run("delete from pacticipants where id = #{pacticipant.id}")
90
91
  end
91
92
 
@@ -9,8 +9,9 @@ module PactBroker
9
9
 
10
10
  set :root, File.join(File.dirname(__FILE__), '..')
11
11
  set :show_exceptions, ENV['RACK_ENV'] != 'production'
12
+ set :dump_errors, false # The padrino logger logs these for us. If this is enabled we get duplicate logging.
12
13
 
13
14
  end
14
15
  end
15
16
  end
16
- end
17
+ end
@@ -7,7 +7,6 @@ module PactBroker
7
7
  module Controllers
8
8
  class ErrorTest < Base
9
9
  include PactBroker::Services
10
- include PactBroker::Logging
11
10
 
12
11
  get "/" do
13
12
  raise PactBroker::Error.new("Don't panic. This is a test UI error.")