Skip to content

Commit

Permalink
Merge branch 'shen-sat-54/Support_webhook_upsert'
Browse files Browse the repository at this point in the history
  • Loading branch information
bethesque committed Feb 13, 2020
2 parents 6c24c6f + f3f0bef commit 32f6c4c
Show file tree
Hide file tree
Showing 11 changed files with 539 additions and 227 deletions.
87 changes: 87 additions & 0 deletions doc/pacts/markdown/Pact Broker Client - Pact Broker.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

* [A request for the index resource](#a_request_for_the_index_resource_given_the_pb:latest-version_relation_exists_in_the_index_resource) given the pb:latest-version relation exists in the index resource

* [A request for the index resource with the webhook relation](#a_request_for_the_index_resource_with_the_webhook_relation)

* [A request for the list of the latest pacts from all consumers for the Pricing Service'](#a_request_for_the_list_of_the_latest_pacts_from_all_consumers_for_the_Pricing_Service'_given_a_latest_pact_between_Condor_and_the_Pricing_Service_exists) given a latest pact between Condor and the Pricing Service exists

* [A request for the list of the latest prod pacts from all consumers for the Pricing Service'](#a_request_for_the_list_of_the_latest_prod_pacts_from_all_consumers_for_the_Pricing_Service'_given_tagged_as_prod_pact_between_Condor_and_the_Pricing_Service_exists) given tagged as prod pact between Condor and the Pricing Service exists
Expand All @@ -38,6 +40,8 @@

* [A request to create a webhook for a consumer and provider](#a_request_to_create_a_webhook_for_a_consumer_and_provider_given_'Condor'_does_not_exist_in_the_pact-broker) given 'Condor' does not exist in the pact-broker

* [A request to create a webhook with a JSON body and a uuid](#a_request_to_create_a_webhook_with_a_JSON_body_and_a_uuid_given_the_'Pricing_Service'_and_'Condor'_already_exist_in_the_pact-broker) given the 'Pricing Service' and 'Condor' already exist in the pact-broker

* [A request to create a webhook with a JSON body for a consumer](#a_request_to_create_a_webhook_with_a_JSON_body_for_a_consumer_given_the_'Pricing_Service'_and_'Condor'_already_exist_in_the_pact-broker) given the 'Pricing Service' and 'Condor' already exist in the pact-broker

* [A request to create a webhook with a JSON body for a consumer and provider](#a_request_to_create_a_webhook_with_a_JSON_body_for_a_consumer_and_provider_given_the_'Pricing_Service'_and_'Condor'_already_exist_in_the_pact-broker) given the 'Pricing Service' and 'Condor' already exist in the pact-broker
Expand Down Expand Up @@ -557,6 +561,34 @@ Pact Broker will respond with:
}
}
```
<a name="a_request_for_the_index_resource_with_the_webhook_relation"></a>
Upon receiving **a request for the index resource with the webhook relation** from Pact Broker Client, with
```json
{
"method": "get",
"path": "/",
"headers": {
"Accept": "application/hal+json"
}
}
```
Pact Broker will respond with:
```json
{
"status": 200,
"headers": {
"Content-Type": "application/hal+json;charset=utf-8"
},
"body": {
"_links": {
"pb:webhook": {
"href": "http://localhost:1234/webhooks/{uuid}",
"templated": true
}
}
}
}
```
<a name="a_request_for_the_list_of_the_latest_pacts_from_all_consumers_for_the_Pricing_Service&#39;_given_a_latest_pact_between_Condor_and_the_Pricing_Service_exists"></a>
Given **a latest pact between Condor and the Pricing Service exists**, upon receiving **a request for the list of the latest pacts from all consumers for the Pricing Service'** from Pact Broker Client, with
```json
Expand Down Expand Up @@ -781,6 +813,61 @@ Pact Broker will respond with:
}
}
```
<a name="a_request_to_create_a_webhook_with_a_JSON_body_and_a_uuid_given_the_&#39;Pricing_Service&#39;_and_&#39;Condor&#39;_already_exist_in_the_pact-broker"></a>
Given **the 'Pricing Service' and 'Condor' already exist in the pact-broker**, upon receiving **a request to create a webhook with a JSON body and a uuid** from Pact Broker Client, with
```json
{
"method": "put",
"path": "/webhooks/9999",
"headers": {
"Content-Type": "application/json",
"Accept": "application/hal+json"
},
"body": {
"events": [
{
"name": "contract_content_changed"
}
],
"request": {
"url": "https://webhook",
"method": "POST",
"headers": {
"Foo": "bar",
"Bar": "foo"
},
"body": {
"some": "body"
},
"username": "username",
"password": "password"
},
"provider": {
"name": "Pricing Service"
},
"consumer": {
"name": "Condor"
}
}
}
```
Pact Broker will respond with:
```json
{
"status": 201,
"headers": {
"Content-Type": "application/hal+json;charset=utf-8"
},
"body": {
"_links": {
"self": {
"href": "http://localhost:1234/some-url",
"title": "A title"
}
}
}
}
```
<a name="a_request_to_create_a_webhook_with_a_JSON_body_for_a_consumer_given_the_&#39;Pricing_Service&#39;_and_&#39;Condor&#39;_already_exist_in_the_pact-broker"></a>
Given **the 'Pricing Service' and 'Condor' already exist in the pact-broker**, upon receiving **a request to create a webhook with a JSON body for a consumer** from Pact Broker Client, with
```json
Expand Down
112 changes: 57 additions & 55 deletions lib/pact_broker/client/cli/broker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -109,67 +109,21 @@ def describe_version
exit(1) unless result.success
end

method_option :request, banner: "METHOD", aliases: "-X", desc: "HTTP method", required: true
method_option :header, aliases: "-H", type: :array, desc: "Header"
method_option :data, aliases: "-d", desc: "Data"
method_option :user, aliases: "-u", desc: "Basic auth username and password eg. username:password"
method_option :consumer, desc: "Consumer name"
method_option :provider, desc: "Provider name"
method_option :broker_base_url, required: true, aliases: "-b", desc: "The base URL of the Pact Broker"
method_option :broker_username, desc: "Pact Broker basic auth username"
method_option :broker_password, aliases: "-p", desc: "Pact Broker basic auth password"
method_option :broker_token, aliases: "-k", desc: "Pact Broker bearer token"
method_option :contract_content_changed, type: :boolean, desc: "Trigger this webhook when the pact content changes"
method_option :provider_verification_published, type: :boolean, desc: "Trigger this webhook when a provider verification result is published"
method_option :verbose, aliases: "-v", type: :boolean, default: false, required: false, desc: "Verbose output. Default: false"
shared_options_for_webhook_commands

desc 'create-webhook URL', 'Creates a webhook using the same switches as a curl request.'
long_desc File.read(File.join(File.dirname(__FILE__), 'create_webhook_long_desc.txt'))
def create_webhook webhook_url
require 'pact_broker/client/webhooks/create'

if !(options.contract_content_changed || options.provider_verification_published)
raise PactBroker::Client::Error.new("You must select at least one of --contract-content-changed or --provider-verification-published")
end

username = options.user ? options.user.split(":", 2).first : nil
password = options.user ? options.user.split(":", 2).last : nil

headers = (options.header || []).each_with_object({}) { | header, headers | headers[header.split(":", 2).first.strip] = header.split(":", 2).last.strip }

body = options.data
if body && body.start_with?("@")
filepath = body[1..-1]
begin
body = File.read(filepath)
rescue StandardError => e
raise PactBroker::Client::Error.new("Couldn't read data from file \"#{filepath}\" due to #{e.class} #{e.message}")
end
end

events = []
events << 'contract_content_changed' if options.contract_content_changed
events << 'provider_verification_published' if options.provider_verification_published
run_webhook_commands webhook_url
end

params = {
http_method: options.request,
url: webhook_url,
headers: headers,
username: username,
password: password,
body: body,
consumer: options.consumer,
provider: options.provider,
events: events
}
shared_options_for_webhook_commands
method_option :uuid, type: :string, required: true, desc: "Specify the uuid for the webhook"

begin
result = PactBroker::Client::Webhooks::Create.call(params, options.broker_base_url, pact_broker_client_options)
$stdout.puts result.message
exit(1) unless result.success
rescue PactBroker::Client::Error => e
raise WebhookCreationError, "#{e.class} - #{e.message}"
end
desc 'create-or-update-webhook URL', 'Creates or updates a webhook with a provided uuid and using the same switches as a curl request.'
long_desc File.read(File.join(File.dirname(__FILE__), 'create_or_update_webhook_long_desc.txt'))
def create_or_update_webhook webhook_url
run_webhook_commands webhook_url
end

desc 'version', "Show the pact_broker-client gem version"
Expand Down Expand Up @@ -232,6 +186,54 @@ def pact_broker_client_options

client_options
end

def run_webhook_commands webhook_url
require 'pact_broker/client/webhooks/create'

if !(options.contract_content_changed || options.provider_verification_published)
raise PactBroker::Client::Error.new("You must select at least one of --contract-content-changed or --provider-verification-published")
end

username = options.user ? options.user.split(":", 2).first : nil
password = options.user ? options.user.split(":", 2).last : nil

headers = (options.header || []).each_with_object({}) { | header, headers | headers[header.split(":", 2).first.strip] = header.split(":", 2).last.strip }

body = options.data
if body && body.start_with?("@")
filepath = body[1..-1]
begin
body = File.read(filepath)
rescue StandardError => e
raise PactBroker::Client::Error.new("Couldn't read data from file \"#{filepath}\" due to #{e.class} #{e.message}")
end
end

events = []
events << 'contract_content_changed' if options.contract_content_changed
events << 'provider_verification_published' if options.provider_verification_published

params = {
uuid: options.uuid,
http_method: options.request,
url: webhook_url,
headers: headers,
username: username,
password: password,
body: body,
consumer: options.consumer,
provider: options.provider,
events: events
}

begin
result = PactBroker::Client::Webhooks::Create.call(params, options.broker_base_url, pact_broker_client_options)
$stdout.puts result.message
exit(1) unless result.success
rescue PactBroker::Client::Error => e
raise WebhookCreationError, "#{e.class} - #{e.message}"
end
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Create a curl command that executes the request that you want your webhook to execute, then replace "curl" with "pact-broker create-or-update-webhook" and add the consumer, provider, event types and broker details. Note that the URL must be the first parameter when executing create-webhook and a uuid must also be provided.
16 changes: 16 additions & 0 deletions lib/pact_broker/client/cli/custom_thor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,22 @@ def self.turn_muliple_tag_options_into_array argv
end
new_argv.flatten
end

def self.shared_options_for_webhook_commands
method_option :request, banner: "METHOD", aliases: "-X", desc: "HTTP method", required: true
method_option :header, aliases: "-H", type: :array, desc: "Header"
method_option :data, aliases: "-d", desc: "Data"
method_option :user, aliases: "-u", desc: "Basic auth username and password eg. username:password"
method_option :consumer, desc: "Consumer name"
method_option :provider, desc: "Provider name"
method_option :broker_base_url, required: true, aliases: "-b", desc: "The base URL of the Pact Broker"
method_option :broker_username, desc: "Pact Broker basic auth username"
method_option :broker_password, aliases: "-p", desc: "Pact Broker basic auth password"
method_option :broker_token, aliases: "-k", desc: "Pact Broker bearer token"
method_option :contract_content_changed, type: :boolean, desc: "Trigger this webhook when the pact content changes"
method_option :provider_verification_published, type: :boolean, desc: "Trigger this webhook when a provider verification result is published"
method_option :verbose, aliases: "-v", type: :boolean, default: false, required: false, desc: "Verbose output. Default: false"
end
end
end
end
Expand Down
8 changes: 6 additions & 2 deletions lib/pact_broker/client/webhooks/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def initialize(params, pact_broker_base_url, pact_broker_client_options)
end

def call
if params.consumer && params.provider
if params.consumer && params.provider && !params.uuid
create_webhook_with_consumer_and_provider
else
create_webhook_with_optional_consumer_and_provider
Expand All @@ -41,7 +41,11 @@ def create_webhook_with_consumer_and_provider
end

def create_webhook_with_optional_consumer_and_provider
webhook_entity = index_link.get!._link("pb:webhooks").post(request_body_with_optional_consumer_and_provider)
if params.uuid
webhook_entity = index_link.get!._link("pb:webhook").expand(uuid: params.uuid).put(request_body_with_optional_consumer_and_provider)
else
webhook_entity = index_link.get!._link("pb:webhooks").post(request_body_with_optional_consumer_and_provider)
end

if webhook_entity.response.status == 405
raise PactBroker::Client::Error.new(WEBHOOKS_WITH_OPTIONAL_PACTICICPANTS_NOT_SUPPORTED)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require 'pact_broker/client/cli/broker'
require 'pact_broker/client/webhooks/create'

module PactBroker
module Client
module CLI
describe Broker do
describe "create_or_update_webhook" do

let(:broker) { Broker.new }

subject { broker.create_or_update_webhook "http://webhook" }

it "calls PactBroker::Client::Webhooks::Create with the webhook params" do
expect(broker).to receive(:run_webhook_commands).with("http://webhook")

subject
end
end
end
end
end
end
Loading

0 comments on commit 32f6c4c

Please sign in to comment.