pact_broker 2.107.1 → 2.109.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 +68 -0
- data/Gemfile +5 -6
- 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/publish_contract_decorator.rb +6 -1
- 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_decorator.rb +1 -1
- 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/environment.rb +4 -0
- 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 +16 -7
- 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/publish_contracts.rb +1 -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 -9
- 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/contract_to_publish.rb +4 -5
- data/lib/pact_broker/contracts/contracts_to_publish.rb +8 -0
- data/lib/pact_broker/contracts/service.rb +9 -3
- 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/logging.rb +10 -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/generate_sha.rb +9 -4
- 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_params.rb +1 -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 +12 -13
- 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 +57 -2
- data/lib/pact_broker/ui/controllers/base_controller.rb +4 -2
- 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/ui.rb +20 -9
- 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 +5 -5
- metadata +54 -31
- 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
|
@@ -227,8 +227,24 @@ module PactBroker
|
|
|
227
227
|
"#{tags_url(base_url, tag.version)}/#{url_encode(tag.name)}"
|
|
228
228
|
end
|
|
229
229
|
|
|
230
|
+
def branch_url(branch, base_url = "")
|
|
231
|
+
"#{pacticipant_branches_url(branch.pacticipant, base_url)}/#{url_encode(branch.name)}"
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def pacticipant_branches_url(pacticipant, base_url = "")
|
|
235
|
+
"#{pacticipant_url(base_url, pacticipant)}/branches"
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def branch_versions_url(branch, base_url = "")
|
|
239
|
+
"#{branch_url(branch, base_url)}/versions"
|
|
240
|
+
end
|
|
241
|
+
|
|
230
242
|
def branch_version_url(branch_version, base_url = "")
|
|
231
|
-
"#{
|
|
243
|
+
"#{branch_versions_url(branch_version.branch, base_url)}/#{url_encode(branch_version.version_number)}"
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def latest_version_for_branch_url(branch, base_url = "")
|
|
247
|
+
"#{branch_url(branch, base_url)}/latest-version"
|
|
232
248
|
end
|
|
233
249
|
|
|
234
250
|
def templated_tag_url_for_pacticipant pacticipant_name, base_url = ""
|
|
@@ -271,7 +287,7 @@ module PactBroker
|
|
|
271
287
|
"#{base_url}/webhooks"
|
|
272
288
|
end
|
|
273
289
|
|
|
274
|
-
def webhook_url uuid, base_url
|
|
290
|
+
def webhook_url uuid, base_url = ""
|
|
275
291
|
"#{base_url}/webhooks/#{uuid}"
|
|
276
292
|
end
|
|
277
293
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require "pact_broker/async/after_reply"
|
|
2
|
+
|
|
3
|
+
module PactBroker
|
|
4
|
+
module Api
|
|
5
|
+
module Resources
|
|
6
|
+
module AfterReply
|
|
7
|
+
|
|
8
|
+
# @param [Callable] block the block to execute after the response has been sent to the user.
|
|
9
|
+
def after_reply(&block)
|
|
10
|
+
PactBroker::Async::AfterReply.new(request.env).execute(&block)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -38,7 +38,7 @@ module PactBroker
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def from_json
|
|
41
|
-
saved_webhook = webhook_service.create(next_uuid, webhook,
|
|
41
|
+
saved_webhook = webhook_service.create(next_uuid, webhook, webhook_consumer, webhook_provider)
|
|
42
42
|
response.body = decorator_class(:webhook_decorator).new(saved_webhook).to_json(**decorator_options)
|
|
43
43
|
end
|
|
44
44
|
|
|
@@ -60,11 +60,11 @@ module PactBroker
|
|
|
60
60
|
api_contract_class(:webhook_contract)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
def
|
|
63
|
+
def webhook_consumer
|
|
64
64
|
webhook.consumer&.name ? pacticipant_service.find_pacticipant_by_name(webhook.consumer.name) : nil
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
def
|
|
67
|
+
def webhook_provider
|
|
68
68
|
webhook.provider&.name ? pacticipant_service.find_pacticipant_by_name(webhook.provider.name) : nil
|
|
69
69
|
end
|
|
70
70
|
|
|
@@ -37,7 +37,8 @@ module PactBroker
|
|
|
37
37
|
badge_url
|
|
38
38
|
rescue StandardError => e
|
|
39
39
|
# Want to render a badge, even if there's an error
|
|
40
|
-
|
|
40
|
+
error_reference = log_and_report_error(e)
|
|
41
|
+
badge_service.error_badge_url("error", "reference: #{error_reference}")
|
|
41
42
|
end
|
|
42
43
|
end
|
|
43
44
|
|
|
@@ -10,6 +10,7 @@ require "pact_broker/pacts/pact_params"
|
|
|
10
10
|
require "pact_broker/api/resources/authentication"
|
|
11
11
|
require "pact_broker/api/resources/authorization"
|
|
12
12
|
require "pact_broker/errors"
|
|
13
|
+
require "pact_broker/messages"
|
|
13
14
|
require "pact_broker/api/resources/error_handling_methods"
|
|
14
15
|
require "pact_broker/api/contracts/utf_8_validation"
|
|
15
16
|
|
|
@@ -26,7 +27,7 @@ module PactBroker
|
|
|
26
27
|
include PactBroker::Api::Resources::Authorization
|
|
27
28
|
include PactBroker::Api::Resources::ErrorHandlingMethods
|
|
28
29
|
include PactBroker::Api::Contracts::UTF8Validation
|
|
29
|
-
|
|
30
|
+
include PactBroker::Messages
|
|
30
31
|
include PactBroker::Logging
|
|
31
32
|
|
|
32
33
|
attr_accessor :user
|
|
@@ -206,7 +207,7 @@ module PactBroker
|
|
|
206
207
|
def find_pacticipant name, role
|
|
207
208
|
pacticipant_service.find_pacticipant_by_name(name).tap do | pacticipant |
|
|
208
209
|
if pacticipant.nil?
|
|
209
|
-
set_json_error_message("No #{role} with name '#{name}' found", title: "Not found", type: "
|
|
210
|
+
set_json_error_message("No #{role} with name '#{name}' found", title: "Not found", type: "not-found", status: 404)
|
|
210
211
|
end
|
|
211
212
|
end
|
|
212
213
|
end
|
|
@@ -257,8 +258,9 @@ module PactBroker
|
|
|
257
258
|
end
|
|
258
259
|
|
|
259
260
|
def validation_errors_for_schema?(schema_to_use = schema, params_to_validate = params)
|
|
260
|
-
|
|
261
|
-
|
|
261
|
+
result = schema_to_use.call(params_to_validate)
|
|
262
|
+
if result.errors.any?
|
|
263
|
+
set_json_validation_error_messages(result.errors)
|
|
262
264
|
true
|
|
263
265
|
else
|
|
264
266
|
false
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "pact_broker/api/resources/base_resource"
|
|
2
|
+
|
|
3
|
+
module PactBroker
|
|
4
|
+
module Api
|
|
5
|
+
module Resources
|
|
6
|
+
class Branch < BaseResource
|
|
7
|
+
def content_types_provided
|
|
8
|
+
[["application/hal+json", :to_json]]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def allowed_methods
|
|
12
|
+
["GET", "DELETE", "OPTIONS"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def resource_exists?
|
|
16
|
+
!!branch
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_json
|
|
20
|
+
decorator_class(:branch_decorator).new(branch).to_json(**decorator_options)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def delete_resource
|
|
24
|
+
branch_service.delete_branch(branch)
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def policy_name
|
|
29
|
+
:'versions::branch'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def branch
|
|
35
|
+
@branch_version ||= branch_service.find_branch(**identifier_from_path.slice(:pacticipant_name, :branch_name))
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require "pact_broker/api/resources/base_resource"
|
|
2
|
+
require "pact_broker/configuration"
|
|
3
|
+
require "pact_broker/api/decorators/versions_decorator"
|
|
4
|
+
require "pact_broker/api/resources/pagination_methods"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module PactBroker
|
|
8
|
+
module Api
|
|
9
|
+
module Resources
|
|
10
|
+
class BranchVersions < BaseResource
|
|
11
|
+
include PaginationMethods
|
|
12
|
+
|
|
13
|
+
def content_types_provided
|
|
14
|
+
[["application/hal+json", :to_json]]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def allowed_methods
|
|
18
|
+
["GET", "OPTIONS"]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def malformed_request?
|
|
22
|
+
super || request.get? && validation_errors_for_schema?(schema, request.query)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def resource_exists?
|
|
26
|
+
!!branch
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def to_json
|
|
30
|
+
decorator_class(:versions_decorator).new(versions).to_json(**decorator_options(identifier_from_path.merge(resource_title: resource_title)))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def versions
|
|
34
|
+
@versions ||= version_service.find_pacticipant_versions_in_reverse_order(pacticipant_name, { branch_name: identifier_from_path[:branch_name] }, pagination_options)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def policy_name
|
|
38
|
+
:'versions::versions'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def branch
|
|
42
|
+
@branch ||= branch_service.find_branch(**identifier_from_path.slice(:pacticipant_name, :branch_name))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def resource_title
|
|
46
|
+
"Versions for branch #{branch.name} of #{branch.pacticipant.name}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def schema
|
|
52
|
+
if request.get?
|
|
53
|
+
PactBroker::Api::Contracts::PaginationQueryParamsSchema
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -14,7 +14,7 @@ module PactBroker
|
|
|
14
14
|
elsif pacticipant.nil?
|
|
15
15
|
badge_service.error_badge_url("pacticipant", "not found")
|
|
16
16
|
elsif version.nil?
|
|
17
|
-
if branch_service.find_branch(identifier_from_path.slice(:pacticipant_name, :branch_name)).nil?
|
|
17
|
+
if branch_service.find_branch(**identifier_from_path.slice(:pacticipant_name, :branch_name)).nil?
|
|
18
18
|
badge_service.error_badge_url("branch", "not found")
|
|
19
19
|
else
|
|
20
20
|
badge_service.error_badge_url("version", "not found")
|
|
@@ -21,7 +21,7 @@ module PactBroker
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def to_json
|
|
24
|
-
decorator_class(decorator_name).new(deployed_versions).to_json(**decorator_options(title: title))
|
|
24
|
+
decorator_class(decorator_name).new(deployed_versions).to_json(**decorator_options(title: title, expand: [:pacticipant, :version]))
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def policy_name
|
|
@@ -21,7 +21,7 @@ module PactBroker
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def to_json
|
|
24
|
-
decorator_class(decorator_name).new(released_versions).to_json(**decorator_options(title: title))
|
|
24
|
+
decorator_class(decorator_name).new(released_versions).to_json(**decorator_options(title: title, expand: [:pacticipant, :version]))
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def policy_name
|
|
@@ -20,6 +20,10 @@ module PactBroker
|
|
|
20
20
|
["GET", "OPTIONS"]
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
def malformed_request?
|
|
24
|
+
super || (request.get? && validation_errors_for_schema?(schema, request.query))
|
|
25
|
+
end
|
|
26
|
+
|
|
23
27
|
def to_json
|
|
24
28
|
decorator_class(:dashboard_decorator).new(index_items).to_json(**decorator_options)
|
|
25
29
|
end
|
|
@@ -34,6 +38,12 @@ module PactBroker
|
|
|
34
38
|
|
|
35
39
|
private
|
|
36
40
|
|
|
41
|
+
def schema
|
|
42
|
+
if request.get?
|
|
43
|
+
PactBroker::Api::Contracts::PaginationQueryParamsSchema
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
37
47
|
def index_items
|
|
38
48
|
index_service.find_index_items_for_api(**identifier_from_path.merge(pagination_options))
|
|
39
49
|
end
|
|
@@ -78,7 +78,7 @@ module PactBroker
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def title
|
|
81
|
-
"Deployed versions for #{pacticipant_name} version #{pacticipant_version_number}"
|
|
81
|
+
"Deployed versions for #{pacticipant_name} version #{pacticipant_version_number} in environment #{environment.display_name}"
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
84
|
end
|
|
@@ -60,7 +60,7 @@ module PactBroker
|
|
|
60
60
|
|
|
61
61
|
def environments
|
|
62
62
|
@environments ||= if request.query["name"]
|
|
63
|
-
[environment_service.find_by_name(request.query["name"])]
|
|
63
|
+
[environment_service.find_by_name(request.query["name"])].compact
|
|
64
64
|
else
|
|
65
65
|
environment_service.find_all
|
|
66
66
|
end
|
|
@@ -1,70 +1,36 @@
|
|
|
1
1
|
require "pact_broker/configuration"
|
|
2
2
|
require "securerandom"
|
|
3
3
|
|
|
4
|
+
# Logs the error
|
|
5
|
+
# Reports the error
|
|
6
|
+
# Generates and returns response headers and response body
|
|
7
|
+
|
|
4
8
|
module PactBroker
|
|
5
9
|
module Api
|
|
6
10
|
module Resources
|
|
7
11
|
class ErrorHandler
|
|
8
12
|
include PactBroker::Logging
|
|
9
13
|
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
elsif reportable?(e)
|
|
15
|
-
log_error(e, "Error reference #{error_reference}")
|
|
16
|
-
report(e, error_reference, request)
|
|
17
|
-
else
|
|
18
|
-
logger.info("Error reference #{error_reference}", e)
|
|
19
|
-
end
|
|
20
|
-
response.body = response_body_hash(e, error_reference).to_json
|
|
14
|
+
def initialize(error_logger, error_response_generator, error_reporter)
|
|
15
|
+
@error_logger = error_logger
|
|
16
|
+
@error_response_generator = error_response_generator
|
|
17
|
+
@error_reporter = error_reporter
|
|
21
18
|
end
|
|
22
19
|
|
|
23
|
-
def
|
|
24
|
-
|
|
25
|
-
end
|
|
20
|
+
def call(error, env, message = nil)
|
|
21
|
+
error_reference = PactBroker::Errors.generate_error_reference
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
end
|
|
23
|
+
# log error
|
|
24
|
+
error_logger.call(error, error_reference, env)
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
end
|
|
26
|
+
# report error
|
|
27
|
+
error_reporter.call(error, error_reference, env)
|
|
34
28
|
|
|
35
|
-
def self.display_message(e, obfuscated_message)
|
|
36
|
-
if PactBroker.configuration.show_backtrace_in_error_response?
|
|
37
|
-
e.message || obfuscated_message
|
|
38
|
-
else
|
|
39
|
-
reportable?(e) ? obfuscated_message : e.message
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def self.obfuscated_error_message error_reference
|
|
44
|
-
"An error has occurred. The details have been logged with the reference #{error_reference}"
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def self.response_body_hash e, error_reference
|
|
48
|
-
response_body = {
|
|
49
|
-
error: {
|
|
50
|
-
message: display_message(e, obfuscated_error_message(error_reference)),
|
|
51
|
-
reference: error_reference
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
if PactBroker.configuration.show_backtrace_in_error_response?
|
|
55
|
-
response_body[:error][:backtrace] = e.backtrace
|
|
56
|
-
end
|
|
57
|
-
response_body
|
|
58
|
-
end
|
|
59
29
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
rescue StandardError => e
|
|
65
|
-
log_error(e, "Error executing api_error_reporter")
|
|
66
|
-
end
|
|
67
|
-
end
|
|
30
|
+
# generate response
|
|
31
|
+
headers, body = error_response_generator.call(error, error_reference, env, message: message)
|
|
32
|
+
headers.each { | key, value | response.headers[key] = value }
|
|
33
|
+
return headers, body
|
|
68
34
|
end
|
|
69
35
|
end
|
|
70
36
|
end
|
|
@@ -7,29 +7,39 @@ module PactBroker
|
|
|
7
7
|
module ErrorHandlingMethods
|
|
8
8
|
|
|
9
9
|
# @override
|
|
10
|
+
# @param [StandardError] error
|
|
10
11
|
def handle_exception(error)
|
|
11
|
-
error_reference =
|
|
12
|
-
application_context.error_logger.call(error, error_reference, request.env)
|
|
13
|
-
if PactBroker::Errors.reportable_error?(error)
|
|
14
|
-
PactBroker::Errors.report(error, error_reference, request.env)
|
|
15
|
-
end
|
|
12
|
+
error_reference = log_and_report_error(error)
|
|
16
13
|
headers, body = application_context.error_response_generator.call(error, error_reference, request.env)
|
|
17
14
|
headers.each { | key, value | response.headers[key] = value }
|
|
18
15
|
response.body = body
|
|
19
16
|
end
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
# @param [StandardError] error
|
|
19
|
+
def log_and_report_error(error)
|
|
20
|
+
# generate reference
|
|
21
|
+
error_reference = PactBroker::Errors.generate_error_reference
|
|
22
|
+
# log error
|
|
23
|
+
application_context.error_logger.call(error, error_reference, request.env)
|
|
24
|
+
# report error
|
|
25
|
+
application_context.error_reporter.call(error, error_reference, request.env)
|
|
26
|
+
# generate response
|
|
27
|
+
error_reference
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @param [String] detail
|
|
31
|
+
# @param [String] title
|
|
32
|
+
# @param [String] type
|
|
33
|
+
# @param [Integer] status
|
|
34
|
+
def set_json_error_message(detail, title: "Server error", type: "server-error", status: 500)
|
|
22
35
|
response.headers["Content-Type"] = error_response_content_type
|
|
23
36
|
response.body = error_response_body(detail, title, type, status)
|
|
24
37
|
end
|
|
25
38
|
|
|
26
|
-
|
|
39
|
+
# @param [Hash,Dry::Validation::MessageSet] errors
|
|
40
|
+
def set_json_validation_error_messages(errors)
|
|
27
41
|
response.headers["Content-Type"] = error_response_content_type
|
|
28
|
-
|
|
29
|
-
response.body = PactBroker::Api::Decorators::ValidationErrorsProblemJSONDecorator.new(errors).to_json(**decorator_options)
|
|
30
|
-
else
|
|
31
|
-
response.body = { errors: errors }.to_json
|
|
32
|
-
end
|
|
42
|
+
response.body = validation_errors_response_body(errors)
|
|
33
43
|
end
|
|
34
44
|
|
|
35
45
|
def error_response_content_type
|
|
@@ -42,15 +52,31 @@ module PactBroker
|
|
|
42
52
|
|
|
43
53
|
def error_response_body(detail, title, type, status)
|
|
44
54
|
if problem_json_error_content_type?
|
|
45
|
-
|
|
55
|
+
decorator_class(:custom_error_problem_json_decorator).new(detail: detail, title: title, type: type, status: status).to_json(**decorator_options_for_error)
|
|
46
56
|
else
|
|
47
|
-
|
|
57
|
+
decorator_class(:error_decorator).new(detail).to_json
|
|
48
58
|
end
|
|
49
59
|
end
|
|
50
60
|
|
|
61
|
+
# @param [Hash,Dry::Validation::MessageSet] errors
|
|
62
|
+
def validation_errors_response_body(errors)
|
|
63
|
+
validation_errors_decorator_class(errors).new(errors).to_json(**decorator_options_for_error)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @param [Hash,Dry::Validation::MessageSet] errors
|
|
67
|
+
def validation_errors_decorator_class(errors)
|
|
68
|
+
application_context.decorator_configuration.validation_error_decorator_class_for(errors.class, request.headers["Accept"])
|
|
69
|
+
end
|
|
70
|
+
|
|
51
71
|
def problem_json_error_content_type?
|
|
52
72
|
request.headers["Accept"]&.include?("application/problem+json")
|
|
53
73
|
end
|
|
74
|
+
|
|
75
|
+
# If we use the normal decorator options that have policy objects we can get into recursive loops in Pactflow, so just make a simple variant of the
|
|
76
|
+
# decorator options here
|
|
77
|
+
def decorator_options_for_error
|
|
78
|
+
{ user_options: { base_url: base_url } }
|
|
79
|
+
end
|
|
54
80
|
end
|
|
55
81
|
end
|
|
56
82
|
end
|
|
@@ -1,23 +1,36 @@
|
|
|
1
1
|
require "pact_broker/configuration"
|
|
2
2
|
require "pact_broker/api/decorators/runtime_error_problem_json_decorator"
|
|
3
|
+
require "pact_broker/errors"
|
|
4
|
+
require "pact_broker/messages"
|
|
5
|
+
|
|
6
|
+
# Generates the response headers and body for use when there is a runtime
|
|
7
|
+
# error in the business logic (services and repositories) when executing a Webmachine resource request.
|
|
8
|
+
# Obfuscates any exception messages that might expose vulnerablities in production.
|
|
9
|
+
# Uses the Accept header to determine whether to return application/problem+json
|
|
10
|
+
# or application/hal+json, for backwards compatibility.
|
|
11
|
+
# In the next major version of the Pact Broker, all error responses
|
|
12
|
+
# should use problem+json, regardless of Accept headers.
|
|
3
13
|
|
|
4
14
|
module PactBroker
|
|
5
15
|
module Api
|
|
6
16
|
module Resources
|
|
7
17
|
class ErrorResponseGenerator
|
|
8
18
|
include PactBroker::Logging
|
|
19
|
+
extend PactBroker::Messages
|
|
9
20
|
|
|
10
21
|
# @param error [StandardError]
|
|
11
22
|
# @param error_reference [String] an error reference to display to the user
|
|
12
23
|
# @param env [Hash] the rack env
|
|
13
24
|
# @return [Hash, String] the response headers to set, the response body to set
|
|
14
|
-
def self.call
|
|
15
|
-
body = response_body_hash(error, error_reference, env, display_message(error, obfuscated_error_message(error_reference)))
|
|
25
|
+
def self.call(error, error_reference, env, message: nil)
|
|
26
|
+
body = response_body_hash(error, error_reference, env, display_message(error, message, obfuscated_error_message(error_reference)))
|
|
16
27
|
return headers(env), body.to_json
|
|
17
28
|
end
|
|
18
29
|
|
|
19
|
-
def self.display_message(error, obfuscated_message)
|
|
20
|
-
if
|
|
30
|
+
def self.display_message(error, message, obfuscated_message)
|
|
31
|
+
if message
|
|
32
|
+
message
|
|
33
|
+
elsif PactBroker.configuration.show_backtrace_in_error_response?
|
|
21
34
|
error.message || obfuscated_message
|
|
22
35
|
else
|
|
23
36
|
PactBroker::Errors.reportable_error?(error) ? obfuscated_message : error.message
|
|
@@ -46,11 +59,11 @@ module PactBroker
|
|
|
46
59
|
end
|
|
47
60
|
|
|
48
61
|
private_class_method def self.problem_json_response_body(message, env)
|
|
49
|
-
|
|
62
|
+
error_decorator_class(env).new(message).to_hash(user_options: { base_url: env["pactbroker.base_url" ] })
|
|
50
63
|
end
|
|
51
64
|
|
|
52
65
|
private_class_method def self.obfuscated_error_message(error_reference)
|
|
53
|
-
"
|
|
66
|
+
message("errors.runtime.with_error_reference", error_reference: error_reference)
|
|
54
67
|
end
|
|
55
68
|
|
|
56
69
|
private_class_method def self.headers(env)
|
|
@@ -64,6 +77,10 @@ module PactBroker
|
|
|
64
77
|
private_class_method def self.problem_json?(env)
|
|
65
78
|
env["HTTP_ACCEPT"]&.include?("application/problem+json")
|
|
66
79
|
end
|
|
80
|
+
|
|
81
|
+
private_class_method def self.error_decorator_class(env)
|
|
82
|
+
env["pactbroker.application_context"].decorator_configuration.class_for(:runtime_error_problem_json_decorator)
|
|
83
|
+
end
|
|
67
84
|
end
|
|
68
85
|
end
|
|
69
86
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "pact_broker/string_refinements"
|
|
1
2
|
require "pact_broker/api/resources/base_resource"
|
|
2
3
|
require "pact_broker/api/decorators/relationships_csv_decorator"
|
|
3
4
|
|
|
@@ -5,6 +6,8 @@ module PactBroker
|
|
|
5
6
|
module Api
|
|
6
7
|
module Resources
|
|
7
8
|
class Group < BaseResource
|
|
9
|
+
using PactBroker::StringRefinements
|
|
10
|
+
|
|
8
11
|
def content_types_provided
|
|
9
12
|
[["text/csv", :to_csv]]
|
|
10
13
|
end
|
|
@@ -32,9 +35,15 @@ module PactBroker
|
|
|
32
35
|
private
|
|
33
36
|
|
|
34
37
|
def group
|
|
35
|
-
@group ||= group_service.find_group_containing(pacticipant)
|
|
38
|
+
@group ||= group_service.find_group_containing(pacticipant, max_pacticipants: max_pacticipants)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def max_pacticipants
|
|
42
|
+
if request.query["maxPacticipants"]&.integer?
|
|
43
|
+
request.query["maxPacticipants"].to_i
|
|
44
|
+
end
|
|
36
45
|
end
|
|
37
46
|
end
|
|
38
47
|
end
|
|
39
48
|
end
|
|
40
|
-
end
|
|
49
|
+
end
|
|
@@ -116,6 +116,12 @@ module PactBroker
|
|
|
116
116
|
title: "Get, create or delete a tag for a pacticipant version",
|
|
117
117
|
templated: true
|
|
118
118
|
},
|
|
119
|
+
"pb:pacticipant-branch" =>
|
|
120
|
+
{
|
|
121
|
+
href: base_url + "/pacticipants/{pacticipant}/branches/{branch}",
|
|
122
|
+
title: "Get or delete a pacticipant branch",
|
|
123
|
+
templated: true
|
|
124
|
+
},
|
|
119
125
|
"pb:pacticipant-branch-version" =>
|
|
120
126
|
{
|
|
121
127
|
href: base_url + "/pacticipants/{pacticipant}/branches/{branch}/versions/{version}",
|