pact_broker 2.42.0 → 2.43.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 +21 -0
- data/lib/pact_broker/api/resources/integrations.rb +1 -1
- data/lib/pact_broker/badges/service.rb +4 -1
- data/lib/pact_broker/db/models.rb +37 -0
- data/lib/pact_broker/integrations/service.rb +18 -0
- data/lib/pact_broker/matrix/query_builder.rb +78 -0
- data/lib/pact_broker/matrix/query_ids.rb +40 -0
- data/lib/pact_broker/matrix/quick_row.rb +192 -127
- data/lib/pact_broker/matrix/repository.rb +4 -27
- data/lib/pact_broker/matrix/resolved_selector.rb +9 -3
- data/lib/pact_broker/test/test_data_builder.rb +19 -2
- data/lib/pact_broker/version.rb +1 -1
- data/lib/rack/pact_broker/request_target.rb +58 -0
- data/lib/rack/pact_broker/ui_request_filter.rb +6 -43
- data/pact_broker.gemspec +3 -3
- data/spec/lib/pact_broker/badges/service_spec.rb +19 -0
- data/spec/lib/pact_broker/integrations/service_spec.rb +10 -0
- data/spec/lib/pact_broker/matrix/deployment_status_summary_spec.rb +0 -2
- data/spec/lib/pact_broker/matrix/integration_spec.rb +40 -0
- data/spec/lib/pact_broker/matrix/quick_row_spec.rb +3 -2
- data/spec/lib/pact_broker/matrix/repository_spec.rb +5 -3
- data/spec/lib/rack/pact_broker/{ui_request_filter_spec.rb → request_target_spec.rb} +22 -29
- data/tasks/database/annotate.rb +12 -4
- data/vendor/hal-browser/js/hal/http/client.js +1 -1
- metadata +28 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 452acf4f3b4042c53c9e91a793f558f39ad6677e
|
4
|
+
data.tar.gz: ffcc62ddc9991aed25c87cbdea9925e9471bc4f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e843bb458d91149a64f50092fcc1d17e63ed8b57468c7c2293033947648233cc015a010d421f7386531e89e90eb7d9499bc8da177da81c5518ea1bb937305ef8
|
7
|
+
data.tar.gz: c4df7ee48ef81fdb78beb668267ad13fcf848916b047c6f848a65bcc4979e7fac851617e93fba857b2a63bd77545d08a614e46257ede2e39e821d937ac3e79ef
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
<a name="v2.43.0"></a>
|
2
|
+
### v2.43.0 (2020-01-06)
|
3
|
+
|
4
|
+
|
5
|
+
#### Features
|
6
|
+
|
7
|
+
* support DELETE /integrations for deleting all integration related data at once (pacticipants, pacts, verifications and webhooks) ([d7e2ef27](/../../commit/d7e2ef27))
|
8
|
+
* optimise query to automatically determine integrations ([147cbfb6](/../../commit/147cbfb6))
|
9
|
+
* change badge timeout message from error to warning ([e34f5676](/../../commit/e34f5676))
|
10
|
+
|
11
|
+
* **matrix**
|
12
|
+
* optimise the query that determines the integrations ([704944b6](/../../commit/704944b6))
|
13
|
+
* attempt to optimise the query that determines the integrations ([afde01e1](/../../commit/afde01e1))
|
14
|
+
|
15
|
+
|
16
|
+
#### Bug Fixes
|
17
|
+
|
18
|
+
* update rack for https://github.com/advisories/GHSA-hrqr-hxpp-chr3 ([c9352fde](/../../commit/c9352fde))
|
19
|
+
* correctly identify missing verification for bi-directional pacts ([3577968a](/../../commit/3577968a))
|
20
|
+
|
21
|
+
|
1
22
|
<a name="v2.42.0"></a>
|
2
23
|
### v2.42.0 (2019-12-05)
|
3
24
|
|
@@ -84,8 +84,11 @@ module PactBroker
|
|
84
84
|
begin
|
85
85
|
response = do_request(uri)
|
86
86
|
response.code == '200' ? response.body : nil
|
87
|
+
rescue Net::OpenTimeout => e
|
88
|
+
logger.warn "Timeout retrieving badge from #{uri} #{e.class} - #{e.message}"
|
89
|
+
nil
|
87
90
|
rescue StandardError => e
|
88
|
-
|
91
|
+
log_error e, "Error retrieving badge from #{uri}"
|
89
92
|
nil
|
90
93
|
end
|
91
94
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'pact_broker/webhooks/execution'
|
2
|
+
require 'pact_broker/webhooks/triggered_webhook'
|
3
|
+
require 'pact_broker/webhooks/webhook'
|
4
|
+
require 'pact_broker/pacts/latest_pact_publication_id_by_consumer_version'
|
5
|
+
require 'pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version'
|
6
|
+
require 'pact_broker/pacts/pact_publication'
|
7
|
+
require 'pact_broker/pacts/pact_version'
|
8
|
+
require 'pact_broker/domain/verification'
|
9
|
+
require 'pact_broker/domain/tag'
|
10
|
+
require 'pact_broker/domain/version'
|
11
|
+
require 'pact_broker/domain/label'
|
12
|
+
require 'pact_broker/domain/pacticipant'
|
13
|
+
|
14
|
+
module PactBroker
|
15
|
+
INTEGRATIONS_TABLES = [
|
16
|
+
PactBroker::Webhooks::Execution,
|
17
|
+
PactBroker::Webhooks::TriggeredWebhook,
|
18
|
+
PactBroker::Webhooks::Webhook,
|
19
|
+
PactBroker::Pacts::LatestPactPublicationIdForConsumerVersion,
|
20
|
+
PactBroker::Verifications::LatestVerificationIdForPactVersionAndProviderVersion,
|
21
|
+
PactBroker::Domain::Verification,
|
22
|
+
PactBroker::Pacts::PactPublication,
|
23
|
+
PactBroker::Pacts::PactVersion,
|
24
|
+
PactBroker::Domain::Tag,
|
25
|
+
PactBroker::Domain::Version,
|
26
|
+
PactBroker::Domain::Label,
|
27
|
+
PactBroker::Domain::Pacticipant
|
28
|
+
]
|
29
|
+
|
30
|
+
module DB
|
31
|
+
def self.each_integration_model
|
32
|
+
INTEGRATIONS_TABLES.each do | model |
|
33
|
+
yield model
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -2,6 +2,8 @@ require 'pact_broker/services'
|
|
2
2
|
require 'pact_broker/repositories'
|
3
3
|
require 'pact_broker/logging'
|
4
4
|
require 'pact_broker/integrations/integration'
|
5
|
+
require 'pact_broker/db/models'
|
6
|
+
require 'pact_broker/repositories/helpers'
|
5
7
|
|
6
8
|
module PactBroker
|
7
9
|
module Integrations
|
@@ -41,6 +43,22 @@ module PactBroker
|
|
41
43
|
pacticipant_service.delete_if_orphan(consumer)
|
42
44
|
pacticipant_service.delete_if_orphan(provider) unless consumer == provider
|
43
45
|
end
|
46
|
+
|
47
|
+
def self.delete_all
|
48
|
+
# TODO move all these into their own repositories
|
49
|
+
PactBroker::DB.each_integration_model do | model |
|
50
|
+
if PactBroker::Repositories::Helpers.postgres?
|
51
|
+
logger.info("Truncating ", model.table_name)
|
52
|
+
model.truncate(cascade: true)
|
53
|
+
else
|
54
|
+
logger.info("Deleting all from ", model.table_name)
|
55
|
+
# Mysql adapter needs to support cascade truncate
|
56
|
+
# https://travis-ci.org/pact-foundation/pact_broker/jobs/633050220#L841
|
57
|
+
# https://travis-ci.org/pact-foundation/pact_broker/jobs/633053228#L849
|
58
|
+
model.dataset.delete
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
44
62
|
end
|
45
63
|
end
|
46
64
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module PactBroker
|
2
|
+
module Matrix
|
3
|
+
class QueryBuilder
|
4
|
+
def self.provider_or_provider_version_matches(query_ids, qualifier = nil)
|
5
|
+
Sequel.|(*provider_or_provider_version_criteria(query_ids, qualifier))
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.provider_or_provider_version_matches_or_pact_unverified(query_ids, qualifier = nil)
|
9
|
+
ors = provider_or_provider_version_criteria(query_ids, qualifier)
|
10
|
+
|
11
|
+
ors << {
|
12
|
+
qualify(:lp, :provider_id) => query_ids.all_pacticipant_ids,
|
13
|
+
qualify(qualifier, :provider_version_id) => nil
|
14
|
+
}
|
15
|
+
Sequel.|(*ors)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.provider_or_provider_version_criteria(query_ids, qualifier = nil)
|
19
|
+
ors = []
|
20
|
+
ors << { qualify(qualifier, :provider_version_id) => query_ids.pacticipant_version_ids } if query_ids.pacticipant_version_ids.any?
|
21
|
+
ors << { qualify(qualifier, :provider_id) => query_ids.pacticipant_ids } if query_ids.pacticipant_ids.any?
|
22
|
+
ors
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.consumer_in_pacticipant_ids(query_ids)
|
26
|
+
{ consumer_id: query_ids.all_pacticipant_ids }
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.consumer_or_consumer_version_matches(query_ids, qualifier)
|
30
|
+
ors = []
|
31
|
+
ors << { qualify(qualifier, :consumer_version_id) => query_ids.pacticipant_version_ids } if query_ids.pacticipant_version_ids.any?
|
32
|
+
ors << { qualify(qualifier, :consumer_id) => query_ids.pacticipant_ids } if query_ids.pacticipant_ids.any?
|
33
|
+
|
34
|
+
Sequel.|(*ors)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Some selecters are specified in the query, others are implied (when only one pacticipant is specified,
|
38
|
+
# the integrations are automatically worked out, and the selectors for these are of type :implied )
|
39
|
+
# When there are 3 pacticipants that each have dependencies on each other (A->B, A->C, B->C), the query
|
40
|
+
# to deploy C (implied A, implied B, specified C) was returning the A->B row because it matched the
|
41
|
+
# implied selectors as well.
|
42
|
+
# This extra filter makes sure that every row that is returned actually matches one of the specified
|
43
|
+
# selectors.
|
44
|
+
def self.either_consumer_or_provider_was_specified_in_query(query_ids, qualifier = nil)
|
45
|
+
Sequel.|({
|
46
|
+
qualify(qualifier, :consumer_id) => query_ids.specified_pacticipant_ids
|
47
|
+
} , {
|
48
|
+
qualify(qualifier, :provider_id) => query_ids.specified_pacticipant_ids
|
49
|
+
})
|
50
|
+
end
|
51
|
+
|
52
|
+
# QueryIds is built from a single selector, so there is only one pacticipant_id or pacticipant_version_id
|
53
|
+
def self.consumer_or_consumer_version_or_provider_or_provider_or_provider_version_match(query_ids)
|
54
|
+
ors = if query_ids.pacticipant_version_id
|
55
|
+
[
|
56
|
+
{ Sequel[:lp][:consumer_version_id] => query_ids.pacticipant_version_id },
|
57
|
+
{ Sequel[:lv][:provider_version_id] => query_ids.pacticipant_version_id }
|
58
|
+
]
|
59
|
+
else
|
60
|
+
[
|
61
|
+
{ Sequel[:lp][:consumer_id] => query_ids.pacticipant_id },
|
62
|
+
{ Sequel[:lp][:provider_id] => query_ids.pacticipant_id }
|
63
|
+
]
|
64
|
+
end
|
65
|
+
|
66
|
+
Sequel.|(*ors)
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.qualify(qualifier, column)
|
70
|
+
if qualifier
|
71
|
+
Sequel[qualifier][column]
|
72
|
+
else
|
73
|
+
column
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module PactBroker
|
2
|
+
module Matrix
|
3
|
+
class QueryIds
|
4
|
+
attr_reader :all_pacticipant_ids, :specified_pacticipant_ids, :pacticipant_ids, :pacticipant_version_ids
|
5
|
+
|
6
|
+
# pacticipant_version_ids - the pacticipant version ids from the selectors where the pacticipant version id is the most specific criterion
|
7
|
+
# pacticipant_ids - the pacticipant ids from the selectors where the pacticipant id is the most specific criterion
|
8
|
+
# all_pacticipant_ids - the pacticipant ids from all the selectors, regardless of whether or not a pacticipant version has also been specified
|
9
|
+
# specified_pacticipant_ids the IDs of the pacticipants that were specified in the can-i-deploy query
|
10
|
+
def initialize(all_pacticipant_ids, specified_pacticipant_ids, pacticipant_ids, pacticipant_version_ids)
|
11
|
+
@all_pacticipant_ids = all_pacticipant_ids
|
12
|
+
@specified_pacticipant_ids = specified_pacticipant_ids
|
13
|
+
@pacticipant_ids = pacticipant_ids
|
14
|
+
@pacticipant_version_ids = pacticipant_version_ids
|
15
|
+
@all_pacticipant_ids = all_pacticipant_ids
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.from_selectors(selectors)
|
19
|
+
most_specific_criteria = selectors.collect(&:most_specific_criterion)
|
20
|
+
all_pacticipant_ids = selectors.collect(&:pacticipant_id)
|
21
|
+
specified_pacticipant_ids = selectors.select(&:specified?).collect(&:pacticipant_id)
|
22
|
+
pacticipant_version_ids = collect_ids(most_specific_criteria, :pacticipant_version_id)
|
23
|
+
pacticipant_ids = collect_ids(most_specific_criteria, :pacticipant_id)
|
24
|
+
QueryIds.new(all_pacticipant_ids, specified_pacticipant_ids, pacticipant_ids, pacticipant_version_ids)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.collect_ids(hashes, key)
|
28
|
+
hashes.collect{ |s| s[key] }.flatten.compact
|
29
|
+
end
|
30
|
+
|
31
|
+
def pacticipant_id
|
32
|
+
pacticipant_ids.first
|
33
|
+
end
|
34
|
+
|
35
|
+
def pacticipant_version_id
|
36
|
+
pacticipant_version_ids.first
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,11 +1,6 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
The Matrix::QuickRow starts with the relevant rows, and builds the matrix query from that,
|
6
|
-
making it much quicker.
|
7
|
-
|
8
|
-
=end
|
1
|
+
require 'pact_broker/pacts/all_pact_publications'
|
2
|
+
require 'pact_broker/repositories/helpers'
|
3
|
+
require 'pact_broker/matrix/query_builder'
|
9
4
|
require 'sequel'
|
10
5
|
require 'pact_broker/repositories/helpers'
|
11
6
|
require 'pact_broker/logging'
|
@@ -15,41 +10,64 @@ require 'pact_broker/domain/version'
|
|
15
10
|
require 'pact_broker/domain/verification'
|
16
11
|
require 'pact_broker/pacts/pact_publication'
|
17
12
|
require 'pact_broker/tags/tag_with_latest_flag'
|
13
|
+
require 'pact_broker/matrix/query_ids'
|
14
|
+
|
15
|
+
# The difference between `join_verifications_for` and `join_verifications` is that
|
16
|
+
# the left outer join is done on a pre-filtered dataset in `join_verifications_for`,
|
17
|
+
# so that we get a row with null verification fields for a pact that has been verified
|
18
|
+
# by a *different* version of the provider we're interested in,
|
19
|
+
# rather than being excluded from the dataset altogether.
|
18
20
|
|
19
21
|
module PactBroker
|
20
22
|
module Matrix
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
23
|
+
class QuickRow < Sequel::Model(Sequel.as(:latest_pact_publication_ids_for_consumer_versions, :lp))
|
24
|
+
|
25
|
+
# Tables
|
26
|
+
LV = :latest_verification_id_for_pact_version_and_provider_version
|
27
|
+
LP = :latest_pact_publication_ids_for_consumer_versions
|
28
|
+
|
29
|
+
# Joins
|
30
|
+
LP_LV_JOIN = { Sequel[:lp][:pact_version_id] => Sequel[:lv][:pact_version_id] }
|
31
|
+
CONSUMER_JOIN = { Sequel[:lp][:consumer_id] => Sequel[:consumers][:id] }
|
32
|
+
PROVIDER_JOIN = { Sequel[:lp][:provider_id] => Sequel[:providers][:id] }
|
33
|
+
CONSUMER_VERSION_JOIN = { Sequel[:lp][:consumer_version_id] => Sequel[:cv][:id] }
|
34
|
+
PROVIDER_VERSION_JOIN = { Sequel[:lv][:provider_version_id] => Sequel[:pv][:id] }
|
35
|
+
|
36
|
+
# Not sure why we're eager loading some things and including others in the base query :shrug:
|
37
|
+
|
38
|
+
# Columns
|
39
|
+
CONSUMER_COLUMNS = [
|
40
|
+
Sequel[:lp][:consumer_id],
|
41
|
+
Sequel[:consumers][:name].as(:consumer_name)
|
42
|
+
]
|
43
|
+
PROVIDER_COLUMNS = [
|
44
|
+
Sequel[:lp][:provider_id],
|
45
|
+
Sequel[:providers][:name].as(:provider_name)
|
46
|
+
]
|
47
|
+
CONSUMER_VERSION_COLUMNS = [
|
48
|
+
Sequel[:lp][:consumer_version_id],
|
49
|
+
Sequel[:cv][:number].as(:consumer_version_number),
|
50
|
+
Sequel[:cv][:order].as(:consumer_version_order)
|
51
|
+
]
|
52
|
+
PROVIDER_VERSION_COLUMNS = [
|
53
|
+
Sequel[:lv][:provider_version_id],
|
54
|
+
Sequel[:pv][:number].as(:provider_version_number),
|
55
|
+
Sequel[:pv][:order].as(:provider_version_order)
|
56
|
+
]
|
57
|
+
PACT_COLUMNS = [
|
58
|
+
Sequel[:lp][:pact_publication_id],
|
59
|
+
Sequel[:lp][:pact_version_id]
|
60
|
+
]
|
61
|
+
VERIFICATION_COLUMNS = [
|
62
|
+
Sequel[:lv][:verification_id]
|
63
|
+
]
|
64
|
+
ALL_COLUMNS = CONSUMER_COLUMNS + CONSUMER_VERSION_COLUMNS + PACT_COLUMNS +
|
65
|
+
PROVIDER_COLUMNS + PROVIDER_VERSION_COLUMNS + VERIFICATION_COLUMNS
|
66
|
+
PACTICIPANT_NAMES_AND_IDS = CONSUMER_COLUMNS + PROVIDER_COLUMNS
|
67
|
+
|
68
|
+
# cachable select arguments
|
69
|
+
SELECT_ALL_COLUMN_ARGS = [:select_all_columns] + ALL_COLUMNS
|
70
|
+
SELECT_PACTICIPANT_NAMES_AND_IDS_ARGS = [:select_pacticipant_names_and_ids] + PACTICIPANT_NAMES_AND_IDS
|
53
71
|
|
54
72
|
associate(:many_to_one, :pact_publication, :class => "PactBroker::Pacts::PactPublication", :key => :pact_publication_id, :primary_key => :id)
|
55
73
|
associate(:many_to_one, :provider, :class => "PactBroker::Domain::Pacticipant", :key => :provider_id, :primary_key => :id)
|
@@ -63,102 +81,26 @@ module PactBroker
|
|
63
81
|
|
64
82
|
dataset_module do
|
65
83
|
include PactBroker::Repositories::Helpers
|
66
|
-
include PactBroker::Logging
|
67
84
|
|
68
|
-
|
69
|
-
|
85
|
+
select *SELECT_ALL_COLUMN_ARGS
|
86
|
+
select *SELECT_PACTICIPANT_NAMES_AND_IDS_ARGS
|
87
|
+
|
88
|
+
def distinct_integrations selectors
|
89
|
+
select_pacticipant_names_and_ids
|
90
|
+
.distinct
|
91
|
+
.matching_selectors(selectors)
|
70
92
|
end
|
71
93
|
|
72
94
|
def matching_selectors selectors
|
73
95
|
if selectors.size == 1
|
74
|
-
|
96
|
+
matching_one_selector(selectors)
|
75
97
|
else
|
76
|
-
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# find rows where (the consumer (and optional version) matches any of the selectors)
|
81
|
-
# AND
|
82
|
-
# the (provider (and optional version) matches any of the selectors OR the provider matches
|
83
|
-
# and the verification is missing (and hence the provider version is null))
|
84
|
-
def where_consumer_and_provider_in selectors
|
85
|
-
where{
|
86
|
-
Sequel.&(
|
87
|
-
Sequel.|(
|
88
|
-
*QueryHelper.consumer_and_maybe_consumer_version_match_any_selector(selectors)
|
89
|
-
),
|
90
|
-
Sequel.|(
|
91
|
-
*QueryHelper.provider_and_maybe_provider_version_match_any_selector_or_verification_is_missing(selectors)
|
92
|
-
),
|
93
|
-
QueryHelper.either_consumer_or_provider_was_specified_in_query(selectors)
|
94
|
-
)
|
95
|
-
}
|
96
|
-
end
|
97
|
-
|
98
|
-
# Can't access other dataset_module methods from inside the Sequel `where{ ... }` block, so make a private class
|
99
|
-
# with some helper methods
|
100
|
-
class QueryHelper
|
101
|
-
def self.consumer_and_maybe_consumer_version_match_any_selector(selectors)
|
102
|
-
selectors.collect { |s| consumer_and_maybe_consumer_version_match_selector(s) }
|
103
|
-
end
|
104
|
-
|
105
|
-
def self.consumer_and_maybe_consumer_version_match_selector(s)
|
106
|
-
if s[:pact_publication_ids]
|
107
|
-
Sequel.&(PACT_PUBLICATION_ID => s[:pact_publication_ids])
|
108
|
-
elsif s[:pacticipant_version_id]
|
109
|
-
Sequel.&(CONSUMER_ID => s[:pacticipant_id], CONSUMER_VERSION_ID => s[:pacticipant_version_id])
|
110
|
-
else
|
111
|
-
Sequel.&(CONSUMER_ID => s[:pacticipant_id])
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def self.provider_and_maybe_provider_version_match_selector(s)
|
116
|
-
if s[:verification_ids]
|
117
|
-
Sequel.&(VERIFICATION_ID => s[:verification_ids])
|
118
|
-
elsif s[:pacticipant_version_id]
|
119
|
-
Sequel.&(PROVIDER_ID => s[:pacticipant_id], PROVIDER_VERSION_ID => s[:pacticipant_version_id])
|
120
|
-
else
|
121
|
-
Sequel.&(PROVIDER_ID => s[:pacticipant_id])
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
# if the pact for a consumer version has never been verified, it exists in the matrix as a row
|
126
|
-
# with a blank provider version id
|
127
|
-
def self.provider_verification_is_missing_for_matching_selector(s)
|
128
|
-
Sequel.&(PROVIDER_ID => s[:pacticipant_id], PROVIDER_VERSION_ID => nil)
|
129
|
-
end
|
130
|
-
|
131
|
-
def self.provider_and_maybe_provider_version_match_any_selector_or_verification_is_missing(selectors)
|
132
|
-
selectors.collect { |s|
|
133
|
-
provider_and_maybe_provider_version_match_selector(s)
|
134
|
-
} + selectors.collect { |s|
|
135
|
-
provider_verification_is_missing_for_matching_selector(s)
|
136
|
-
}
|
137
|
-
end
|
138
|
-
|
139
|
-
# Some selecters are specified in the query, others are implied (when only one pacticipant is specified,
|
140
|
-
# the integrations are automatically worked out, and the selectors for these are of type :implied )
|
141
|
-
# When there are 3 pacticipants that each have dependencies on each other (A->B, A->C, B->C), the query
|
142
|
-
# to deploy C (implied A, implied B, specified C) was returning the A->B row because it matched the
|
143
|
-
# implied selectors as well.
|
144
|
-
# This extra filter makes sure that every row that is returned actually matches one of the specified
|
145
|
-
# selectors.
|
146
|
-
def self.either_consumer_or_provider_was_specified_in_query(selectors)
|
147
|
-
specified_pacticipant_ids = selectors.select{ |s| s[:type] == :specified }.collect{ |s| s[:pacticipant_id] }
|
148
|
-
Sequel.|({ CONSUMER_ID => specified_pacticipant_ids } , { PROVIDER_ID => specified_pacticipant_ids })
|
98
|
+
matching_multiple_selectors(selectors)
|
149
99
|
end
|
150
100
|
end
|
151
101
|
|
152
|
-
def where_consumer_or_provider_is s
|
153
|
-
where{
|
154
|
-
Sequel.|(
|
155
|
-
s[:pacticipant_version_id] ? Sequel.&(CONSUMER_ID => s[:pacticipant_id], CONSUMER_VERSION_ID => s[:pacticipant_version_id]) : Sequel.&(CONSUMER_ID => s[:pacticipant_id]),
|
156
|
-
s[:pacticipant_version_id] ? Sequel.&(PROVIDER_ID => s[:pacticipant_id], PROVIDER_VERSION_ID => s[:pacticipant_version_id]) : Sequel.&(PROVIDER_ID => s[:pacticipant_id])
|
157
|
-
)
|
158
|
-
}
|
159
|
-
end
|
160
|
-
|
161
102
|
def order_by_names_ascending_most_recent_first
|
103
|
+
from_self.
|
162
104
|
order(
|
163
105
|
Sequel.asc(:consumer_name),
|
164
106
|
Sequel.desc(:consumer_version_order),
|
@@ -177,7 +119,86 @@ module PactBroker
|
|
177
119
|
.eager(:pact_version)
|
178
120
|
end
|
179
121
|
|
180
|
-
|
122
|
+
def default_scope
|
123
|
+
select_all_columns.join_verifications.join_pacticipants_and_pacticipant_versions.from_self
|
124
|
+
end
|
125
|
+
|
126
|
+
# PRIVATE METHODS
|
127
|
+
|
128
|
+
# When we have one selector, we need to join ALL the verifications to find out
|
129
|
+
# what integrations exist
|
130
|
+
def matching_one_selector(selectors)
|
131
|
+
join_verifications
|
132
|
+
.join_pacticipants_and_pacticipant_versions
|
133
|
+
.where {
|
134
|
+
QueryBuilder.consumer_or_consumer_version_or_provider_or_provider_or_provider_version_match(QueryIds.from_selectors(selectors))
|
135
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
# When the user has specified multiple selectors, we only want to join the verifications for
|
139
|
+
# the specified selectors. This is because of the behaviour of the left outer join.
|
140
|
+
# Imagine a pact has been verified by a provider version that was NOT specified in the selectors.
|
141
|
+
# If we join all the verifications and THEN filter the rows to only show the versions specified
|
142
|
+
# in the selectors, we won't get a row for that pact, and hence, we won't
|
143
|
+
# know that it hasn't been verified by the provider version we're interested in.
|
144
|
+
# Instead, we need to filter the verifications dataset down to only the ones specified in the selectors first,
|
145
|
+
# and THEN join them to the pacts, so that we get a row for the pact with null provider version
|
146
|
+
# and verification fields.
|
147
|
+
def matching_multiple_selectors(selectors)
|
148
|
+
query_ids = QueryIds.from_selectors(selectors)
|
149
|
+
join_verifications_for(query_ids)
|
150
|
+
.join_pacticipants_and_pacticipant_versions
|
151
|
+
.where {
|
152
|
+
Sequel.&(
|
153
|
+
QueryBuilder.consumer_or_consumer_version_matches(query_ids, :lp),
|
154
|
+
QueryBuilder.provider_or_provider_version_matches_or_pact_unverified(query_ids, :lv),
|
155
|
+
QueryBuilder.either_consumer_or_provider_was_specified_in_query(query_ids, :lp)
|
156
|
+
)
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
def join_verifications_for(query_ids)
|
161
|
+
left_outer_join(verifications_for(query_ids), LP_LV_JOIN, { table_alias: :lv } )
|
162
|
+
end
|
163
|
+
|
164
|
+
def verifications_for(query_ids)
|
165
|
+
db[LV]
|
166
|
+
.select(:verification_id, :provider_version_id, :pact_version_id, :provider_id)
|
167
|
+
.where {
|
168
|
+
Sequel.&(
|
169
|
+
QueryBuilder.consumer_in_pacticipant_ids(query_ids),
|
170
|
+
QueryBuilder.provider_or_provider_version_matches(query_ids)
|
171
|
+
)
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
def join_pacticipants_and_pacticipant_versions
|
176
|
+
join_consumers
|
177
|
+
.join_providers
|
178
|
+
.join_consumer_versions
|
179
|
+
.join_provider_versions
|
180
|
+
end
|
181
|
+
|
182
|
+
def join_consumers
|
183
|
+
join(:pacticipants, CONSUMER_JOIN, { table_alias: :consumers })
|
184
|
+
end
|
185
|
+
|
186
|
+
def join_providers
|
187
|
+
join(:pacticipants, PROVIDER_JOIN, { table_alias: :providers })
|
188
|
+
end
|
189
|
+
|
190
|
+
def join_consumer_versions
|
191
|
+
join(:versions, CONSUMER_VERSION_JOIN, { table_alias: :cv })
|
192
|
+
end
|
193
|
+
|
194
|
+
def join_provider_versions
|
195
|
+
left_outer_join(:versions, PROVIDER_VERSION_JOIN, { table_alias: :pv } )
|
196
|
+
end
|
197
|
+
|
198
|
+
def join_verifications
|
199
|
+
left_outer_join(LV, LP_LV_JOIN, { table_alias: :lv } )
|
200
|
+
end
|
201
|
+
end # end dataset_module
|
181
202
|
|
182
203
|
def success
|
183
204
|
verification&.success
|
@@ -250,6 +271,50 @@ module PactBroker
|
|
250
271
|
def involves_pacticipant_with_name?(pacticipant_name)
|
251
272
|
pacticipant_name.include?(pacticipant_name)
|
252
273
|
end
|
274
|
+
|
275
|
+
def provider_version_id
|
276
|
+
# null when not verified
|
277
|
+
values[:provider_version_id]
|
278
|
+
end
|
279
|
+
|
280
|
+
def verification_id
|
281
|
+
# null when not verified
|
282
|
+
return_or_raise_if_not_set(:verification_id)
|
283
|
+
end
|
284
|
+
|
285
|
+
def consumer_name
|
286
|
+
return_or_raise_if_not_set(:consumer_name)
|
287
|
+
end
|
288
|
+
|
289
|
+
def consumer_version_number
|
290
|
+
return_or_raise_if_not_set(:consumer_version_number)
|
291
|
+
end
|
292
|
+
|
293
|
+
def consumer_version_order
|
294
|
+
return_or_raise_if_not_set(:consumer_version_order)
|
295
|
+
end
|
296
|
+
|
297
|
+
def provider_name
|
298
|
+
return_or_raise_if_not_set(:provider_name)
|
299
|
+
end
|
300
|
+
|
301
|
+
def provider_version_number
|
302
|
+
return_or_raise_if_not_set(:provider_version_number)
|
303
|
+
end
|
304
|
+
|
305
|
+
def provider_version_order
|
306
|
+
return_or_raise_if_not_set(:provider_version_order)
|
307
|
+
end
|
308
|
+
|
309
|
+
# This model needs the verifications and pacticipants joined to it
|
310
|
+
# before it can be used, as it's not a "real" model.
|
311
|
+
def return_or_raise_if_not_set(key)
|
312
|
+
if values.key?(key)
|
313
|
+
values[key]
|
314
|
+
else
|
315
|
+
raise "Required table not joined"
|
316
|
+
end
|
317
|
+
end
|
253
318
|
end
|
254
319
|
end
|
255
320
|
end
|