pact_broker 2.107.1 → 2.108.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 +55 -0
- data/Gemfile +5 -4
- data/README.md +1 -0
- data/db/migrations/20230615_add_integrations_contract_data_updated_at.rb +13 -0
- data/db/migrations/20230616_set_integrations_contract_data_updated_at.rb +11 -0
- data/db/migrations/20231002_add_version_id_index_to_released_version.rb +21 -0
- data/db/migrations/20231003_add_version_id_index_to_deployed_version.rb +21 -0
- data/docs/CONFIGURATION.md +10 -0
- data/lib/pact_broker/api/contracts/base_contract.rb +2 -1
- data/lib/pact_broker/api/contracts/dry_validation_errors_formatter.rb +2 -0
- data/lib/pact_broker/api/contracts/pagination_query_params_schema.rb +19 -0
- data/lib/pact_broker/api/contracts/publish_contracts_contract_contract.rb +29 -18
- data/lib/pact_broker/api/decorators/base_decorator.rb +40 -1
- data/lib/pact_broker/api/decorators/branch_decorator.rb +35 -0
- data/lib/pact_broker/api/decorators/branch_version_decorator.rb +16 -0
- data/lib/pact_broker/api/decorators/configuration.rb +19 -0
- data/lib/pact_broker/api/decorators/custom_error_problem_json_decorator.rb +1 -1
- data/lib/pact_broker/api/decorators/decorator_context_creator.rb +47 -2
- data/lib/pact_broker/api/decorators/deployed_version_decorator.rb +2 -1
- data/lib/pact_broker/api/decorators/deployed_versions_decorator.rb +2 -2
- data/lib/pact_broker/api/decorators/dry_validation_errors_decorator.rb +32 -0
- data/lib/pact_broker/api/decorators/dry_validation_errors_problem_json_decorator.rb +24 -0
- data/lib/pact_broker/api/decorators/embedded_branch_version_decorator.rb +2 -2
- data/lib/pact_broker/api/decorators/embedded_deployed_version_decorator.rb +30 -0
- data/lib/pact_broker/api/decorators/embedded_error_problem_json_decorator.rb +84 -0
- data/lib/pact_broker/api/decorators/embedded_released_version_decorator.rb +27 -0
- data/lib/pact_broker/api/decorators/embedded_version_decorator.rb +0 -3
- data/lib/pact_broker/api/decorators/error_decorator.rb +30 -0
- data/lib/pact_broker/api/decorators/extended_pact_decorator.rb +6 -1
- data/lib/pact_broker/api/decorators/integration_decorator.rb +3 -2
- data/lib/pact_broker/api/decorators/integrations_decorator.rb +3 -0
- data/lib/pact_broker/api/decorators/notices_decorator.rb +11 -0
- data/lib/pact_broker/api/decorators/pact_pacticipant_decorator.rb +1 -5
- data/lib/pact_broker/api/decorators/pact_versions_decorator.rb +0 -1
- data/lib/pact_broker/api/decorators/pact_webhooks_status_decorator.rb +0 -1
- data/lib/pact_broker/api/decorators/pacticipant_branches_decorator.rb +32 -0
- data/lib/pact_broker/api/decorators/pacticipant_decorator.rb +11 -1
- data/lib/pact_broker/api/decorators/{pacticipant_collection_decorator.rb → pacticipants_decorator.rb} +8 -4
- data/lib/pact_broker/api/decorators/pagination_links.rb +2 -2
- data/lib/pact_broker/api/decorators/released_versions_decorator.rb +2 -2
- data/lib/pact_broker/api/decorators/runtime_error_problem_json_decorator.rb +2 -2
- data/lib/pact_broker/api/decorators/validation_errors_decorator.rb +30 -0
- data/lib/pact_broker/api/decorators/validation_errors_problem_json_decorator.rb +4 -6
- data/lib/pact_broker/api/decorators/version_decorator.rb +5 -3
- data/lib/pact_broker/api/decorators/versions_decorator.rb +24 -14
- data/lib/pact_broker/api/decorators/webhook_execution_result_decorator.rb +2 -0
- data/lib/pact_broker/api/middleware/configuration.rb +2 -0
- data/lib/pact_broker/api/pact_broker_urls.rb +18 -2
- data/lib/pact_broker/api/resources/after_reply.rb +15 -0
- data/lib/pact_broker/api/resources/all_webhooks.rb +3 -3
- data/lib/pact_broker/api/resources/badge_methods.rb +2 -1
- data/lib/pact_broker/api/resources/base_resource.rb +6 -4
- data/lib/pact_broker/api/resources/branch.rb +40 -0
- data/lib/pact_broker/api/resources/branch_versions.rb +59 -0
- data/lib/pact_broker/api/resources/can_i_deploy_pacticipant_version_by_branch_to_environment_badge.rb +1 -1
- data/lib/pact_broker/api/resources/currently_deployed_versions_for_environment.rb +1 -1
- data/lib/pact_broker/api/resources/currently_supported_versions_for_environment.rb +1 -1
- data/lib/pact_broker/api/resources/dashboard.rb +10 -0
- data/lib/pact_broker/api/resources/deployed_versions_for_version_and_environment.rb +1 -1
- data/lib/pact_broker/api/resources/environments.rb +1 -1
- data/lib/pact_broker/api/resources/error_handler.rb +18 -52
- data/lib/pact_broker/api/resources/error_handling_methods.rb +40 -14
- data/lib/pact_broker/api/resources/error_response_generator.rb +23 -6
- data/lib/pact_broker/api/resources/event_methods.rb +15 -0
- data/lib/pact_broker/api/resources/filter_methods.rb +15 -0
- data/lib/pact_broker/api/resources/group.rb +11 -2
- data/lib/pact_broker/api/resources/index.rb +6 -0
- data/lib/pact_broker/api/resources/integrations.rb +18 -4
- data/lib/pact_broker/api/resources/latest_version.rb +2 -0
- data/lib/pact_broker/api/resources/pact.rb +11 -6
- data/lib/pact_broker/api/resources/pacticipant_branches.rb +67 -0
- data/lib/pact_broker/api/resources/pacticipants.rb +26 -7
- data/lib/pact_broker/api/resources/pacticipants_for_label.rb +2 -2
- data/lib/pact_broker/api/resources/pagination_methods.rb +11 -1
- data/lib/pact_broker/api/resources/verifications.rb +9 -4
- data/lib/pact_broker/api/resources/versions.rb +12 -0
- data/lib/pact_broker/api.rb +5 -0
- data/lib/pact_broker/app.rb +10 -4
- data/lib/pact_broker/application_context.rb +29 -25
- data/lib/pact_broker/async/after_reply.rb +30 -0
- data/lib/pact_broker/config/runtime_configuration.rb +9 -21
- data/lib/pact_broker/config/runtime_configuration_coercion_methods.rb +32 -2
- data/lib/pact_broker/config/runtime_configuration_database_methods.rb +1 -1
- data/lib/pact_broker/config/runtime_configuration_logging_methods.rb +15 -5
- data/lib/pact_broker/configuration.rb +29 -12
- data/lib/pact_broker/contracts/contracts_to_publish.rb +8 -0
- data/lib/pact_broker/contracts/service.rb +7 -1
- data/lib/pact_broker/dataset/page.rb +22 -0
- data/lib/pact_broker/dataset.rb +122 -0
- data/lib/pact_broker/db/data_migrations/set_contract_data_updated_at_for_integrations.rb +47 -0
- data/lib/pact_broker/db/migrate_data.rb +1 -0
- data/lib/pact_broker/db/models.rb +1 -1
- data/lib/pact_broker/deployments/currently_deployed_version_id.rb +2 -5
- data/lib/pact_broker/deployments/deployed_version.rb +3 -3
- data/lib/pact_broker/deployments/environment.rb +0 -2
- data/lib/pact_broker/deployments/released_version.rb +4 -5
- data/lib/pact_broker/doc/views/index/pacticipant-branch.markdown +25 -0
- data/lib/pact_broker/domain/label.rb +6 -3
- data/lib/pact_broker/domain/pact.rb +10 -5
- data/lib/pact_broker/domain/pacticipant.rb +4 -34
- data/lib/pact_broker/domain/tag.rb +4 -5
- data/lib/pact_broker/domain/verification.rb +2 -4
- data/lib/pact_broker/domain/version.rb +12 -19
- data/lib/pact_broker/errors/error_reporter.rb +30 -0
- data/lib/pact_broker/errors.rb +2 -15
- data/lib/pact_broker/events/subscriber.rb +12 -4
- data/lib/pact_broker/feature_toggle.rb +1 -1
- data/lib/pact_broker/groups/service.rb +38 -5
- data/lib/pact_broker/index/service.rb +1 -2
- data/lib/pact_broker/integrations/event_listener.rb +23 -0
- data/lib/pact_broker/integrations/integration.rb +24 -2
- data/lib/pact_broker/integrations/repository.rb +34 -1
- data/lib/pact_broker/integrations/service.rb +17 -18
- data/lib/pact_broker/labels/repository.rb +4 -8
- data/lib/pact_broker/locale/en.yml +5 -0
- data/lib/pact_broker/matrix/every_row.rb +58 -40
- data/lib/pact_broker/matrix/integration_row.rb +95 -0
- data/lib/pact_broker/matrix/integrations_repository.rb +133 -0
- data/lib/pact_broker/matrix/matrix_row.rb +88 -0
- data/lib/pact_broker/matrix/matrix_row_dataset_module.rb +185 -0
- data/lib/pact_broker/matrix/matrix_row_instance_methods.rb +150 -0
- data/lib/pact_broker/matrix/matrix_row_verification_dataset_module.rb +83 -0
- data/lib/pact_broker/matrix/parse_query.rb +1 -0
- data/lib/pact_broker/matrix/repository.rb +62 -285
- data/lib/pact_broker/matrix/resolved_selector.rb +13 -4
- data/lib/pact_broker/matrix/resolved_selector_builder.rb +84 -0
- data/lib/pact_broker/matrix/resolved_selectors_builder.rb +39 -0
- data/lib/pact_broker/matrix/row_ignorer.rb +36 -0
- data/lib/pact_broker/matrix/selector_ignorer.rb +59 -0
- data/lib/pact_broker/matrix/selector_resolver.rb +130 -0
- data/lib/pact_broker/metrics/service.rb +4 -9
- data/lib/pact_broker/pacticipants/latest_version_for_pacticipant_eager_loader.rb +33 -0
- data/lib/pact_broker/pacticipants/repository.rb +7 -9
- data/lib/pact_broker/pacticipants/service.rb +2 -2
- data/lib/pact_broker/pacts/latest_pact_publication_id_for_consumer_version.rb +2 -4
- data/lib/pact_broker/pacts/metadata.rb +3 -1
- data/lib/pact_broker/pacts/pact_publication.rb +23 -5
- data/lib/pact_broker/pacts/pact_publication_dataset_module.rb +5 -1
- data/lib/pact_broker/pacts/pact_version.rb +2 -3
- data/lib/pact_broker/pacts/pacts_for_verification_repository.rb +2 -5
- data/lib/pact_broker/pacts/placeholder_pact.rb +3 -1
- data/lib/pact_broker/pacts/repository.rb +12 -12
- data/lib/pact_broker/pacts/service.rb +1 -1
- data/lib/pact_broker/repositories.rb +9 -1
- data/lib/pact_broker/string_refinements.rb +4 -0
- data/lib/pact_broker/tags/head_pact_tags.rb +2 -5
- data/lib/pact_broker/tags/repository.rb +3 -7
- data/lib/pact_broker/test/test_data_builder.rb +50 -1
- data/lib/pact_broker/ui/controllers/groups.rb +2 -1
- data/lib/pact_broker/ui/view_models/matrix_line.rb +4 -4
- data/lib/pact_broker/ui/views/groups/show.html.erb +2 -1
- data/lib/pact_broker/verifications/latest_verification_for_consumer_and_provider.rb +0 -3
- data/lib/pact_broker/verifications/latest_verification_id_for_pact_version_and_provider_version.rb +2 -4
- data/lib/pact_broker/verifications/repository.rb +2 -5
- data/lib/pact_broker/verifications/sequence.rb +1 -4
- data/lib/pact_broker/verifications/service.rb +4 -0
- data/lib/pact_broker/version.rb +1 -1
- data/lib/pact_broker/versions/branch.rb +2 -5
- data/lib/pact_broker/versions/branch_head.rb +0 -3
- data/lib/pact_broker/versions/branch_repository.rb +76 -0
- data/lib/pact_broker/versions/branch_service.rb +13 -25
- data/lib/pact_broker/versions/branch_version.rb +0 -3
- data/lib/pact_broker/versions/branch_version_repository.rb +17 -0
- data/lib/pact_broker/versions/repository.rb +19 -2
- data/lib/pact_broker/versions/sequence.rb +1 -3
- data/lib/pact_broker/versions/service.rb +4 -0
- data/lib/pact_broker/webhooks/execution.rb +3 -7
- data/lib/pact_broker/webhooks/job.rb +16 -7
- data/lib/pact_broker/webhooks/pact_and_verification_parameters.rb +2 -2
- data/lib/pact_broker/webhooks/repository.rb +0 -1
- data/lib/pact_broker/webhooks/trigger_service.rb +11 -12
- data/lib/pact_broker/webhooks/triggered_webhook.rb +3 -4
- data/lib/pact_broker/webhooks/webhook.rb +2 -2
- data/lib/pact_broker/webhooks/webhook_event.rb +2 -5
- data/lib/rack/pact_broker/add_cache_header.rb +14 -0
- data/lib/rack/pact_broker/application_context.rb +16 -0
- data/lib/rack/pact_broker/configurable_make_it_later.rb +1 -1
- data/lib/rack/pact_broker/invalid_uri_protection.rb +19 -3
- data/lib/webmachine/describe_routes.rb +55 -39
- data/lib/webmachine/render_error_monkey_patch.rb +13 -4
- data/pact_broker.gemspec +4 -4
- metadata +52 -29
- data/lib/pact_broker/api/decorators/decorator_context.rb +0 -22
- data/lib/pact_broker/matrix/query_builder.rb +0 -90
- data/lib/pact_broker/matrix/query_ids.rb +0 -40
- data/lib/pact_broker/matrix/quick_row.rb +0 -458
- data/lib/pact_broker/relationships/groupify.rb +0 -45
- data/lib/pact_broker/repositories/helpers.rb +0 -96
- data/lib/pact_broker/repositories/page.rb +0 -24
- data/lib/pact_broker/tags/tag_with_latest_flag.rb +0 -28
@@ -1,11 +1,17 @@
|
|
1
1
|
require "pact_broker/api/resources/base_resource"
|
2
2
|
require "pact_broker/api/renderers/integrations_dot_renderer"
|
3
3
|
require "pact_broker/api/decorators/integrations_decorator"
|
4
|
+
require "pact_broker/api/resources/filter_methods"
|
5
|
+
require "pact_broker/api/resources/pagination_methods"
|
6
|
+
require "pact_broker/api/contracts/pagination_query_params_schema"
|
4
7
|
|
5
8
|
module PactBroker
|
6
9
|
module Api
|
7
10
|
module Resources
|
8
11
|
class Integrations < BaseResource
|
12
|
+
include PaginationMethods
|
13
|
+
include FilterMethods
|
14
|
+
|
9
15
|
def content_types_provided
|
10
16
|
[
|
11
17
|
["text/vnd.graphviz", :to_dot],
|
@@ -17,18 +23,20 @@ module PactBroker
|
|
17
23
|
["GET", "OPTIONS", "DELETE"]
|
18
24
|
end
|
19
25
|
|
26
|
+
def malformed_request?
|
27
|
+
super || (request.get? && validation_errors_for_schema?(schema, request.query))
|
28
|
+
end
|
29
|
+
|
20
30
|
def to_dot
|
31
|
+
integrations = integration_service.find_all(filter_options, pagination_options)
|
21
32
|
PactBroker::Api::Renderers::IntegrationsDotRenderer.call(integrations)
|
22
33
|
end
|
23
34
|
|
24
35
|
def to_json
|
36
|
+
integrations = integration_service.find_all(filter_options, pagination_options, decorator_class(:integrations_decorator).eager_load_associations)
|
25
37
|
decorator_class(:integrations_decorator).new(integrations).to_json(**decorator_options)
|
26
38
|
end
|
27
39
|
|
28
|
-
def integrations
|
29
|
-
@integrations ||= integration_service.find_all
|
30
|
-
end
|
31
|
-
|
32
40
|
def delete_resource
|
33
41
|
integration_service.delete_all
|
34
42
|
true
|
@@ -37,6 +45,12 @@ module PactBroker
|
|
37
45
|
def policy_name
|
38
46
|
:'integrations::integrations'
|
39
47
|
end
|
48
|
+
|
49
|
+
def schema
|
50
|
+
if request.get?
|
51
|
+
PactBroker::Api::Contracts::PaginationQueryParamsSchema
|
52
|
+
end
|
53
|
+
end
|
40
54
|
end
|
41
55
|
end
|
42
56
|
end
|
@@ -17,6 +17,8 @@ module PactBroker
|
|
17
17
|
def version
|
18
18
|
if identifier_from_path[:tag]
|
19
19
|
@version ||= version_service.find_by_pacticipant_name_and_latest_tag(identifier_from_path[:pacticipant_name], identifier_from_path[:tag])
|
20
|
+
elsif identifier_from_path[:branch_name]
|
21
|
+
@version ||= version_service.find_latest_by_pacticipant_name_and_branch_name(identifier_from_path[:pacticipant_name], identifier_from_path[:branch_name])
|
20
22
|
else
|
21
23
|
@version ||= version_service.find_latest_by_pacticpant_name(identifier_from_path)
|
22
24
|
end
|
@@ -9,14 +9,17 @@ require "pact_broker/api/contracts/put_pact_params_contract"
|
|
9
9
|
require "pact_broker/webhooks/execution_configuration"
|
10
10
|
require "pact_broker/api/resources/webhook_execution_methods"
|
11
11
|
require "pact_broker/api/resources/pact_resource_methods"
|
12
|
+
require "pact_broker/api/resources/event_methods"
|
13
|
+
require "pact_broker/integrations/event_listener"
|
12
14
|
|
13
15
|
module PactBroker
|
14
16
|
module Api
|
15
17
|
module Resources
|
16
18
|
class Pact < BaseResource
|
19
|
+
include EventMethods
|
17
20
|
include PacticipantResourceMethods
|
18
|
-
include WebhookExecutionMethods
|
19
21
|
include PactResourceMethods
|
22
|
+
include WebhookExecutionMethods
|
20
23
|
include PactBroker::Messages
|
21
24
|
|
22
25
|
def content_types_provided
|
@@ -65,11 +68,13 @@ module PactBroker
|
|
65
68
|
def from_json
|
66
69
|
response_code = pact ? 200 : 201
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
71
|
+
subscribe(PactBroker::Integrations::EventListener.new) do
|
72
|
+
handle_webhook_events do
|
73
|
+
if request.patch? && resource_exists?
|
74
|
+
@pact = pact_service.merge_pact(pact_params)
|
75
|
+
else
|
76
|
+
@pact = pact_service.create_or_update_pact(pact_params)
|
77
|
+
end
|
73
78
|
end
|
74
79
|
end
|
75
80
|
response.body = to_json
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "pact_broker/api/resources/base_resource"
|
2
|
+
require "pact_broker/api/resources/pagination_methods"
|
3
|
+
require "pact_broker/api/resources/filter_methods"
|
4
|
+
require "pact_broker/api/resources/after_reply"
|
5
|
+
require "rack/utils"
|
6
|
+
|
7
|
+
module PactBroker
|
8
|
+
module Api
|
9
|
+
module Resources
|
10
|
+
class PacticipantBranches < BaseResource
|
11
|
+
include PaginationMethods
|
12
|
+
include FilterMethods
|
13
|
+
include AfterReply
|
14
|
+
|
15
|
+
def content_types_provided
|
16
|
+
[["application/hal+json", :to_json]]
|
17
|
+
end
|
18
|
+
|
19
|
+
def allowed_methods
|
20
|
+
["GET", "DELETE", "OPTIONS"]
|
21
|
+
end
|
22
|
+
|
23
|
+
def resource_exists?
|
24
|
+
!!pacticipant
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_json
|
28
|
+
decorator_class(:pacticipant_branches_decorator).new(branches).to_json(**decorator_options(pacticipant: pacticipant))
|
29
|
+
end
|
30
|
+
|
31
|
+
def policy_name
|
32
|
+
:'versions::branches'
|
33
|
+
end
|
34
|
+
|
35
|
+
# Allows bulk deletion of pacticipant branches, keeping the specified branches and the main branch.
|
36
|
+
# Deletes the branches asyncronously, after the response has been sent, for performance reasons.
|
37
|
+
def delete_resource
|
38
|
+
after_reply do
|
39
|
+
branch_service.delete_branches_for_pacticipant(pacticipant, exclude: exclude)
|
40
|
+
end
|
41
|
+
notices = branch_service.branch_deletion_notices(pacticipant, exclude: exclude)
|
42
|
+
response.body = decorator_class(:notices_decorator).new(notices).to_json(**decorator_options)
|
43
|
+
202
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def branches
|
49
|
+
@branches ||= branch_service.find_all_branches_for_pacticipant(
|
50
|
+
pacticipant,
|
51
|
+
filter_options,
|
52
|
+
default_pagination_options.merge(pagination_options),
|
53
|
+
eager_load_associations
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
def exclude
|
58
|
+
Rack::Utils.parse_nested_query(request.uri.query)["exclude"] || []
|
59
|
+
end
|
60
|
+
|
61
|
+
def eager_load_associations
|
62
|
+
decorator_class(:pacticipant_branches_decorator).eager_load_associations
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -12,7 +12,6 @@ module PactBroker
|
|
12
12
|
using PactBroker::HashRefinements
|
13
13
|
include PaginationMethods
|
14
14
|
|
15
|
-
|
16
15
|
def content_types_provided
|
17
16
|
[["application/hal+json", :to_json]]
|
18
17
|
end
|
@@ -26,7 +25,15 @@ module PactBroker
|
|
26
25
|
end
|
27
26
|
|
28
27
|
def malformed_request?
|
29
|
-
super
|
28
|
+
if super
|
29
|
+
true
|
30
|
+
elsif request.post? && validation_errors_for_schema?
|
31
|
+
true
|
32
|
+
elsif request.get? && validation_errors_for_schema?(schema, request.query)
|
33
|
+
true
|
34
|
+
else
|
35
|
+
false
|
36
|
+
end
|
30
37
|
end
|
31
38
|
|
32
39
|
def request_body_required?
|
@@ -47,11 +54,11 @@ module PactBroker
|
|
47
54
|
end
|
48
55
|
|
49
56
|
def to_json
|
50
|
-
generate_json(pacticipant_service.find_all_pacticipants(pagination_options))
|
57
|
+
generate_json(pacticipant_service.find_all_pacticipants(filter_options, pagination_options, eager_load_associations))
|
51
58
|
end
|
52
59
|
|
53
60
|
def generate_json pacticipants
|
54
|
-
decorator_class(:
|
61
|
+
decorator_class(:deprecated_pacticipants_decorator).new(pacticipants).to_json(**decorator_options)
|
55
62
|
end
|
56
63
|
|
57
64
|
def decorator_for model
|
@@ -69,11 +76,23 @@ module PactBroker
|
|
69
76
|
private
|
70
77
|
|
71
78
|
def schema
|
72
|
-
|
79
|
+
if request.get?
|
80
|
+
PactBroker::Api::Contracts::PaginationQueryParamsSchema
|
81
|
+
else
|
82
|
+
PactBroker::Api::Contracts::PacticipantCreateSchema
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def eager_load_associations
|
87
|
+
decorator_class(:deprecated_pacticipants_decorator).eager_load_associations
|
73
88
|
end
|
74
89
|
|
75
|
-
def
|
76
|
-
|
90
|
+
def filter_options
|
91
|
+
if (request.query.has_key?("q"))
|
92
|
+
{ query_string: request.query["q"] }
|
93
|
+
else
|
94
|
+
{}
|
95
|
+
end
|
77
96
|
end
|
78
97
|
end
|
79
98
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require "pact_broker/api/resources/base_resource"
|
2
|
-
require "pact_broker/api/decorators/
|
2
|
+
require "pact_broker/api/decorators/pacticipants_decorator"
|
3
3
|
|
4
4
|
module PactBroker
|
5
5
|
module Api
|
@@ -19,7 +19,7 @@ module PactBroker
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def generate_json pacticipants
|
22
|
-
decorator_class(:
|
22
|
+
decorator_class(:pacticipants_decorator).new(pacticipants).to_json(**decorator_options)
|
23
23
|
end
|
24
24
|
|
25
25
|
def policy_name
|
@@ -2,8 +2,14 @@ module PactBroker
|
|
2
2
|
module Api
|
3
3
|
module Resources
|
4
4
|
module PaginationMethods
|
5
|
+
# rubocop: disable Metrics/CyclomaticComplexity
|
5
6
|
def pagination_options
|
6
|
-
if request.query["
|
7
|
+
if request.query["page"] || request.query["size"]
|
8
|
+
{
|
9
|
+
page_number: request.query["page"]&.to_i || 1,
|
10
|
+
page_size: request.query["size"]&.to_i || 100
|
11
|
+
}
|
12
|
+
elsif request.query["pageNumber"] || request.query["pageSize"]
|
7
13
|
{
|
8
14
|
page_number: request.query["pageNumber"]&.to_i || 1,
|
9
15
|
page_size: request.query["pageSize"]&.to_i || 100
|
@@ -12,6 +18,10 @@ module PactBroker
|
|
12
18
|
{}
|
13
19
|
end
|
14
20
|
end
|
21
|
+
|
22
|
+
def default_pagination_options
|
23
|
+
{ page_number: 1, page_size: 100 }
|
24
|
+
end
|
15
25
|
end
|
16
26
|
end
|
17
27
|
end
|
@@ -5,6 +5,8 @@ require "pact_broker/api/contracts/verification_contract"
|
|
5
5
|
require "pact_broker/api/decorators/verification_decorator"
|
6
6
|
require "pact_broker/api/resources/webhook_execution_methods"
|
7
7
|
require "pact_broker/api/resources/metadata_resource_methods"
|
8
|
+
require "pact_broker/api/resources/event_methods"
|
9
|
+
require "pact_broker/integrations/event_listener"
|
8
10
|
|
9
11
|
module PactBroker
|
10
12
|
module Api
|
@@ -12,6 +14,7 @@ module PactBroker
|
|
12
14
|
class Verifications < BaseResource
|
13
15
|
include WebhookExecutionMethods
|
14
16
|
include MetadataResourceMethods
|
17
|
+
include EventMethods
|
15
18
|
|
16
19
|
def content_types_accepted
|
17
20
|
[["application/json", :from_json]]
|
@@ -42,10 +45,12 @@ module PactBroker
|
|
42
45
|
end
|
43
46
|
|
44
47
|
def from_json
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
48
|
+
subscribe(PactBroker::Integrations::EventListener.new) do
|
49
|
+
handle_webhook_events(build_url: verification_params["buildUrl"]) do
|
50
|
+
verified_pacts = pact_service.find_for_verification_publication(pact_params, event_context[:consumer_version_selectors])
|
51
|
+
verification = verification_service.create(next_verification_number, verification_params, verified_pacts, event_context)
|
52
|
+
response.body = decorator_for(verification).to_json(**decorator_options)
|
53
|
+
end
|
49
54
|
end
|
50
55
|
true
|
51
56
|
end
|
@@ -18,6 +18,10 @@ module PactBroker
|
|
18
18
|
["GET", "OPTIONS"]
|
19
19
|
end
|
20
20
|
|
21
|
+
def malformed_request?
|
22
|
+
super || request.get? && validation_errors_for_schema?(schema, request.query)
|
23
|
+
end
|
24
|
+
|
21
25
|
def resource_exists?
|
22
26
|
!!pacticipant
|
23
27
|
end
|
@@ -33,6 +37,14 @@ module PactBroker
|
|
33
37
|
def policy_name
|
34
38
|
:'versions::versions'
|
35
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def schema
|
44
|
+
if request.get?
|
45
|
+
PactBroker::Api::Contracts::PaginationQueryParamsSchema
|
46
|
+
end
|
47
|
+
end
|
36
48
|
end
|
37
49
|
end
|
38
50
|
end
|
data/lib/pact_broker/api.rb
CHANGED
@@ -64,6 +64,7 @@ module PactBroker
|
|
64
64
|
# Latest pacts
|
65
65
|
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest"], Api::Resources::LatestPact, {resource_name: "latest_pact_publication"}
|
66
66
|
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest", :tag], Api::Resources::LatestPact, {resource_name: "latest_tagged_pact_publication"}
|
67
|
+
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "branch", :branch_name, "latest"], Api::Resources::LatestPact, {resource_name: "latest_pact_publication_for_branch"}
|
67
68
|
add ["pacts", "provider", :provider_name], Api::Resources::ProviderPacts, {resource_name: "provider_pact_publications"}
|
68
69
|
add ["pacts", "provider", :provider_name, "tag", :tag], Api::Resources::ProviderPacts, {resource_name: "tagged_provider_pact_publications"}
|
69
70
|
add ["pacts", "provider", :provider_name, "consumer", :consumer_name, "latest-untagged"], Api::Resources::LatestPact, {resource_name: "latest_untagged_pact_publication", tag: :untagged}
|
@@ -86,12 +87,16 @@ module PactBroker
|
|
86
87
|
|
87
88
|
# Versions
|
88
89
|
add ["pacticipants", :pacticipant_name, "versions"], Api::Resources::Versions, {resource_name: "pacticipant_versions"}
|
90
|
+
add ["pacticipants", :pacticipant_name, "branches", :branch_name, "versions"], Api::Resources::BranchVersions, {resource_name: "pacticipant_branch_versions"}
|
89
91
|
add ["pacticipants", :pacticipant_name, "versions", :pacticipant_version_number], Api::Resources::Version, {resource_name: "pacticipant_version"}
|
90
92
|
add ["pacticipants", :pacticipant_name, "latest-version", :tag], Api::Resources::LatestVersion, {resource_name: "latest_tagged_pacticipant_version"}
|
91
93
|
add ["pacticipants", :pacticipant_name, "latest-version", :tag, "can-i-deploy", "to", :to], Api::Resources::CanIDeployPacticipantVersionByTagToTag, { resource_name: "can_i_deploy_latest_tagged_version_to_tag" }
|
92
94
|
add ["pacticipants", :pacticipant_name, "latest-version", :tag, "can-i-deploy", "to", :to, "badge"], Api::Resources::CanIDeployPacticipantVersionByTagToTagBadge, { resource_name: "can_i_deploy_latest_tagged_version_to_tag_badge" }
|
93
95
|
add ["pacticipants", :pacticipant_name, "latest-version"], Api::Resources::LatestVersion, {resource_name: "latest_pacticipant_version"}
|
94
96
|
add ["pacticipants", :pacticipant_name, "versions", :pacticipant_version_number, "tags", :tag_name], Api::Resources::Tag, {resource_name: "pacticipant_version_tag"}
|
97
|
+
add ["pacticipants", :pacticipant_name, "branches"], Api::Resources::PacticipantBranches, {resource_name: "pacticipant_branches"}
|
98
|
+
add ["pacticipants", :pacticipant_name, "branches", :branch_name], Api::Resources::Branch, { resource_name: "branch" }
|
99
|
+
add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version"], Api::Resources::LatestVersion, { resource_name: "latest_pacticipant_version_for_branch" }
|
95
100
|
add ["pacticipants", :pacticipant_name, "branches", :branch_name, "versions", :version_number], Api::Resources::BranchVersion, { resource_name: "branch_version" }
|
96
101
|
add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version", "can-i-deploy", "to-environment", :environment_name], Api::Resources::CanIDeployPacticipantVersionByBranchToEnvironment, { resource_name: "can_i_deploy_latest_branch_version_to_environment" }
|
97
102
|
add ["pacticipants", :pacticipant_name, "branches", :branch_name, "latest-version", "can-i-deploy", "to-environment", :environment_name, "badge"], Api::Resources::CanIDeployPacticipantVersionByBranchToEnvironmentBadge, { resource_name: "can_i_deploy_latest_branch_version_to_environment_badge" }
|
data/lib/pact_broker/app.rb
CHANGED
@@ -21,14 +21,17 @@ require "rack/pact_broker/ui_authentication"
|
|
21
21
|
require "rack/pact_broker/configurable_make_it_later"
|
22
22
|
require "rack/pact_broker/no_auth"
|
23
23
|
require "rack/pact_broker/reset_thread_data"
|
24
|
+
require "rack/pact_broker/add_cache_header"
|
24
25
|
require "rack/pact_broker/add_vary_header"
|
25
26
|
require "rack/pact_broker/use_when"
|
27
|
+
require "rack/pact_broker/application_context"
|
26
28
|
require "sucker_punch"
|
27
29
|
require "pact_broker/api/middleware/configuration"
|
28
30
|
require "pact_broker/api/middleware/basic_auth"
|
29
31
|
require "pact_broker/config/basic_auth_configuration"
|
30
32
|
require "pact_broker/api/authorization/resource_access_policy"
|
31
33
|
require "pact_broker/api/middleware/http_debug_logs"
|
34
|
+
require "pact_broker/application_context"
|
32
35
|
|
33
36
|
module PactBroker
|
34
37
|
|
@@ -36,15 +39,16 @@ module PactBroker
|
|
36
39
|
include PactBroker::Logging
|
37
40
|
using Rack::PactBroker::UseWhen
|
38
41
|
|
39
|
-
attr_accessor :configuration
|
42
|
+
attr_accessor :configuration, :application_context
|
40
43
|
|
41
|
-
def initialize
|
44
|
+
def initialize(application_context = PactBroker::ApplicationContext.default_application_context)
|
45
|
+
@application_context = application_context
|
42
46
|
@app_builder = ::Rack::Builder.new
|
43
47
|
@cascade_apps = []
|
44
48
|
@make_it_later_api_auth = ::Rack::PactBroker::ConfigurableMakeItLater.new(Rack::PactBroker::NoAuth)
|
45
49
|
@make_it_later_ui_auth = ::Rack::PactBroker::ConfigurableMakeItLater.new(Rack::PactBroker::NoAuth)
|
46
50
|
# Can only be required after database connection has been made because the decorators rely on the Sequel models
|
47
|
-
@create_pact_broker_api_block = ->() { require "pact_broker/api"; PactBroker
|
51
|
+
@create_pact_broker_api_block = ->() { require "pact_broker/api"; PactBroker.build_api(application_context) }
|
48
52
|
@configuration = PactBroker.configuration
|
49
53
|
yield configuration if block_given?
|
50
54
|
post_configure
|
@@ -55,7 +59,7 @@ module PactBroker
|
|
55
59
|
@configuration.freeze
|
56
60
|
end
|
57
61
|
|
58
|
-
# Allows middleware to be inserted at the bottom of the shared
|
62
|
+
# Allows middleware to be inserted at the bottom of the shared middleware stack
|
59
63
|
# (ie just before the cascade is called for diagnostic, UI and API).
|
60
64
|
# To insert middleware at the top of the stack, initialize
|
61
65
|
# the middleware with the app, and run it manually.
|
@@ -177,12 +181,14 @@ module PactBroker
|
|
177
181
|
@app_builder.use PactBroker::Api::Middleware::HttpDebugLogs if configuration.http_debug_logging_enabled
|
178
182
|
configure_basic_auth
|
179
183
|
configure_rack_protection
|
184
|
+
@app_builder.use Rack::PactBroker::ApplicationContext, application_context
|
180
185
|
@app_builder.use Rack::PactBroker::InvalidUriProtection
|
181
186
|
@app_builder.use Rack::PactBroker::ResetThreadData
|
182
187
|
@app_builder.use Rack::PactBroker::AddPactBrokerVersionHeader
|
183
188
|
@app_builder.use Rack::PactBroker::AddVaryHeader
|
184
189
|
@app_builder.use Rack::Static, :urls => ["/stylesheets", "/css", "/fonts", "/js", "/javascripts", "/images"], :root => PactBroker.project_root.join("public")
|
185
190
|
@app_builder.use Rack::Static, :urls => ["/favicon.ico"], :root => PactBroker.project_root.join("public/images"), header_rules: [[:all, {"Content-Type" => "image/x-icon"}]]
|
191
|
+
@app_builder.use Rack::PactBroker::AddCacheHeader
|
186
192
|
@app_builder.use Rack::PactBroker::ConvertFileExtensionToAcceptHeader
|
187
193
|
# Rack::PactBroker::SetBaseUrl needs to be before the Rack::PactBroker::HalBrowserRedirect
|
188
194
|
@app_builder.use Rack::PactBroker::SetBaseUrl, configuration.base_urls
|
@@ -1,10 +1,3 @@
|
|
1
|
-
require "pact_broker/api/decorators/configuration"
|
2
|
-
require "pact_broker/api/contracts/configuration"
|
3
|
-
require "pact_broker/api/decorators/decorator_context_creator"
|
4
|
-
require "pact_broker/webhooks/execution_configuration_creator"
|
5
|
-
require "pact_broker/errors/error_logger"
|
6
|
-
require "pact_broker/api/resources/error_response_generator"
|
7
|
-
|
8
1
|
module PactBroker
|
9
2
|
class ApplicationContext
|
10
3
|
attr_reader :decorator_configuration,
|
@@ -15,32 +8,43 @@ module PactBroker
|
|
15
8
|
:before_resource,
|
16
9
|
:after_resource,
|
17
10
|
:error_logger,
|
11
|
+
:error_reporter,
|
18
12
|
:error_response_generator
|
19
13
|
|
20
|
-
def initialize(params
|
21
|
-
|
14
|
+
def initialize(params)
|
15
|
+
@decorator_configuration = params[:decorator_configuration]
|
16
|
+
@api_contract_configuration = params[:api_contract_configuration]
|
17
|
+
@decorator_context_creator = params[:decorator_context_creator]
|
18
|
+
@webhook_execution_configuration_creator = params[:webhook_execution_configuration_creator]
|
19
|
+
@resource_authorizer = params[:resource_authorizer]
|
20
|
+
@before_resource = params[:before_resource]
|
21
|
+
@after_resource = params[:after_resource]
|
22
|
+
@error_logger = params[:error_logger]
|
23
|
+
@error_reporter = params[:error_reporter]
|
24
|
+
@error_response_generator = params[:error_response_generator]
|
25
|
+
end
|
26
|
+
|
27
|
+
# TODO pass in configuration
|
28
|
+
def self.default_application_context(overrides = {})
|
29
|
+
require "pact_broker/api/decorators/configuration"
|
30
|
+
require "pact_broker/api/contracts/configuration"
|
31
|
+
require "pact_broker/api/decorators/decorator_context_creator"
|
32
|
+
require "pact_broker/webhooks/execution_configuration_creator"
|
33
|
+
require "pact_broker/errors/error_logger"
|
34
|
+
require "pact_broker/errors/error_reporter"
|
35
|
+
require "pact_broker/api/resources/error_response_generator"
|
36
|
+
|
37
|
+
params = {
|
22
38
|
decorator_configuration: PactBroker::Api::Decorators::Configuration.default_configuration,
|
23
39
|
api_contract_configuration: PactBroker::Api::Contracts::Configuration.default_configuration,
|
24
40
|
decorator_context_creator: PactBroker::Api::Decorators::DecoratorContextCreator,
|
25
41
|
webhook_execution_configuration_creator: PactBroker::Webhooks::ExecutionConfigurationCreator,
|
26
42
|
error_logger: PactBroker::Errors::ErrorLogger,
|
27
|
-
|
28
|
-
|
43
|
+
error_reporter: PactBroker::Errors::ErrorReporter.new(PactBroker.configuration.api_error_reporters),
|
44
|
+
error_response_generator: PactBroker::Api::Resources::ErrorResponseGenerator,
|
45
|
+
}.merge(overrides)
|
29
46
|
|
30
|
-
|
31
|
-
@api_contract_configuration = params_with_defaults[:api_contract_configuration]
|
32
|
-
@decorator_context_creator = params_with_defaults[:decorator_context_creator]
|
33
|
-
@webhook_execution_configuration_creator = params_with_defaults[:webhook_execution_configuration_creator]
|
34
|
-
@resource_authorizer = params_with_defaults[:resource_authorizer]
|
35
|
-
@before_resource = params_with_defaults[:before_resource]
|
36
|
-
@after_resource = params_with_defaults[:after_resource]
|
37
|
-
@error_logger = params_with_defaults[:error_logger]
|
38
|
-
@error_response_generator = params_with_defaults[:error_response_generator]
|
39
|
-
|
40
|
-
end
|
41
|
-
|
42
|
-
def self.default_application_context(overrides = {})
|
43
|
-
ApplicationContext.new(overrides)
|
47
|
+
ApplicationContext.new(params)
|
44
48
|
end
|
45
49
|
end
|
46
50
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Saves a block for execution after the HTTP response has been sent to the user.
|
2
|
+
# When the block is executed, it connects to the database before executing the code.
|
3
|
+
# This is good for doing things that might take a while and don't have to be done before
|
4
|
+
# the response is sent, and don't need retries (in which case, it might be better to use a SuckerPunch Job).
|
5
|
+
#
|
6
|
+
# This leverages a feature of Puma which I'm not sure is meant to be public or not.
|
7
|
+
# There are serveral mentions of it on the internet, so I assume it's ok to use it.
|
8
|
+
# Puma itself uses the rack.after_reply for http request logging.
|
9
|
+
#
|
10
|
+
# https://github.com/search?q=repo%3Apuma%2Fpuma%20rack.after_reply&type=code
|
11
|
+
|
12
|
+
module PactBroker
|
13
|
+
module Async
|
14
|
+
class AfterReply
|
15
|
+
def initialize(rack_env)
|
16
|
+
@rack_env = rack_env
|
17
|
+
@database_connector = rack_env.fetch("pactbroker.database_connector")
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute(&block)
|
21
|
+
dc = @database_connector
|
22
|
+
@rack_env["rack.after_reply"] << lambda {
|
23
|
+
dc.call do
|
24
|
+
block.call
|
25
|
+
end
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -31,6 +31,8 @@ module PactBroker
|
|
31
31
|
include RuntimeConfigurationDatabaseMethods
|
32
32
|
include RuntimeConfigurationBasicAuthMethods
|
33
33
|
|
34
|
+
config_name :pact_broker
|
35
|
+
|
34
36
|
# logging attributes
|
35
37
|
attr_config(
|
36
38
|
log_dir: File.expand_path("./log"),
|
@@ -91,7 +93,8 @@ module PactBroker
|
|
91
93
|
allow_dangerous_contract_modification: false,
|
92
94
|
semver_formats: ["%M.%m.%p%s%d", "%M.%m", "%M"],
|
93
95
|
seed_example_data: true,
|
94
|
-
|
96
|
+
network_diagram_max_pacticipants: 150,
|
97
|
+
features: {}
|
95
98
|
)
|
96
99
|
|
97
100
|
def self.getter_and_setter_method_names
|
@@ -105,8 +108,11 @@ module PactBroker
|
|
105
108
|
config_attributes + config_attributes.collect{ |k| "#{k}=".to_sym } + extra_methods - [:base_url]
|
106
109
|
end
|
107
110
|
|
108
|
-
|
109
|
-
|
111
|
+
coerce_types(
|
112
|
+
features: COERCE_FEATURES,
|
113
|
+
network_diagram_max_pacticipants: :integer,
|
114
|
+
webhook_certificates: COERCE_WEBHOOKS
|
115
|
+
)
|
110
116
|
sensitive_values(:database_url, :database_password)
|
111
117
|
|
112
118
|
def log_level= log_level
|
@@ -179,10 +185,6 @@ module PactBroker
|
|
179
185
|
super(value_to_string_array(main_branch_candidates, "main_branch_candidates"))
|
180
186
|
end
|
181
187
|
|
182
|
-
def features= features
|
183
|
-
super(value_to_string_array(features, "features").collect(&:downcase))
|
184
|
-
end
|
185
|
-
|
186
188
|
def rack_protection_use= rack_protection_use
|
187
189
|
super(value_to_string_array(rack_protection_use, "rack_protection_use")&.collect(&:to_sym))
|
188
190
|
end
|
@@ -191,20 +193,6 @@ module PactBroker
|
|
191
193
|
super(value_to_string_array(rack_protection_except, "rack_protection_except")&.collect(&:to_sym))
|
192
194
|
end
|
193
195
|
|
194
|
-
def webhook_certificates= webhook_certificates
|
195
|
-
if webhook_certificates.is_a?(Array)
|
196
|
-
super(webhook_certificates.collect(&:symbolize_keys))
|
197
|
-
elsif webhook_certificates.is_a?(Hash)
|
198
|
-
if all_keys_are_number_strings?(webhook_certificates)
|
199
|
-
super(convert_hash_with_number_string_keys_to_array(webhook_certificates).collect(&:symbolize_keys))
|
200
|
-
else
|
201
|
-
raise_validation_error("webhook_certificates must be an array, or a hash where each key is an integer in string format.")
|
202
|
-
end
|
203
|
-
elsif !webhook_certificates.nil?
|
204
|
-
raise_validation_error("webhook_certificates cannot be set using a #{webhook_certificates.class}")
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
196
|
def warning_error_classes
|
209
197
|
warning_error_class_names.collect do | class_name |
|
210
198
|
begin
|
@@ -1,15 +1,45 @@
|
|
1
1
|
require "pact_broker/config/space_delimited_string_list"
|
2
2
|
require "pact_broker/config/space_delimited_integer_list"
|
3
|
+
require "pact_broker/hash_refinements"
|
4
|
+
require "pact_broker/error"
|
3
5
|
|
4
6
|
module PactBroker
|
5
7
|
module Config
|
6
8
|
module RuntimeConfigurationCoercionMethods
|
7
9
|
|
8
|
-
|
10
|
+
using PactBroker::HashRefinements
|
11
|
+
|
12
|
+
COERCE_FEATURES = lambda { | value |
|
13
|
+
if value.is_a?(String)
|
14
|
+
value.split(" ").each_with_object({}) { | k, h | h[k.downcase.to_sym] = true }
|
15
|
+
elsif value.is_a?(Array)
|
16
|
+
value.each_with_object({}) { | k, h | h[k.downcase.to_sym] = true }
|
17
|
+
elsif value.is_a?(Hash)
|
18
|
+
value.each_with_object({}) { | (k, v), new_hash | new_hash[k.downcase.to_sym] = Anyway::AutoCast.call(v) }
|
19
|
+
else
|
20
|
+
raise PactBroker::ConfigurationError, "Expected a String, Hash or Array for features but got a #{value.class.name}"
|
21
|
+
end
|
22
|
+
}
|
23
|
+
|
24
|
+
COERCE_WEBHOOKS = lambda { | value |
|
25
|
+
if value.is_a?(Hash) # from env vars
|
26
|
+
if RuntimeConfigurationCoercionMethods.all_keys_are_number_strings?(value)
|
27
|
+
RuntimeConfigurationCoercionMethods.convert_hash_with_number_string_keys_to_array(value).collect(&:symbolize_keys)
|
28
|
+
else
|
29
|
+
raise PactBroker::ConfigurationError, "Could not coerce #{value} into an array of webhook configurations. Please check docs for the expected format."
|
30
|
+
end
|
31
|
+
elsif value.is_a?(Array) # from YAML
|
32
|
+
value.collect(&:symbolize_keys)
|
33
|
+
else
|
34
|
+
raise PactBroker::ConfigurationError, "Webhook certificates cannot be set using a #{value.class}"
|
35
|
+
end
|
36
|
+
}
|
37
|
+
|
38
|
+
def self.all_keys_are_number_strings?(hash)
|
9
39
|
hash.keys.all? { | k | k.to_s.to_i.to_s == k } # is an integer as a string
|
10
40
|
end
|
11
41
|
|
12
|
-
def convert_hash_with_number_string_keys_to_array(hash)
|
42
|
+
def self.convert_hash_with_number_string_keys_to_array(hash)
|
13
43
|
hash.keys.collect{ |k| [k, k.to_i]}.sort_by(&:last).collect(&:first).collect do | key |
|
14
44
|
hash[key]
|
15
45
|
end
|
@@ -27,7 +27,7 @@ module PactBroker
|
|
27
27
|
allow_missing_migration_files: true,
|
28
28
|
validate_database_connection_config: true,
|
29
29
|
database_statement_timeout: 15,
|
30
|
-
metrics_sql_statement_timeout: 30,
|
30
|
+
metrics_sql_statement_timeout: 30, # TODO get rid of this in next major version
|
31
31
|
database_connection_validation_timeout: nil
|
32
32
|
)
|
33
33
|
|