pact_broker 2.95.0 → 2.97.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/Gemfile +1 -0
  4. data/docs/CONFIGURATION.md +98 -66
  5. data/lib/db.rb +2 -7
  6. data/lib/pact_broker/api/middleware/http_debug_logs.rb +36 -0
  7. data/lib/pact_broker/api/resources/base_resource.rb +273 -1
  8. data/lib/pact_broker/api/resources/default_base_resource.rb +0 -280
  9. data/lib/pact_broker/app.rb +1 -7
  10. data/lib/pact_broker/config/basic_auth_configuration.rb +7 -0
  11. data/lib/pact_broker/config/runtime_configuration.rb +20 -3
  12. data/lib/pact_broker/config/runtime_configuration_coercion_methods.rb +11 -0
  13. data/lib/pact_broker/config/runtime_configuration_database_methods.rb +6 -1
  14. data/lib/pact_broker/config/runtime_configuration_logging_methods.rb +13 -2
  15. data/lib/pact_broker/configuration.rb +3 -17
  16. data/lib/pact_broker/db/models.rb +2 -2
  17. data/lib/pact_broker/index/service.rb +1 -2
  18. data/lib/pact_broker/integrations/integration.rb +21 -6
  19. data/lib/pact_broker/integrations/service.rb +1 -1
  20. data/lib/pact_broker/matrix/repository.rb +11 -12
  21. data/lib/pact_broker/matrix/service.rb +0 -1
  22. data/lib/pact_broker/metrics/service.rb +2 -2
  23. data/lib/pact_broker/pacts/lazy_loaders.rb +26 -0
  24. data/lib/pact_broker/pacts/pact_publication.rb +16 -31
  25. data/lib/pact_broker/pacts/pact_version.rb +24 -28
  26. data/lib/pact_broker/pacts/pact_version_association_loaders.rb +36 -0
  27. data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +16 -12
  28. data/lib/pact_broker/pacts/repository.rb +29 -24
  29. data/lib/pact_broker/repositories/helpers.rb +8 -0
  30. data/lib/pact_broker/test/http_test_data_builder.rb +8 -1
  31. data/lib/pact_broker/test/test_data_builder.rb +2 -1
  32. data/lib/pact_broker/ui/controllers/matrix.rb +14 -11
  33. data/lib/pact_broker/version.rb +1 -1
  34. data/pact_broker.gemspec +1 -1
  35. metadata +9 -16
  36. data/lib/pact_broker/matrix/aggregated_row.rb +0 -79
  37. data/lib/pact_broker/matrix/head_row.rb +0 -80
  38. data/lib/pact_broker/matrix/row.rb +0 -287
@@ -31,6 +31,11 @@ module PactBroker
31
31
  database_connection_validation_timeout: nil
32
32
  )
33
33
 
34
+ coerce_types(
35
+ database_username: :string,
36
+ database_password: :string
37
+ )
38
+
34
39
  def database_configuration
35
40
  database_credentials
36
41
  .merge(
@@ -77,7 +82,7 @@ module PactBroker
77
82
  private :postgres?
78
83
 
79
84
  def driver_options
80
- if postgres?
85
+ if postgres? && database_statement_timeout
81
86
  { options: "-c statement_timeout=#{database_statement_timeout}s" }
82
87
  end
83
88
  end
@@ -1,8 +1,11 @@
1
1
  require "uri"
2
+ require "pact_broker/hash_refinements"
2
3
 
3
4
  module PactBroker
4
5
  module Config
5
6
  module RuntimeConfigurationLoggingMethods
7
+ using PactBroker::HashRefinements
8
+
6
9
  module ClassMethods
7
10
  def sensitive_values(*values)
8
11
  @sensitive_values ||= []
@@ -19,17 +22,25 @@ module PactBroker
19
22
  end
20
23
 
21
24
  module InstanceMethods
25
+ # base_url raises a not implemented error
22
26
  def log_configuration(logger)
23
- to_source_trace.sort_by { |key, _| key }.each { |key, value| log_config_inner(key, value, logger) }
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
+ }
33
+ end.sort_by { |key, _| key }.each { |key, value| log_config_inner(key, value, logger) }
24
34
  end
25
35
 
26
36
  def log_config_inner(key, value, logger)
37
+ # TODO fix the source display for webhook_certificates set by environment variables
27
38
  if !value.has_key? :value
28
39
  value.sort_by { |inner_key, _| inner_key }.each { |inner_key, inner_value| log_config_inner("#{key}.#{inner_key}", inner_value, logger) }
29
40
  elsif self.class.sensitive_value?(key)
30
41
  logger.info "#{key}=#{redact(key, value[:value])} source=#{value[:source]}"
31
42
  else
32
- logger.info "#{key}=#{value[:value]} source=#{value[:source]}"
43
+ logger.info "#{key}=#{value[:value].inspect} source=#{value[:source]}"
33
44
  end
34
45
  end
35
46
  private :log_config_inner
@@ -15,10 +15,6 @@ module PactBroker
15
15
  RequestStore.store[:pact_broker_configuration] = configuration
16
16
  end
17
17
 
18
- def self.with_runtime_configuration_overrides(overrides, &block)
19
- self.configuration.with_runtime_configuration_overrides(overrides, &block)
20
- end
21
-
22
18
  # @private, for testing only
23
19
  def self.reset_configuration
24
20
  RequestStore.store[:pact_broker_configuration] = Configuration.default_configuration
@@ -35,7 +31,7 @@ module PactBroker
35
31
  attr_accessor :content_security_policy, :hal_browser_content_security_policy_overrides
36
32
  attr_accessor :api_error_reporters
37
33
  attr_reader :custom_logger
38
- attr_accessor :policy_builder, :policy_scope_builder, :base_resource_class_factory
34
+ attr_accessor :policy_builder, :policy_scope_builder
39
35
  alias_method :policy_finder=, :policy_builder=
40
36
  alias_method :policy_scope_finder=, :policy_scope_builder=
41
37
 
@@ -59,6 +55,8 @@ module PactBroker
59
55
  config.version_parser = PactBroker::Versions::ParseSemanticVersion
60
56
  config.sha_generator = PactBroker::Pacts::GenerateSha
61
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.
62
60
  require "pact_broker/db/seed_example_data"
63
61
  PactBroker::DB::SeedExampleData.call
64
62
  end
@@ -79,21 +77,9 @@ module PactBroker
79
77
  }
80
78
  config.policy_builder = -> (object) { DefaultPolicy.new(nil, object) }
81
79
  config.policy_scope_builder = -> (scope) { scope }
82
- config.base_resource_class_factory = -> () {
83
- require "pact_broker/api/resources/default_base_resource"
84
- PactBroker::Api::Resources::DefaultBaseResource
85
- }
86
80
  config
87
81
  end
88
82
 
89
- def with_runtime_configuration_overrides(overrides)
90
- original_runtime_configuration = runtime_configuration
91
- self.runtime_configuration = override_runtime_configuration!(overrides)
92
- yield
93
- ensure
94
- self.runtime_configuration = original_runtime_configuration
95
- end
96
-
97
83
  def override_runtime_configuration!(overrides)
98
84
  new_runtime_configuration = runtime_configuration.dup
99
85
  valid_overrides = {}
@@ -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) }
@@ -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]
@@ -84,7 +83,7 @@ module PactBroker
84
83
 
85
84
  def find_integrations_for_specified_selectors(resolved_specified_selectors, options)
86
85
  if infer_selectors_for_integrations?(options)
87
- find_integrations_for_specified_selectors_with_inferred_integrations(resolved_specified_selectors, options)
86
+ find_integrations_for_specified_selectors_with_inferred_integrations(resolved_specified_selectors)
88
87
  else
89
88
  find_integrations_for_specified_selectors_only(resolved_specified_selectors)
90
89
  end
@@ -101,9 +100,9 @@ module PactBroker
101
100
  end
102
101
  end
103
102
 
104
- def find_integrations_for_specified_selectors_with_inferred_integrations(resolved_specified_selectors, options)
103
+ def find_integrations_for_specified_selectors_with_inferred_integrations(resolved_specified_selectors)
105
104
  integrations = integrations_where_specified_selector_is_consumer(resolved_specified_selectors) +
106
- integrations_where_specified_selector_is_provider(resolved_specified_selectors, options)
105
+ integrations_where_specified_selector_is_provider(resolved_specified_selectors)
107
106
  deduplicate_integrations(integrations)
108
107
  end
109
108
 
@@ -118,28 +117,25 @@ module PactBroker
118
117
  consumer_name: integration[:consumer_name],
119
118
  provider_id: integration[:provider_id],
120
119
  provider_name: integration[:provider_name],
121
- required: true
120
+ required: true # synchronous consumer requires the provider to be present
122
121
  )
123
122
  end
124
123
  end
125
124
  end
126
125
 
127
- def integrations_where_specified_selector_is_provider(resolved_specified_selectors, options)
126
+ def integrations_where_specified_selector_is_provider(resolved_specified_selectors)
128
127
  integrations_involving_specified_providers = PactBroker::Integrations::Integration
129
128
  .where(provider_id: resolved_specified_selectors.collect(&:pacticipant_id))
130
129
  .eager(:consumer, :provider)
131
130
  .all
132
131
 
133
- destination_selector = PactBroker::Matrix::UnresolvedSelector.new(options.slice(:latest, :tag, :branch, :environment_name).compact)
134
- required = PactBroker::Domain::Version.for_selector(destination_selector).pacticipants_set
135
-
136
132
  integrations_involving_specified_providers.collect do | integration |
137
133
  Integration.from_hash(
138
134
  consumer_id: integration.consumer.id,
139
135
  consumer_name: integration.consumer.name,
140
136
  provider_id: integration.provider.id,
141
137
  provider_name: integration.provider.name,
142
- required: required.member?(integration.consumer.id)
138
+ required: false # synchronous provider does not require the consumer to be present
143
139
  )
144
140
  end
145
141
  end
@@ -263,6 +259,9 @@ module PactBroker
263
259
  end
264
260
  end
265
261
 
262
+ # The user has specified --to TAG or --to-environment ENVIRONMENT in the CLI
263
+ # (or nothing, which to defaults to "with the latest version of the other integrated applications")
264
+ # The branch isn't implemented in the CLI yet (March 2022), but the API supports it.
266
265
  def infer_selectors_for_integrations?(options)
267
266
  options[:latest] || options[:tag] || options[:branch] || options[:environment_name]
268
267
  end
@@ -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
@@ -9,6 +9,32 @@ module PactBroker
9
9
  .latest_for_consumer_tag(consumer_version_tag_names)
10
10
  .from_self.order_by(:tag_name)
11
11
  }
12
+
13
+ LATEST_VERIFICATION_FOR_CONSUMER_BRANCHES = lambda {
14
+ bv_pp_join = {
15
+ Sequel[:branch_versions][:version_id] => Sequel[:pact_publications][:consumer_version_id],
16
+ Sequel[:pact_publications][:provider_id] => provider_id
17
+ }
18
+
19
+ verifications_join = {
20
+ Sequel[:verifications][:pact_version_id] => Sequel[:pact_publications][:pact_version_id]
21
+ }
22
+
23
+ branch_ids = PactBroker::Versions::BranchVersion
24
+ .select(:branch_id)
25
+ .where(version_id: consumer_version_id)
26
+
27
+
28
+ latest_verification_id = PactBroker::Versions::BranchVersion
29
+ .select(Sequel[:verifications][:id])
30
+ .where(Sequel[:branch_versions][:branch_id] => branch_ids)
31
+ .join(:pact_publications, bv_pp_join)
32
+ .join(:verifications, verifications_join)
33
+ .order(Sequel.desc(Sequel[:verifications][:id]))
34
+ .limit(1)
35
+
36
+ PactBroker::Domain::Verification.where(id: latest_verification_id)
37
+ }
12
38
  end
13
39
  end
14
40
  end
@@ -24,8 +24,7 @@ module PactBroker
24
24
  associate(:many_to_one, :consumer, :class => "PactBroker::Domain::Pacticipant", :key => :consumer_id, :primary_key => :id)
25
25
  associate(:many_to_one, :consumer_version, :class => "PactBroker::Domain::Version", :key => :consumer_version_id, :primary_key => :id)
26
26
  associate(:many_to_one, :pact_version, class: "PactBroker::Pacts::PactVersion", :key => :pact_version_id, :primary_key => :id)
27
- associate(:many_to_one, :integration, class: "PactBroker::Integrations::Integration", key: [:consumer_id, :provider_id], primary_key: [:consumer_id, :provider_id])
28
-
27
+ associate(:many_to_one, :integration, class: "PactBroker::Integrations::Integration", key: [:consumer_id, :provider_id], primary_key: [:consumer_id, :provider_id], read_only: true, forbid_lazy_load: false)
29
28
  # TODO rename to consumer_version_tags
30
29
  associate(:one_to_many, :tags, :class => "PactBroker::Domain::Tag", :key => :version_id, :primary_key => :consumer_version_id)
31
30
 
@@ -34,43 +33,19 @@ module PactBroker
34
33
  read_only: true,
35
34
  key: :id,
36
35
  primary_key: :id,
37
- dataset: lambda {
38
-
39
- bv_pp_join = {
40
- Sequel[:branch_versions][:version_id] => Sequel[:pact_publications][:consumer_version_id],
41
- Sequel[:pact_publications][:provider_id] => provider_id
42
- }
43
-
44
- verifications_join = {
45
- Sequel[:verifications][:pact_version_id] => Sequel[:pact_publications][:pact_version_id]
46
- }
47
-
48
- branch_ids = PactBroker::Versions::BranchVersion
49
- .select(:branch_id)
50
- .where(version_id: consumer_version_id)
51
-
52
-
53
- latest_verification_id = PactBroker::Versions::BranchVersion
54
- .select(Sequel[:verifications][:id])
55
- .where(Sequel[:branch_versions][:branch_id] => branch_ids)
56
- .join(:pact_publications, bv_pp_join)
57
- .join(:verifications, verifications_join)
58
- .order(Sequel.desc(Sequel[:verifications][:id]))
59
- .limit(1)
60
-
61
- PactBroker::Domain::Verification.where(id: latest_verification_id)
62
- },
36
+ forbid_lazy_load: false,
37
+ dataset: PactBroker::Pacts::LazyLoaders::LATEST_VERIFICATION_FOR_CONSUMER_BRANCHES,
63
38
  eager_loader: proc do | _ |
64
39
  raise NotImplementedError
65
40
  end
66
41
  )
67
42
 
68
-
69
43
  one_to_many(:head_pact_publications_for_tags,
70
44
  class: PactPublication,
71
45
  read_only: true,
72
46
  dataset: PactBroker::Pacts::LazyLoaders::HEAD_PACT_PUBLICATIONS_FOR_TAGS,
73
- eager_loader: PactBroker::Pacts::EagerLoaders::HeadPactPublicationsForTags
47
+ eager_loader: PactBroker::Pacts::EagerLoaders::HeadPactPublicationsForTags,
48
+ forbid_lazy_load: false
74
49
  )
75
50
 
76
51
  plugin :upsert, identifying_columns: [:consumer_version_id, :provider_id, :revision_number]
@@ -81,6 +56,10 @@ module PactBroker
81
56
  include PactPublicationDatasetModule
82
57
  include PactPublicationCleanSelectorDatasetModule
83
58
  include PactPublicationWipDatasetModule
59
+
60
+ def eager_for_domain_with_content
61
+ eager(:tags, :consumer, :provider, :consumer_version, :pact_version)
62
+ end
84
63
  end
85
64
 
86
65
  def self.subtract(a, *b)
@@ -105,8 +84,14 @@ module PactBroker
105
84
  .collect { | head_pact_publication| head_pact_publication.values.fetch(:tag_name) }
106
85
  end
107
86
 
87
+ # If the consumer_version is already loaded, and it already has tags, use those
88
+ # otherwise, load them directly.
108
89
  def consumer_version_tags
109
- tags
90
+ if associations[:consumer_version] && associations[:consumer_version].associations[:tags]
91
+ consumer_version.tags
92
+ else
93
+ tags
94
+ end
110
95
  end
111
96
 
112
97
  def latest_verification
@@ -1,39 +1,32 @@
1
1
  require "sequel"
2
2
  require "pact_broker/repositories/helpers"
3
- require "pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version"
4
3
  require "pact_broker/pacts/content"
4
+ require "pact_broker/pacts/pact_version_association_loaders"
5
5
 
6
6
  module PactBroker
7
7
  module Pacts
8
8
  class PactVersion < Sequel::Model(:pact_versions)
9
+ include PactVersionAssociationLoaders
10
+
9
11
  plugin :timestamps
10
12
  plugin :upsert, identifying_columns: [:consumer_id, :provider_id, :sha]
11
13
 
12
- one_to_many :pact_publications, reciprocal: :pact_version
13
- one_to_many :verifications, reciprocal: :verification, order: :id, class: "PactBroker::Domain::Verification"
14
- associate(:many_to_one, :provider, class: "PactBroker::Domain::Pacticipant", key: :provider_id, primary_key: :id)
15
- associate(:many_to_one, :consumer, class: "PactBroker::Domain::Pacticipant", key: :consumer_id, primary_key: :id)
16
- associate(:many_to_many, :consumer_versions, class: "PactBroker::Domain::Version", join_table: :pact_publications, left_key: :pact_version_id, right_key: :consumer_version_id, order: :order)
14
+ one_to_many(:pact_publications, reciprocal: :pact_version)
15
+ one_to_many(:verifications, reciprocal: :verification, order: :id, class: "PactBroker::Domain::Verification")
16
+ many_to_one(:provider, class: "PactBroker::Domain::Pacticipant", key: :provider_id, primary_key: :id)
17
+ many_to_one(:consumer, class: "PactBroker::Domain::Pacticipant", key: :consumer_id, primary_key: :id)
18
+ many_to_many(:consumer_versions,
19
+ class: "PactBroker::Domain::Version",
20
+ join_table: :pact_publications,
21
+ left_key: :pact_version_id,
22
+ right_key: :consumer_version_id,
23
+ order: :order
24
+ )
17
25
 
18
26
  one_to_one(:latest_main_branch_verification,
19
27
  class: "PactBroker::Domain::Verification",
20
28
  read_only: true,
21
- dataset: lambda {
22
- providers_join = {
23
- Sequel[:providers][:id] => Sequel[:latest_verification_id_for_pact_version_and_provider_version][:provider_id]
24
- }
25
-
26
- branch_versions_join = {
27
- Sequel[:latest_verification_id_for_pact_version_and_provider_version][:provider_version_id] => Sequel[:branch_versions][:version_id],
28
- Sequel[:providers][:main_branch] => Sequel[:branch_versions][:branch_name]
29
- }
30
- max_verification_id_for_pact_version = PactBroker::Verifications::LatestVerificationIdForPactVersionAndProviderVersion
31
- .join(:pacticipants, providers_join, { table_alias: :providers })
32
- .join(:branch_versions, branch_versions_join)
33
- .select(Sequel.function(:max, :verification_id))
34
- .where(pact_version_id: id)
35
- PactBroker::Domain::Verification.where(id: max_verification_id_for_pact_version)
36
- },
29
+ dataset: LATEST_MAIN_BRANCH_VERIFICATION,
37
30
  key: :pact_version_id,
38
31
  primary_key: :id,
39
32
  eager_block: lambda { | ds | ds.from_provider_main_branch.latest_by_pact_version }
@@ -42,15 +35,18 @@ module PactBroker
42
35
  one_to_one(:latest_verification,
43
36
  class: "PactBroker::Domain::Verification",
44
37
  read_only: true,
45
- dataset: lambda { PactBroker::Domain::Verification.where(id: PactBroker::Verifications::LatestVerificationIdForPactVersionAndProviderVersion.select(Sequel.function(:max, :verification_id)).where(pact_version_id: id)) },
38
+ dataset: LATEST_VERIFICATION_DATASET,
46
39
  key: :pact_version_id, primary_key: :id,
47
40
  eager_block: lambda { | ds | ds.latest_by_pact_version }
48
41
  )
49
42
 
50
43
  # do not eager load this - it won't work because of the limit(1)
51
- one_through_one(:latest_consumer_version, class: "PactBroker::Domain::Version", join_table: :pact_publications, left_key: :pact_version_id, right_key: :consumer_version_id) do | ds |
52
- ds.unlimited.order(Sequel.desc(:order)).limit(1)
53
- end
44
+ one_through_one(:latest_consumer_version,
45
+ class: "PactBroker::Domain::Version",
46
+ join_table: :pact_publications,
47
+ left_key: :pact_version_id,
48
+ right_key: :consumer_version_id, &LATEST_CONSUMER_VERSION_LAZY_LOADER
49
+ )
54
50
 
55
51
  dataset_module do
56
52
  include PactBroker::Repositories::Helpers
@@ -89,11 +85,11 @@ module PactBroker
89
85
  end
90
86
 
91
87
  def provider_name
92
- pact_publications.last.provider.name
88
+ provider.name
93
89
  end
94
90
 
95
91
  def consumer_name
96
- pact_publications.last.consumer.name
92
+ consumer.name
97
93
  end
98
94
 
99
95
  def latest_pact_publication
@@ -0,0 +1,36 @@
1
+ require "pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version"
2
+
3
+ module PactBroker
4
+ module Pacts
5
+ module PactVersionAssociationLoaders
6
+
7
+ LATEST_MAIN_BRANCH_VERIFICATION = lambda {
8
+ providers_join = {
9
+ Sequel[:providers][:id] => Sequel[:latest_verification_id_for_pact_version_and_provider_version][:provider_id]
10
+ }
11
+
12
+ branch_versions_join = {
13
+ Sequel[:latest_verification_id_for_pact_version_and_provider_version][:provider_version_id] => Sequel[:branch_versions][:version_id],
14
+ Sequel[:providers][:main_branch] => Sequel[:branch_versions][:branch_name]
15
+ }
16
+ max_verification_id_for_pact_version = PactBroker::Verifications::LatestVerificationIdForPactVersionAndProviderVersion
17
+ .join(:pacticipants, providers_join, { table_alias: :providers })
18
+ .join(:branch_versions, branch_versions_join)
19
+ .select(Sequel.function(:max, :verification_id))
20
+ .where(pact_version_id: id)
21
+ PactBroker::Domain::Verification.where(id: max_verification_id_for_pact_version)
22
+ }
23
+
24
+ LATEST_VERIFICATION_DATASET = lambda {
25
+ PactBroker::Domain::Verification
26
+ .where(
27
+ id: PactBroker::Verifications::LatestVerificationIdForPactVersionAndProviderVersion.select(
28
+ Sequel.function(:max, :verification_id)
29
+ ).where(pact_version_id: id)
30
+ )
31
+ }
32
+
33
+ LATEST_CONSUMER_VERSION_LAZY_LOADER = lambda { | ds | ds.unlimited.order(Sequel.desc(:order)).limit(1) }
34
+ end
35
+ end
36
+ end
@@ -23,7 +23,7 @@ module PactBroker
23
23
  :provider,
24
24
  :consumer,
25
25
  :consumer_version,
26
- pact_version: :latest_verification
26
+ :pact_version
27
27
  ]
28
28
 
29
29
  def find(provider_name, consumer_version_selectors)
@@ -162,16 +162,14 @@ module PactBroker
162
162
 
163
163
  def find_pacts_for_which_the_latest_version_for_the_fallback_tag_is_required(provider_name, selectors)
164
164
  selectors.collect do | selector |
165
- query = scope_for(PactPublication).for_provider_name(provider_name).for_latest_consumer_versions_with_tag(selector.fallback_tag)
165
+ query = scope_for(PactPublication).eager_for_domain_with_content.for_provider_name(provider_name).for_latest_consumer_versions_with_tag(selector.fallback_tag)
166
166
  query = query.for_consumer_name(selector.consumer) if selector.consumer
167
- query.all
168
- .collect do | latest_tagged_pact_publication |
169
- pact_publication = unscoped(PactPublication).find(id: latest_tagged_pact_publication.id)
170
- SelectedPact.new(
171
- pact_publication.to_domain,
172
- Selectors.new(selector.resolve_for_fallback(pact_publication.consumer_version))
173
- )
174
- end
167
+ query.all.collect do | pact_publication |
168
+ SelectedPact.new(
169
+ pact_publication.to_domain,
170
+ Selectors.new(selector.resolve_for_fallback(pact_publication.consumer_version))
171
+ )
172
+ end
175
173
  end.flatten
176
174
  end
177
175
 
@@ -299,7 +297,13 @@ module PactBroker
299
297
  end
300
298
 
301
299
  def collect_consumer_name_and_version_number(pact_publications_query)
302
- pact_publications_query.eager(:provider).eager(:consumer).eager(:consumer_version).order(:consumer_version_order).all.sort.collect do |p|
300
+ pact_publications = pact_publications_query
301
+ .eager(:consumer, :consumer_version)
302
+ .order(:consumer_version_order)
303
+ .all_forbidding_lazy_load
304
+ .sort
305
+
306
+ pact_publications.collect do |p|
303
307
  suffix = if p.values[:tag_name]
304
308
  " (tag #{p.values[:tag_name]})"
305
309
  elsif p.values[:branch_name]
@@ -308,7 +312,7 @@ module PactBroker
308
312
  ""
309
313
  end
310
314
 
311
- "#{p.consumer_name} #{p.consumer_version_number}" + suffix
315
+ "#{p.consumer.name} #{p.consumer_version.number}" + suffix
312
316
  end
313
317
  end
314
318