pact_broker 2.96.0 → 2.99.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -0
  3. data/Gemfile +1 -0
  4. data/docs/CONFIGURATION.md +131 -67
  5. data/lib/db.rb +1 -7
  6. data/lib/pact_broker/api/middleware/http_debug_logs.rb +42 -0
  7. data/lib/pact_broker/api/resources/base_resource.rb +4 -0
  8. data/lib/pact_broker/api/resources/latest_pacts.rb +1 -1
  9. data/lib/pact_broker/api/resources/pact.rb +0 -8
  10. data/lib/pact_broker/api/resources/pact_content_diff.rb +7 -2
  11. data/lib/pact_broker/api/resources/pact_versions.rb +1 -5
  12. data/lib/pact_broker/api/resources/pact_versions_for_branch.rb +1 -5
  13. data/lib/pact_broker/api/resources/provider_pacts.rb +1 -1
  14. data/lib/pact_broker/api/resources/tagged_pact_versions.rb +1 -5
  15. data/lib/pact_broker/api/resources/verification.rb +0 -4
  16. data/lib/pact_broker/api/resources/verifications.rb +0 -4
  17. data/lib/pact_broker/api/resources/version.rb +8 -0
  18. data/lib/pact_broker/app.rb +3 -7
  19. data/lib/pact_broker/config/runtime_configuration.rb +24 -5
  20. data/lib/pact_broker/config/runtime_configuration_coercion_methods.rb +11 -0
  21. data/lib/pact_broker/config/runtime_configuration_database_methods.rb +2 -2
  22. data/lib/pact_broker/config/runtime_configuration_logging_methods.rb +7 -2
  23. data/lib/pact_broker/configuration.rb +2 -0
  24. data/lib/pact_broker/db/models.rb +2 -2
  25. data/lib/pact_broker/index/service.rb +1 -2
  26. data/lib/pact_broker/integrations/integration.rb +21 -6
  27. data/lib/pact_broker/integrations/service.rb +1 -1
  28. data/lib/pact_broker/matrix/every_row.rb +19 -1
  29. data/lib/pact_broker/matrix/integration.rb +5 -5
  30. data/lib/pact_broker/matrix/quick_row.rb +36 -3
  31. data/lib/pact_broker/matrix/repository.rb +4 -3
  32. data/lib/pact_broker/matrix/service.rb +0 -1
  33. data/lib/pact_broker/metrics/service.rb +2 -2
  34. data/lib/pact_broker/pacts/create_formatted_diff.rb +1 -0
  35. data/lib/pact_broker/pacts/eager_loaders.rb +4 -1
  36. data/lib/pact_broker/pacts/pact_publication.rb +9 -6
  37. data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +25 -0
  38. data/lib/pact_broker/pacts/pact_publication_wip_dataset_module.rb +0 -15
  39. data/lib/pact_broker/pacts/pact_version.rb +24 -28
  40. data/lib/pact_broker/pacts/pact_version_association_loaders.rb +36 -0
  41. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +9 -13
  42. data/lib/pact_broker/pacts/repository.rb +29 -27
  43. data/lib/pact_broker/test/http_test_data_builder.rb +11 -2
  44. data/lib/pact_broker/test/test_data_builder.rb +2 -1
  45. data/lib/pact_broker/ui/controllers/matrix.rb +14 -11
  46. data/lib/pact_broker/ui/views/groups/show.html.erb +2 -2
  47. data/lib/pact_broker/version.rb +1 -1
  48. data/pact_broker.gemspec +1 -1
  49. metadata +9 -16
  50. data/lib/pact_broker/matrix/aggregated_row.rb +0 -79
  51. data/lib/pact_broker/matrix/head_row.rb +0 -80
  52. data/lib/pact_broker/matrix/row.rb +0 -287
@@ -152,6 +152,10 @@ module PactBroker
152
152
  @request_body ||= request.body.to_s
153
153
  end
154
154
 
155
+ def any_request_body?
156
+ request_body && request_body.size > 0
157
+ end
158
+
155
159
  def consumer_name
156
160
  identifier_from_path[:consumer_name]
157
161
  end
@@ -22,7 +22,7 @@ module PactBroker
22
22
  end
23
23
 
24
24
  def policy_name
25
- :'pacts::pacts'
25
+ :'pacts::latest_pacts'
26
26
  end
27
27
  end
28
28
  end
@@ -94,14 +94,6 @@ module PactBroker
94
94
  :'pacts::pact'
95
95
  end
96
96
 
97
- def policy_pacticipant
98
- if resource_exists?
99
- consumer
100
- else
101
- nil
102
- end
103
- end
104
-
105
97
  private
106
98
 
107
99
  def pact
@@ -1,6 +1,7 @@
1
1
  require "pact_broker/api/resources/base_resource"
2
2
  require "pact_broker/pacts/pact_params"
3
3
  require "pact_broker/pacts/diff"
4
+ require "timeout"
4
5
 
5
6
  module PactBroker
6
7
  module Api
@@ -19,8 +20,12 @@ module PactBroker
19
20
  end
20
21
 
21
22
  def to_text
22
- output = PactBroker::Pacts::Diff.new.process pact_params.merge(base_url: base_url), comparison_pact_params, raw: false
23
- response.body = output
23
+ Timeout::timeout(PactBroker.configuration.pact_content_diff_timeout) do
24
+ output = PactBroker::Pacts::Diff.new.process pact_params.merge(base_url: base_url), comparison_pact_params, raw: false
25
+ response.body = output
26
+ end
27
+ rescue Timeout::Error
28
+ 408
24
29
  end
25
30
 
26
31
  def pact
@@ -32,11 +32,7 @@ module PactBroker
32
32
  end
33
33
 
34
34
  def policy_name
35
- :'pacts::pacts'
36
- end
37
-
38
- def policy_pacticipant
39
- consumer
35
+ :'pacts::pact_versions'
40
36
  end
41
37
  end
42
38
  end
@@ -28,11 +28,7 @@ module PactBroker
28
28
  end
29
29
 
30
30
  def policy_name
31
- :'pacts::pacts'
32
- end
33
-
34
- def policy_pacticipant
35
- consumer
31
+ :'pacts::pact_versions'
36
32
  end
37
33
  end
38
34
  end
@@ -20,7 +20,7 @@ module PactBroker
20
20
  end
21
21
 
22
22
  def policy_name
23
- :'pacts::pacts'
23
+ :'pacts::provider_pacts'
24
24
  end
25
25
 
26
26
  def to_json
@@ -36,11 +36,7 @@ module PactBroker
36
36
  end
37
37
 
38
38
  def policy_name
39
- :'pacts::pacts'
40
- end
41
-
42
- def policy_pacticipant
43
- consumer
39
+ :'pacts::pact_versions'
44
40
  end
45
41
  end
46
42
  end
@@ -54,10 +54,6 @@ module PactBroker
54
54
  :'verifications::verification'
55
55
  end
56
56
 
57
- def policy_pacticipant
58
- provider
59
- end
60
-
61
57
  private
62
58
 
63
59
  def verification
@@ -62,10 +62,6 @@ module PactBroker
62
62
  :'verifications::verifications'
63
63
  end
64
64
 
65
- def policy_pacticipant
66
- provider
67
- end
68
-
69
65
  private
70
66
 
71
67
  def pact
@@ -25,6 +25,14 @@ module PactBroker
25
25
  !!version
26
26
  end
27
27
 
28
+ def malformed_request?
29
+ if request.put? && any_request_body?
30
+ invalid_json?
31
+ else
32
+ false
33
+ end
34
+ end
35
+
28
36
  def from_json
29
37
  if request.really_put?
30
38
  handle_request do
@@ -29,6 +29,7 @@ require "pact_broker/api/middleware/configuration"
29
29
  require "pact_broker/api/middleware/basic_auth"
30
30
  require "pact_broker/config/basic_auth_configuration"
31
31
  require "pact_broker/api/authorization/resource_access_policy"
32
+ require "pact_broker/api/middleware/http_debug_logs"
32
33
 
33
34
  module PactBroker
34
35
 
@@ -134,17 +135,11 @@ module PactBroker
134
135
  # Keep this configuration in sync with lib/db.rb
135
136
  configuration.database_connection ||= PactBroker.create_database_connection(configuration.database_configuration, configuration.logger)
136
137
  PactBroker::DB.connection = configuration.database_connection
137
- PactBroker::DB.connection.extend_datasets do
138
- # rubocop: disable Lint/NestedMethodDefinition
139
- def any?
140
- !empty?
141
- end
142
- # rubocop: enable Lint/NestedMethodDefinition
143
- end
144
138
  PactBroker::DB.validate_connection_config if configuration.validate_database_connection_config
145
139
  PactBroker::DB.set_mysql_strict_mode_if_mysql
146
140
  PactBroker::DB.connection.extension(:pagination)
147
141
  PactBroker::DB.connection.extension(:statement_timeout)
142
+ PactBroker::DB.connection.extension(:any_not_empty)
148
143
  PactBroker::DB.connection.timezone = :utc
149
144
  Sequel.datetime_class = DateTime
150
145
  Sequel.database_timezone = :utc # Store all dates in UTC, assume any date without a TZ is UTC
@@ -180,6 +175,7 @@ module PactBroker
180
175
  end
181
176
 
182
177
  def configure_middleware
178
+ @app_builder.use PactBroker::Api::Middleware::HttpDebugLogs if configuration.http_debug_logging_enabled
183
179
  configure_basic_auth
184
180
  configure_rack_protection
185
181
  @app_builder.use Rack::PactBroker::InvalidUriProtection
@@ -39,7 +39,8 @@ module PactBroker
39
39
  log_format: nil,
40
40
  warning_error_class_names: ["Sequel::ForeignKeyConstraintViolation"],
41
41
  hide_pactflow_messages: false,
42
- log_configuration_on_startup: true
42
+ log_configuration_on_startup: true,
43
+ http_debug_logging_enabled: false
43
44
  )
44
45
 
45
46
  on_load :validate_logging_attributes!
@@ -52,9 +53,12 @@ module PactBroker
52
53
  webhook_scheme_whitelist: ["https"],
53
54
  webhook_host_whitelist: [],
54
55
  disable_ssl_verification: false,
55
- webhook_certificates: [],
56
- user_agent: "Pact Broker v#{PactBroker::VERSION}",
56
+ user_agent: "Pact Broker v#{PactBroker::VERSION}"
57
57
  )
58
+ # no default, if you set it to [] or nil, then anyway config blows up when it tries to merge in the
59
+ # numerically indexed hash from the environment variables.
60
+ attr_config :webhook_certificates
61
+ on_load :set_webhook_attribute_defaults
58
62
 
59
63
  # resource attributes
60
64
  attr_config(
@@ -67,7 +71,8 @@ module PactBroker
67
71
  badge_provider_mode: :redirect,
68
72
  enable_public_badge_access: false,
69
73
  shields_io_base_url: "https://img.shields.io",
70
- use_case_sensitive_resource_names: true
74
+ use_case_sensitive_resource_names: true,
75
+ pact_content_diff_timeout: 15
71
76
  )
72
77
 
73
78
  # domain attributes
@@ -178,8 +183,14 @@ module PactBroker
178
183
  def webhook_certificates= webhook_certificates
179
184
  if webhook_certificates.is_a?(Array)
180
185
  super(webhook_certificates.collect(&:symbolize_keys))
186
+ elsif webhook_certificates.is_a?(Hash)
187
+ if all_keys_are_number_strings?(webhook_certificates)
188
+ super(convert_hash_with_number_string_keys_to_array(webhook_certificates).collect(&:symbolize_keys))
189
+ else
190
+ raise_validation_error("webhook_certificates must be an array, or a hash where each key is an integer in string format.")
191
+ end
181
192
  elsif !webhook_certificates.nil?
182
- raise_validation_error("webhook_certificates must be an array")
193
+ raise_validation_error("webhook_certificates cannot be set using a #{webhook_certificates.class}")
183
194
  end
184
195
  end
185
196
 
@@ -208,6 +219,14 @@ module PactBroker
208
219
  def raise_validation_error(msg)
209
220
  raise PactBroker::ConfigurationError, msg
210
221
  end
222
+
223
+ def set_webhook_attribute_defaults
224
+ # can't set a default on this, or anyway config blows up when trying to merge the
225
+ # hash from the env vars into an array/nil.
226
+ if webhook_certificates.nil?
227
+ self.webhook_certificates = []
228
+ end
229
+ end
211
230
  end
212
231
  end
213
232
  end
@@ -4,6 +4,17 @@ require "pact_broker/config/space_delimited_integer_list"
4
4
  module PactBroker
5
5
  module Config
6
6
  module RuntimeConfigurationCoercionMethods
7
+
8
+ def all_keys_are_number_strings?(hash)
9
+ hash.keys.all? { | k | k.to_s.to_i.to_s == k } # is an integer as a string
10
+ end
11
+
12
+ def convert_hash_with_number_string_keys_to_array(hash)
13
+ hash.keys.collect{ |k| [k, k.to_i]}.sort_by(&:last).collect(&:first).collect do | key |
14
+ hash[key]
15
+ end
16
+ end
17
+
7
18
  def value_to_string_array value, property_name
8
19
  if value.is_a?(String)
9
20
  PactBroker::Config::SpaceDelimitedStringList.parse(value)
@@ -16,7 +16,7 @@ module PactBroker
16
16
  database_port: nil,
17
17
  database_url: nil,
18
18
  database_sslmode: nil,
19
- sql_log_level: :debug,
19
+ sql_log_level: :none,
20
20
  sql_log_warn_duration: 5,
21
21
  sql_enable_caller_logging: false,
22
22
  database_max_connections: nil,
@@ -82,7 +82,7 @@ module PactBroker
82
82
  private :postgres?
83
83
 
84
84
  def driver_options
85
- if postgres?
85
+ if postgres? && database_statement_timeout
86
86
  { options: "-c statement_timeout=#{database_statement_timeout}s" }
87
87
  end
88
88
  end
@@ -24,12 +24,17 @@ module PactBroker
24
24
  module InstanceMethods
25
25
  # base_url raises a not implemented error
26
26
  def log_configuration(logger)
27
- to_source_trace.without("base_url").each_with_object({})do | (key, details), new_hash |
28
- new_hash[key] = details.merge(value: self.send(key.to_sym))
27
+ source_info = to_source_trace
28
+ (self.class.config_attributes - [:base_url]).collect(&:to_s).each_with_object({})do | key, new_hash |
29
+ new_hash[key] = {
30
+ value: self.send(key.to_sym),
31
+ source: source_info.dig(key, :source) || {:type=>:defaults}
32
+ }
29
33
  end.sort_by { |key, _| key }.each { |key, value| log_config_inner(key, value, logger) }
30
34
  end
31
35
 
32
36
  def log_config_inner(key, value, logger)
37
+ # TODO fix the source display for webhook_certificates set by environment variables
33
38
  if !value.has_key? :value
34
39
  value.sort_by { |inner_key, _| inner_key }.each { |inner_key, inner_value| log_config_inner("#{key}.#{inner_key}", inner_value, logger) }
35
40
  elsif self.class.sensitive_value?(key)
@@ -55,6 +55,8 @@ module PactBroker
55
55
  config.version_parser = PactBroker::Versions::ParseSemanticVersion
56
56
  config.sha_generator = PactBroker::Pacts::GenerateSha
57
57
  config.example_data_seeder = lambda do
58
+ # Do the require in the lambda, not at the top of the file, because we need
59
+ # the database connection to be made before loading any Sequel::Model classes.
58
60
  require "pact_broker/db/seed_example_data"
59
61
  PactBroker::DB::SeedExampleData.call
60
62
  end
@@ -14,11 +14,11 @@ require "pact_broker/domain/pacticipant"
14
14
  require "pact_broker/deployments/environment"
15
15
  require "pact_broker/deployments/deployed_version"
16
16
  require "pact_broker/deployments/released_version"
17
- require "pact_broker/matrix/row"
18
- require "pact_broker/matrix/head_row"
19
17
  require "pact_broker/versions/branch"
20
18
  require "pact_broker/versions/branch_version"
21
19
  require "pact_broker/versions/branch_head"
20
+ require "pact_broker/matrix/quick_row"
21
+ require "pact_broker/matrix/every_row"
22
22
 
23
23
  module PactBroker
24
24
  INTEGRATIONS_TABLES = [
@@ -1,10 +1,9 @@
1
1
  require "pact_broker/repositories"
2
2
  require "pact_broker/logging"
3
3
  require "pact_broker/domain/index_item"
4
- require "pact_broker/matrix/head_row"
5
- require "pact_broker/matrix/aggregated_row"
6
4
  require "pact_broker/repositories/helpers"
7
5
  require "pact_broker/index/page"
6
+ require "pact_broker/verifications/latest_verification_for_consumer_version_tag"
8
7
 
9
8
  module PactBroker
10
9
  module Index
@@ -3,6 +3,7 @@ require "pact_broker/verifications/pseudo_branch_status"
3
3
  require "pact_broker/domain/verification"
4
4
  require "pact_broker/webhooks/latest_triggered_webhook"
5
5
  require "pact_broker/webhooks/webhook"
6
+ require "pact_broker/verifications/latest_verification_for_consumer_and_provider"
6
7
 
7
8
  module PactBroker
8
9
  module Integrations
@@ -21,17 +22,30 @@ module PactBroker
21
22
  integration.associations[:latest_pact] = nil
22
23
  end
23
24
 
24
- PactBroker::Pacts::PactPublication.overall_latest.each do | pact |
25
- eo_opts[:rows].each do | integration |
26
- if integration.consumer_id == pact.consumer_id && integration.provider_id == pact.provider_id
27
- integration.associations[:latest_pact] = pact
28
- end
25
+
26
+ # Would prefer to be able to eager load only the fields specified in the original Integrations
27
+ # query, but we don't seem to have that information in this context.
28
+ # Need the latest verification for the verification status in the index response.
29
+ latest_pact_publications_query = PactBroker::Pacts::PactPublication
30
+ .eager_for_domain_with_content
31
+ .eager(pact_version: :latest_verification)
32
+ .overall_latest
33
+
34
+ latest_pact_publications_query.all.each do | pact |
35
+ eo_opts[:id_map][[pact.consumer_id, pact.provider_id]]&.each do | integration |
36
+ integration.associations[:latest_pact] = pact
29
37
  end
30
38
  end
31
39
  end
32
40
 
33
41
  one_to_one(:latest_pact, class: "PactBroker::Pacts::PactPublication", :key => [:consumer_id, :provider_id], primary_key: [:consumer_id, :provider_id], :eager_loader=> LATEST_PACT_EAGER_LOADER) do | _ds |
34
- PactBroker::Pacts::PactPublication.overall_latest_for_consumer_id_and_provider_id(consumer_id, provider_id)
42
+ # Would prefer to be able to eager load only the fields specified in the original Integrations
43
+ # query, but we don't seem to have that information in this context.
44
+ # Need the latest verification for the verification status in the index response.
45
+ PactBroker::Pacts::PactPublication
46
+ .eager_for_domain_with_content
47
+ .eager(pact_version: :latest_verification)
48
+ .overall_latest_for_consumer_id_and_provider_id(consumer_id, provider_id)
35
49
  end
36
50
 
37
51
  # When viewing the index, every webhook in the database will match at least one of the rows, so
@@ -65,6 +79,7 @@ module PactBroker
65
79
  end
66
80
  end
67
81
 
82
+ # TODO make this the verification status for the latest from main branch
68
83
  def verification_status_for_latest_pact
69
84
  @verification_status_for_latest_pact ||= PactBroker::Verifications::PseudoBranchStatus.new(latest_pact, latest_pact&.latest_verification)
70
85
  end
@@ -26,7 +26,7 @@ module PactBroker
26
26
  scope_for(PactBroker::Integrations::Integration)
27
27
  .eager(:consumer)
28
28
  .eager(:provider)
29
- .eager(latest_pact: [:latest_verification, :pact_version])
29
+ .eager(:latest_pact) # latest_pact eager loader is custom, can't take any more options
30
30
  .eager(:latest_verification)
31
31
  .all
32
32
  .sort { | a, b| Integration.compare_by_last_action_date(a, b) }
@@ -17,15 +17,19 @@ module PactBroker
17
17
  Sequel[:p][:created_at].as(:consumer_version_created_at),
18
18
  Sequel[:p][:id].as(:pact_order)
19
19
  ]
20
+
20
21
  VERIFICATION_COLUMNS = [
21
22
  Sequel[:v][:id].as(:verification_id),
22
23
  Sequel[:v][:provider_version_id],
23
24
  Sequel[:v][:created_at].as(:provider_version_created_at)
24
25
  ]
25
26
 
27
+ JOINED_VERIFICATION_COLUMNS = [:id, :pact_version_id, :provider_id, :provider_version_id, :created_at]
28
+
26
29
  ALL_COLUMNS = PACT_COLUMNS + VERIFICATION_COLUMNS
27
30
 
28
31
  SELECT_ALL_COLUMN_ARGS = [:select_all_columns] + ALL_COLUMNS
32
+
29
33
  dataset_module do
30
34
  select(*SELECT_ALL_COLUMN_ARGS)
31
35
 
@@ -33,9 +37,23 @@ module PactBroker
33
37
  left_outer_join(:verifications, P_V_JOIN, { table_alias: :v } )
34
38
  end
35
39
 
40
+ def inner_join_verifications
41
+ join(:verifications, P_V_JOIN, { table_alias: :v } )
42
+ end
43
+
44
+ def inner_join_verifications_matching_one_selector_provider_or_provider_version(query_ids)
45
+ verifications = db[:verifications]
46
+ .select(*JOINED_VERIFICATION_COLUMNS)
47
+ .where {
48
+ QueryBuilder.provider_or_provider_version_matches(query_ids)
49
+ }
50
+
51
+ join(verifications, P_V_JOIN, { table_alias: :v } )
52
+ end
53
+
36
54
  def verifications_for(query_ids)
37
55
  db[:verifications]
38
- .select(:id, :pact_version_id, :provider_id, :provider_version_id, :created_at)
56
+ .select(*JOINED_VERIFICATION_COLUMNS)
39
57
  .where {
40
58
  Sequel.&(
41
59
  QueryBuilder.consumer_in_pacticipant_ids(query_ids),
@@ -1,9 +1,9 @@
1
-
2
1
  # Represents the integration relationship between a consumer and a provider in the context
3
2
  # of a matrix or can-i-deploy query.
4
- # If the required flag is set, then one of the pacticipants (consumers) specified in the HTTP query
5
- # requires the provider. It would not be required if a provider was specified, and it had an
6
- # integration with a consumer.
3
+ # If the required flag is set, then one of the pacticipants specified in the matrix query
4
+ # is a consumer and it requires the provider to be already deployed. An integration would not be required if a provider
5
+ # was specified, and it had an integration with a consumer, but that consumer wasn't deployed yet.
6
+ #
7
7
 
8
8
  module PactBroker
9
9
  module Matrix
@@ -11,7 +11,7 @@ module PactBroker
11
11
 
12
12
  attr_reader :consumer_name, :consumer_id, :provider_name, :provider_id
13
13
 
14
- def initialize consumer_id, consumer_name, provider_id, provider_name, required
14
+ def initialize(consumer_id, consumer_name, provider_id, provider_name, required)
15
15
  @consumer_id = consumer_id
16
16
  @consumer_name = consumer_name
17
17
  @provider_id = provider_id
@@ -11,6 +11,14 @@ require "pact_broker/pacts/pact_publication"
11
11
  require "pact_broker/tags/tag_with_latest_flag"
12
12
  require "pact_broker/matrix/query_ids"
13
13
 
14
+ # The PactBroker::Matrix::QuickRow represents a row in the table that is created when
15
+ # the consumer versions are joined to the provider versions via the pacts and verifications tables,
16
+ # aka "The Matrix". The difference between this class and the EveryRow class is that
17
+ # the EveryRow class includes results for overridden pact verisons and verifications (used only when there is no latestby
18
+ # set in the matrix query), where as the QuickRow class does not.
19
+ # It is called the QuickRow because the initial implementation was called the Row, and this is an optimised
20
+ # version. It needs to be renamed back to Row now that the old Row class has been deleted.
21
+
14
22
  # The difference between `join_verifications_for` and `join_verifications` is that
15
23
  # the left outer join is done on a pre-filtered dataset in `join_verifications_for`,
16
24
  # so that we get a row with null verification fields for a pact that has been verified
@@ -19,6 +27,7 @@ require "pact_broker/matrix/query_ids"
19
27
 
20
28
  module PactBroker
21
29
  module Matrix
30
+ # TODO rename this to just Row
22
31
  # rubocop: disable Metrics/ClassLength
23
32
  class QuickRow < Sequel::Model(Sequel.as(:latest_pact_publication_ids_for_consumer_versions, :p))
24
33
 
@@ -45,6 +54,15 @@ module PactBroker
45
54
  Sequel[:v][:verification_id],
46
55
  Sequel[:v][:created_at].as(:provider_version_created_at)
47
56
  ]
57
+
58
+ JOINED_VERIFICATION_COLUMNS = [
59
+ :verification_id,
60
+ :provider_version_id,
61
+ :pact_version_id,
62
+ :provider_id,
63
+ :created_at
64
+ ]
65
+
48
66
  LAST_ACTION_DATE = Sequel.lit("CASE WHEN (provider_version_created_at IS NOT NULL AND provider_version_created_at > consumer_version_created_at) THEN provider_version_created_at ELSE consumer_version_created_at END").as(:last_action_date)
49
67
 
50
68
  ALL_COLUMNS = PACT_COLUMNS + VERIFICATION_COLUMNS
@@ -146,10 +164,15 @@ module PactBroker
146
164
  # When we have one selector, we need to join ALL the verifications to find out
147
165
  # what integrations exist
148
166
  def matching_one_selector(selectors)
149
- join_verifications
167
+ query_ids = QueryIds.from_selectors(selectors)
168
+ rows_where_selector_matches_consumer_cols = join_verifications
150
169
  .where {
151
- QueryBuilder.consumer_or_consumer_version_or_provider_or_provider_or_provider_version_match(QueryIds.from_selectors(selectors), :p, :v)
170
+ QueryBuilder.consumer_or_consumer_version_matches(query_ids, :p)
152
171
  }
172
+
173
+ rows_where_selector_matches_provider_cols = inner_join_verifications_matching_one_selector_provider_or_provider_version(query_ids)
174
+
175
+ rows_where_selector_matches_consumer_cols.union(rows_where_selector_matches_provider_cols)
153
176
  end
154
177
 
155
178
  def pacticipant_ids_matching_one_selector_optimised(selectors)
@@ -229,9 +252,19 @@ module PactBroker
229
252
  left_outer_join(verifications_for(query_ids), LP_LV_JOIN, { table_alias: :v } )
230
253
  end
231
254
 
255
+ def inner_join_verifications_matching_one_selector_provider_or_provider_version(query_ids)
256
+ verifications = db[LV]
257
+ .select(*JOINED_VERIFICATION_COLUMNS)
258
+ .where {
259
+ QueryBuilder.provider_or_provider_version_matches(query_ids)
260
+ }
261
+
262
+ join(verifications, LP_LV_JOIN, { table_alias: :v } )
263
+ end
264
+
232
265
  def verifications_for(query_ids)
233
266
  db[LV]
234
- .select(:verification_id, :provider_version_id, :pact_version_id, :provider_id, :created_at)
267
+ .select(*JOINED_VERIFICATION_COLUMNS)
235
268
  .where {
236
269
  Sequel.&(
237
270
  QueryBuilder.consumer_in_pacticipant_ids(query_ids),
@@ -1,9 +1,7 @@
1
1
  require "pact_broker/logging"
2
2
  require "pact_broker/repositories/helpers"
3
- require "pact_broker/matrix/row"
4
3
  require "pact_broker/matrix/quick_row"
5
4
  require "pact_broker/matrix/every_row"
6
- require "pact_broker/matrix/head_row"
7
5
  require "pact_broker/error"
8
6
  require "pact_broker/matrix/query_results"
9
7
  require "pact_broker/matrix/integration"
@@ -24,7 +22,8 @@ module PactBroker
24
22
 
25
23
  # TODO move latest verification logic in to database
26
24
 
27
- TP_COLS = PactBroker::Matrix::Row::TP_COLS
25
+ # Used when using table_print to output query results
26
+ TP_COLS = [ :consumer_version_number, :pact_revision_number, :provider_version_number, :verification_number]
28
27
 
29
28
  GROUP_BY_PROVIDER_VERSION_NUMBER = [:consumer_name, :consumer_version_number, :provider_name, :provider_version_number]
30
29
  GROUP_BY_PROVIDER = [:consumer_name, :consumer_version_number, :provider_name]
@@ -124,6 +123,8 @@ module PactBroker
124
123
  end
125
124
  end
126
125
 
126
+ # Why does the consumer equivalent of this method use the QuickRow distinct_integrations_for_selector_as_consumer
127
+ # while this method uses the Integration?
127
128
  def integrations_where_specified_selector_is_provider(resolved_specified_selectors)
128
129
  integrations_involving_specified_providers = PactBroker::Integrations::Integration
129
130
  .where(provider_id: resolved_specified_selectors.collect(&:pacticipant_id))
@@ -1,6 +1,5 @@
1
1
  require "pact_broker/logging"
2
2
  require "pact_broker/repositories"
3
- require "pact_broker/matrix/row"
4
3
  require "pact_broker/matrix/deployment_status_summary"
5
4
  require "pact_broker/matrix/query_results_with_deployment_status_summary"
6
5
  require "pact_broker/messages"
@@ -118,8 +118,8 @@ module PactBroker
118
118
 
119
119
  def matrix_count
120
120
  begin
121
- PactBroker::Matrix::Row.db.with_statement_timeout(PactBroker.configuration.metrics_sql_statement_timeout) do
122
- PactBroker::Matrix::Row.count
121
+ PactBroker::Matrix::EveryRow.db.with_statement_timeout(PactBroker.configuration.metrics_sql_statement_timeout) do
122
+ PactBroker::Matrix::EveryRow.default_scope.count
123
123
  end
124
124
  rescue Sequel::DatabaseError => _ex
125
125
  -1
@@ -19,6 +19,7 @@ module PactBroker
19
19
  end
20
20
 
21
21
  difference = diff(previous_pact_hash, pact_hash)
22
+
22
23
  Pact::Matchers::UnixDiffFormatter.call(difference, colour: false, include_explanation: false)
23
24
  end
24
25
  end
@@ -32,7 +32,10 @@ module PactBroker
32
32
 
33
33
  pact_publications.each do | pact_publication |
34
34
  pact_publication.consumer_version_tags.collect(&:name).sort.each do | tag_name |
35
- pact_publication.associations[:head_pact_publications_for_tags] << head_pact_publications_by_tag[tag_name]
35
+ # Not sure how this can ever be nil, but a PF error suggests that it has happend. Maybe a timing issue?
36
+ if head_pact_publications_by_tag[tag_name]
37
+ pact_publication.associations[:head_pact_publications_for_tags] << head_pact_publications_by_tag[tag_name]
38
+ end
36
39
  end
37
40
  end
38
41
  end