pact_broker 2.95.1 → 2.98.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/Gemfile +1 -0
- data/docs/CONFIGURATION.md +120 -66
- data/lib/db.rb +1 -7
- data/lib/pact_broker/api/middleware/http_debug_logs.rb +36 -0
- data/lib/pact_broker/app.rb +3 -7
- data/lib/pact_broker/config/basic_auth_configuration.rb +7 -0
- data/lib/pact_broker/config/runtime_configuration.rb +22 -4
- data/lib/pact_broker/config/runtime_configuration_coercion_methods.rb +11 -0
- data/lib/pact_broker/config/runtime_configuration_database_methods.rb +6 -1
- data/lib/pact_broker/config/runtime_configuration_logging_methods.rb +13 -2
- data/lib/pact_broker/configuration.rb +2 -12
- data/lib/pact_broker/db/models.rb +2 -2
- data/lib/pact_broker/index/service.rb +2 -3
- data/lib/pact_broker/integrations/integration.rb +21 -6
- data/lib/pact_broker/integrations/service.rb +1 -1
- data/lib/pact_broker/matrix/repository.rb +2 -3
- data/lib/pact_broker/matrix/service.rb +0 -1
- data/lib/pact_broker/metrics/service.rb +2 -2
- data/lib/pact_broker/pacts/lazy_loaders.rb +26 -0
- data/lib/pact_broker/pacts/pact_publication.rb +13 -34
- data/lib/pact_broker/pacts/pact_version.rb +24 -28
- data/lib/pact_broker/pacts/pact_version_association_loaders.rb +36 -0
- data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +9 -13
- data/lib/pact_broker/pacts/repository.rb +29 -25
- data/lib/pact_broker/repositories/helpers.rb +4 -0
- data/lib/pact_broker/test/http_test_data_builder.rb +8 -1
- data/lib/pact_broker/test/test_data_builder.rb +2 -1
- data/lib/pact_broker/ui/controllers/matrix.rb +14 -11
- data/lib/pact_broker/version.rb +1 -1
- data/pact_broker.gemspec +1 -1
- metadata +9 -16
- data/lib/pact_broker/matrix/aggregated_row.rb +0 -79
- data/lib/pact_broker/matrix/head_row.rb +0 -80
- data/lib/pact_broker/matrix/row.rb +0 -287
@@ -0,0 +1,36 @@
|
|
1
|
+
require "pact_broker/logging"
|
2
|
+
|
3
|
+
module PactBroker
|
4
|
+
module Api
|
5
|
+
module Middleware
|
6
|
+
class HttpDebugLogs
|
7
|
+
include PactBroker::Logging
|
8
|
+
|
9
|
+
EXCLUDE_HEADERS = ["puma.", "rack.", "pactbroker."]
|
10
|
+
RACK_SESSION = "rack.session"
|
11
|
+
|
12
|
+
def initialize(app)
|
13
|
+
@app = app
|
14
|
+
@logger = logger
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
env_to_log = env.reject { | header, _ | header.start_with?(*EXCLUDE_HEADERS) }
|
19
|
+
env_to_log["rack.session"] = env["rack.session"].to_hash if env["rack.session"]
|
20
|
+
env_to_log["rack.input"] = request_body(env) if env["rack.input"]
|
21
|
+
logger.debug("env", payload: env_to_log)
|
22
|
+
status, headers, body = @app.call(env)
|
23
|
+
logger.debug("response", payload: { "status" => status, "headers" => headers, "body" => body })
|
24
|
+
[status, headers, body]
|
25
|
+
end
|
26
|
+
|
27
|
+
def request_body(env)
|
28
|
+
buffer = env["rack.input"]
|
29
|
+
request_body = buffer.read
|
30
|
+
buffer.respond_to?(:rewind) && buffer.rewind
|
31
|
+
JSON.parse(request_body) rescue request_body
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/pact_broker/app.rb
CHANGED
@@ -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
|
@@ -20,6 +20,13 @@ module PactBroker
|
|
20
20
|
|
21
21
|
sensitive_values(:basic_auth_password, :basic_auth_read_only_password)
|
22
22
|
|
23
|
+
coerce_types(
|
24
|
+
basic_auth_username: :string,
|
25
|
+
basic_auth_password: :string,
|
26
|
+
basic_auth_read_only_username: :string,
|
27
|
+
basic_auth_read_only_password: :string
|
28
|
+
)
|
29
|
+
|
23
30
|
def basic_auth_credentials_provided?
|
24
31
|
basic_auth_username&.not_blank? && basic_auth_password&.not_blank?
|
25
32
|
end
|
@@ -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
|
-
|
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(
|
@@ -178,8 +182,14 @@ module PactBroker
|
|
178
182
|
def webhook_certificates= webhook_certificates
|
179
183
|
if webhook_certificates.is_a?(Array)
|
180
184
|
super(webhook_certificates.collect(&:symbolize_keys))
|
185
|
+
elsif webhook_certificates.is_a?(Hash)
|
186
|
+
if all_keys_are_number_strings?(webhook_certificates)
|
187
|
+
super(convert_hash_with_number_string_keys_to_array(webhook_certificates).collect(&:symbolize_keys))
|
188
|
+
else
|
189
|
+
raise_validation_error("webhook_certificates must be an array, or a hash where each key is an integer in string format.")
|
190
|
+
end
|
181
191
|
elsif !webhook_certificates.nil?
|
182
|
-
raise_validation_error("webhook_certificates
|
192
|
+
raise_validation_error("webhook_certificates cannot be set using a #{webhook_certificates.class}")
|
183
193
|
end
|
184
194
|
end
|
185
195
|
|
@@ -208,6 +218,14 @@ module PactBroker
|
|
208
218
|
def raise_validation_error(msg)
|
209
219
|
raise PactBroker::ConfigurationError, msg
|
210
220
|
end
|
221
|
+
|
222
|
+
def set_webhook_attribute_defaults
|
223
|
+
# can't set a default on this, or anyway config blows up when trying to merge the
|
224
|
+
# hash from the env vars into an array/nil.
|
225
|
+
if webhook_certificates.nil?
|
226
|
+
self.webhook_certificates = []
|
227
|
+
end
|
228
|
+
end
|
211
229
|
end
|
212
230
|
end
|
213
231
|
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)
|
@@ -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
|
-
|
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
|
@@ -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
|
@@ -82,14 +80,6 @@ module PactBroker
|
|
82
80
|
config
|
83
81
|
end
|
84
82
|
|
85
|
-
def with_runtime_configuration_overrides(overrides)
|
86
|
-
original_runtime_configuration = runtime_configuration
|
87
|
-
self.runtime_configuration = override_runtime_configuration!(overrides)
|
88
|
-
yield
|
89
|
-
ensure
|
90
|
-
self.runtime_configuration = original_runtime_configuration
|
91
|
-
end
|
92
|
-
|
93
83
|
def override_runtime_configuration!(overrides)
|
94
84
|
new_runtime_configuration = runtime_configuration.dup
|
95
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
|
@@ -108,7 +107,7 @@ module PactBroker
|
|
108
107
|
# rubocop: disable Metrics/CyclomaticComplexity
|
109
108
|
def self.latest_verification_for_pseudo_branch(pact_publication, is_overall_latest, latest_verifications_for_cv_tags, tags_option, options)
|
110
109
|
if options[:view] == "branch" || (options[:view] == "all" && pact_publication.consumer_version.branch_heads.any?)
|
111
|
-
pact_publication.latest_verification || pact_publication.latest_verification_for_consumer_branches
|
110
|
+
pact_publication.latest_verification || pact_publication.latest_verification_for_consumer_branches
|
112
111
|
elsif tags_option == true
|
113
112
|
latest_verifications_for_cv_tags
|
114
113
|
.select{ | v | v.consumer_id == pact_publication.consumer_id && v.provider_id == pact_publication.provider_id && pact_publication.head_pact_tags.collect(&:name).include?(v.consumer_version_tag_name) }
|
@@ -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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
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
|
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
|
-
|
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]
|
@@ -118,8 +118,8 @@ module PactBroker
|
|
118
118
|
|
119
119
|
def matrix_count
|
120
120
|
begin
|
121
|
-
PactBroker::Matrix::
|
122
|
-
PactBroker::Matrix::
|
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
|
@@ -20,12 +20,11 @@ module PactBroker
|
|
20
20
|
delegate [:consumer_version_number, :name, :provider_name, :consumer_name] => :cached_domain_for_delegation
|
21
21
|
|
22
22
|
set_primary_key :id
|
23
|
-
associate(:many_to_one, :provider, :class => "PactBroker::Domain::Pacticipant", :key => :provider_id, :primary_key => :id
|
24
|
-
associate(:many_to_one, :consumer, :class => "PactBroker::Domain::Pacticipant", :key => :consumer_id, :primary_key => :id
|
25
|
-
associate(:many_to_one, :consumer_version, :class => "PactBroker::Domain::Version", :key => :consumer_version_id, :primary_key => :id
|
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], forbid_lazy_load: false)
|
28
|
-
|
23
|
+
associate(:many_to_one, :provider, :class => "PactBroker::Domain::Pacticipant", :key => :provider_id, :primary_key => :id)
|
24
|
+
associate(:many_to_one, :consumer, :class => "PactBroker::Domain::Pacticipant", :key => :consumer_id, :primary_key => :id)
|
25
|
+
associate(:many_to_one, :consumer_version, :class => "PactBroker::Domain::Version", :key => :consumer_version_id, :primary_key => :id)
|
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], 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
|
-
|
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)
|
@@ -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
|
13
|
-
one_to_many
|
14
|
-
|
15
|
-
|
16
|
-
|
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:
|
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:
|
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,
|
52
|
-
|
53
|
-
|
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
|
-
|
88
|
+
provider.name
|
93
89
|
end
|
94
90
|
|
95
91
|
def consumer_name
|
96
|
-
|
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
|