pact_broker 2.16.1 → 2.17.0

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