pact_broker 2.42.0 → 2.43.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|