pact_broker 1.18.0.beta.1 → 1.18.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -2
  3. data/README.md +12 -12
  4. data/example/{heroku → basic_auth}/Gemfile +0 -0
  5. data/example/{heroku → basic_auth}/Procfile +0 -0
  6. data/example/{heroku → basic_auth}/README.md +1 -1
  7. data/example/basic_auth/config.ru +19 -0
  8. data/example/config.ru +0 -2
  9. data/lib/pact_broker/api/decorators/versions_decorator.rb +1 -1
  10. data/lib/pact_broker/api/resources/versions.rb +1 -1
  11. data/lib/pact_broker/app.rb +7 -6
  12. data/lib/pact_broker/configuration.rb +4 -42
  13. data/lib/pact_broker/domain/order_versions.rb +15 -5
  14. data/lib/pact_broker/domain/webhook.rb +0 -1
  15. data/lib/pact_broker/domain/webhook_request.rb +6 -4
  16. data/lib/pact_broker/logging.rb +4 -0
  17. data/lib/pact_broker/pacticipants/repository.rb +2 -1
  18. data/lib/pact_broker/pacticipants/service.rb +2 -2
  19. data/lib/pact_broker/version.rb +1 -1
  20. data/lib/pact_broker/webhooks/job.rb +46 -0
  21. data/lib/pact_broker/webhooks/service.rb +9 -8
  22. data/lib/pact_broker/webhooks/webhook.rb +1 -1
  23. data/pact_broker.gemspec +2 -1
  24. data/pact_broker_client-pact_broker.json +4 -4
  25. data/script/foo-bar.json +22 -0
  26. data/script/publish-new.sh +7 -0
  27. data/script/publish.sh +2 -2
  28. data/script/recreate-pg-db.sh +7 -0
  29. data/spec/fixtures/a_consumer-a_provider-2.json +1 -1
  30. data/spec/fixtures/a_consumer-a_provider-3.json +1 -1
  31. data/spec/fixtures/a_consumer-a_provider-conflict.json +1 -1
  32. data/spec/fixtures/a_consumer-a_provider-merged.json +2 -2
  33. data/spec/fixtures/a_consumer-a_provider.json +1 -1
  34. data/spec/fixtures/consumer-provider.json +1 -1
  35. data/spec/fixtures/renderer_pact.json +1 -1
  36. data/spec/lib/pact_broker/configuration_spec.rb +2 -22
  37. data/spec/lib/pact_broker/domain/order_versions_spec.rb +30 -10
  38. data/spec/lib/pact_broker/domain/webhook_request_spec.rb +3 -1
  39. data/spec/lib/pact_broker/pacticipants/repository_spec.rb +16 -0
  40. data/spec/lib/pact_broker/webhooks/job_spec.rb +67 -0
  41. data/spec/lib/pact_broker/webhooks/service_spec.rb +40 -3
  42. data/spec/support/provider_state_builder.rb +36 -8
  43. metadata +29 -12
  44. data/example/heroku/config.ru +0 -12
  45. data/lib/pact_broker/configuration/configure_basic_auth.rb +0 -83
  46. data/spec/lib/pact_broker/configuration/configure_basic_auth_spec.rb +0 -267
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c780083d99fd7a3c73e53f16b703c3bfe5b86a78
4
- data.tar.gz: aa8ef0eb97c2e18461179607d395c7b493e9f50e
3
+ metadata.gz: 7ef22c7934452713d713906de14fade4ecc2a2c8
4
+ data.tar.gz: e20f94e91cd30b71fde2c80393861342e989a33f
5
5
  SHA512:
6
- metadata.gz: 63db04af90da66ce5833f9f2de88f734529f94c7ebb759ffe4a8eb89f5a7cf5b439c221bf5464bf4d499f5e326038668dd58e5ebbff6f9db31ab7a9b92669861
7
- data.tar.gz: 261ccb52f5819dc9d9eee9c1088bff11c0d6fb3269492d68e1de25f5687e66adc7a814a43ad7c69c8e3b883ec10ca5e0bf865a0e46bf5f515011384057e402fd
6
+ metadata.gz: b5be0a05dd839aef2b0da83d95f7ea58c0c9934ec6e59162a726fa21c3c9f7f795090f05071506df821ff2a930557a1649111f951ec7321a008faed5f59ea2de
7
+ data.tar.gz: 1fb67c57f5491571a02d096e0243bd20c43f64faf1a5245457743c71663a002ee3c91dd59355ea863164025ef22ca6840c38d226ec324b40d69c237da5bbddae
data/CHANGELOG.md CHANGED
@@ -2,8 +2,10 @@ Do this to generate your change history
2
2
 
3
3
  $ git log --pretty=format:' * %h - %s (%an, %ad)' vX.Y.Z..HEAD
4
4
 
5
- #### 1.18.0.beta.1 (2017-05-05)
6
- * 99e825b - Add in-built configuration for basic auth. (Beth Skurrie, Fri May 5 10:22:53 2017 +1000)
5
+ #### 1.18.0 (2017-05-09)
6
+ * 397060b - Display application versions in reverse order in the Versions resource. (Beth Skurrie, Tue May 9 13:59:54 2017 +1000)
7
+ * 251c878 - Allow application versions to be ordered by creation date where no consistent orderable object can be extracted from the consumer application version. (Beth Skurrie, Tue May 9 13:22:36 2017 +1000)
8
+ * 68bb6d9 - Execute webhooks using sucker punch. (Beth Skurrie, Mon May 8 10:32:45 2017 +1000)
7
9
 
8
10
  #### 1.17.2 (2017-05-04)
9
11
  * b8f45e1 - fix issue with pact document link not displaying #94 (Matt Fellows, Wed May 3 11:23:09 2017 +1000)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Pact Broker
2
2
 
3
- [![Build Status](https://travis-ci.org/bethesque/pact_broker.svg?branch=master)](https://travis-ci.org/bethesque/pact_broker) [![Join the chat at https://gitter.im/bethesque/pact_broker](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bethesque/pact_broker?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
3
+ [![Build Status](https://travis-ci.org/pact-foundation/pact_broker.svg?branch=master)](https://travis-ci.org/pact-foundation/pact_broker) [![Join the chat at https://gitter.im/pact-foundation/pact_broker](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pact-foundation/pact_broker?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
4
 
5
5
  The Pact Broker provides a repository for consumer driven contracts created using the pact gem.
6
6
 
@@ -23,7 +23,7 @@ Features:
23
23
  * Tracks changes between Pact versions so you can tell when a consumer has changed its expectations.
24
24
  * [Docker Pact Broker][docker]
25
25
 
26
- Travis CI Status: [![Build Status](https://travis-ci.org/bethesque/pact_broker.svg?branch=master)](https://travis-ci.org/bethesque/pact_broker)
26
+ Travis CI Status: [![Build Status](https://travis-ci.org/pact-foundation/pact_broker.svg?branch=master)](https://travis-ci.org/pact-foundation/pact_broker)
27
27
 
28
28
  ### How would I use the Pact Broker?
29
29
 
@@ -41,47 +41,47 @@ If you don't have a [Pact Broker CI Nerf Gun][nerf], you'll probably want to rea
41
41
 
42
42
  ## Documentation
43
43
 
44
- See the [Pact Broker Client](https://github.com/bethesque/pact_broker-client) for documentation on how to publish a pact to the Pact Broker, and configure the URLs in the provider project.
44
+ See the [Pact Broker Client](https://github.com/pact-foundation/pact_broker-client) for documentation on how to publish a pact to the Pact Broker, and configure the URLs in the provider project.
45
45
 
46
- See the [wiki](https://github.com/bethesque/pact_broker/wiki) for documentation related to the Pact Broker itself.
46
+ See the [wiki](https://github.com/pact-foundation/pact_broker/wiki) for documentation related to the Pact Broker itself.
47
47
 
48
48
  ### Screenshots
49
49
 
50
50
  #### Index
51
51
 
52
52
  * * *
53
- <img src="https://raw.githubusercontent.com/wiki/bethesque/pact_broker/images/index.png"/>
53
+ <img src="https://raw.githubusercontent.com/wiki/pact-foundation/pact_broker/images/index.png"/>
54
54
 
55
55
  #### Autogenerated documentation
56
56
 
57
57
  Paste the pact URL into a browser to view a HTML version of the pact.
58
58
  * * *
59
- <img src="https://raw.githubusercontent.com/wiki/bethesque/pact_broker/images/autogenerated_documentation.png"/>
59
+ <img src="https://raw.githubusercontent.com/wiki/pact-foundation/pact_broker/images/autogenerated_documentation.png"/>
60
60
 
61
61
 
62
62
  #### Network diagram
63
63
 
64
64
  * * *
65
- <img src="https://raw.githubusercontent.com/wiki/bethesque/pact_broker/images/network_diagram.png"/>
65
+ <img src="https://raw.githubusercontent.com/wiki/pact-foundation/pact_broker/images/network_diagram.png"/>
66
66
 
67
67
  #### HAL browser
68
68
 
69
69
  Use the embedded HAL browser to navigate the API.
70
70
  * * *
71
- <img src="https://raw.githubusercontent.com/wiki/bethesque/pact_broker/images/hal_browser.png"/>
71
+ <img src="https://raw.githubusercontent.com/wiki/pact-foundation/pact_broker/images/hal_browser.png"/>
72
72
 
73
73
  #### HAL documentation
74
74
 
75
75
  Use the HAL browser to view documentation as you browse.
76
76
  * * *
77
- <img src="https://raw.githubusercontent.com/wiki/bethesque/pact_broker/images/hal_documentation.png"/>
77
+ <img src="https://raw.githubusercontent.com/wiki/pact-foundation/pact_broker/images/hal_documentation.png"/>
78
78
 
79
79
  ## Usage
80
80
 
81
81
  ### To have a play around on your local machine
82
82
 
83
83
  * Install ruby 2.2.0 or later and bundler >= 1.12.0
84
- * Run `git clone git@github.com:bethesque/pact_broker.git && cd pact_broker/example`
84
+ * Run `git clone git@github.com:pact-foundation/pact_broker.git && cd pact_broker/example`
85
85
  * Run `bundle`
86
86
  * Run `bundle exec rackup -p 8080`
87
87
  * Open [http://localhost:8080](http://localhost:8080) and you should see a list containing the pact between the Zoo App and the Animal Service.
@@ -100,7 +100,7 @@ the [Hosted Pact Broker](https://pact.dius.com.au/?utm_source=github&utm_campaig
100
100
  You can use the [Pact Broker Docker container][docker] or [Terraform on AWS][terraform] or to roll your own...
101
101
 
102
102
  * Create a database using a product that is supported by the Sequel gem (listed on this page http://sequel.jeremyevans.net/rdoc/files/README_rdoc.html). The migrations have been tested on MySQL and PostgreSQL - your mileage will vary on other databases.
103
- * __Note:__ It is recommended to use __PostgreSQL__ as it will support JSON search features that are planned in a future release, however MySQL the other [semi supported](https://github.com/bethesque/pact_broker/issues/33) database.
103
+ * __Note:__ It is recommended to use __PostgreSQL__ as it will support JSON search features that are planned in a future release, however MySQL the other [semi supported](https://github.com/pact-foundation/pact_broker/issues/33) database.
104
104
  * Install ruby 2.2.0 or later and bundler >= 1.12.0
105
105
  * Copy the [example](/example) directory to the location you want to install the application.
106
106
  * Modify the config.ru and Gemfile as desired (eg. choose database driver gem, set your database credentials. Use the "pg" gem if using Postgres.)
@@ -110,7 +110,7 @@ You can use the [Pact Broker Docker container][docker] or [Terraform on AWS][ter
110
110
 
111
111
  [decouple]: http://techblog.realestate.com.au/enter-the-pact-matrix-or-how-to-decouple-the-release-cycles-of-your-microservices/
112
112
  [pact]: https://github.com/realestate-com-au/pact
113
- [nerf]: https://github.com/bethesque/pact_broker/wiki/pact-broker-ci-nerf-gun
113
+ [nerf]: https://github.com/pact-foundation/pact_broker/wiki/pact-broker-ci-nerf-gun
114
114
  [different-teams]: https://github.com/realestate-com-au/pact/wiki/Using-pact-where-the-consumer-team-is-different-from-the-provider-team
115
115
  [docker]: https://hub.docker.com/r/dius/pact-broker
116
116
  [terraform]: https://github.com/nadnerb/terraform-pact-broker
File without changes
File without changes
@@ -27,7 +27,7 @@ $ git push heroku master
27
27
  Your Pact Broker instance is now available!
28
28
 
29
29
  ## Publish consumer pacts - consumer side
30
- You will need to set these environment variables with your basic auth credentials
30
+ You will need to set these environment variables with your basic auth credentials
31
31
  ```
32
32
  export PACT_BROKER_USERNAME=admin
33
33
  export PACT_BROKER_PASSWORD=changeme
@@ -0,0 +1,19 @@
1
+ require 'fileutils'
2
+ require 'logger'
3
+ require 'sequel'
4
+ require 'pact_broker'
5
+ require 'pg'
6
+
7
+ use Rack::Auth::Basic, "Restricted Area" do |username, password|
8
+ username == ENV['PACT_BROKER_USERNAME'] and password == ENV['PACT_BROKER_PASSWORD']
9
+ end
10
+
11
+ app = PactBroker::App.new do | config |
12
+ # change these from their default values if desired
13
+ # config.log_dir = "./log"
14
+ # config.auto_migrate_db = true
15
+ # config.use_hal_browser = true
16
+ config.database_connection = Sequel.connect(ENV['DATABASE_URL'], adapter: "postgres", encoding: 'utf8')
17
+ end
18
+
19
+ run app
data/example/config.ru CHANGED
@@ -27,8 +27,6 @@ app = PactBroker::App.new do | config |
27
27
  # config.use_hal_browser = true
28
28
  config.database_connection = Sequel.connect(DATABASE_CREDENTIALS.merge(:logger => config.logger))
29
29
  config.database_connection.timezone = :utc
30
- # See configuration section of wiki for more basic auth configuration options
31
- # config.protect_with_basic_auth :app_read, {username: 'username', password: 'password'}
32
30
  end
33
31
 
34
32
  run app
@@ -15,7 +15,7 @@ module PactBroker
15
15
  link :self do | context |
16
16
  {
17
17
  href: context[:resource_url],
18
- title: "All versions of the pacticipant #{context[:pacticipant_name]}"
18
+ title: "All application versions of #{context[:pacticipant_name]}"
19
19
  }
20
20
  end
21
21
 
@@ -25,7 +25,7 @@ module PactBroker
25
25
  end
26
26
 
27
27
  def versions
28
- pacticipant_service.find_all_pacticipant_versions pacticipant_name
28
+ pacticipant_service.find_all_pacticipant_versions_in_reverse_order pacticipant_name
29
29
  end
30
30
 
31
31
  end
@@ -3,7 +3,7 @@ require 'pact_broker/db'
3
3
  require 'pact_broker/project_root'
4
4
  require 'rack/hal_browser'
5
5
  require 'rack/pact_broker/convert_file_extension_to_accept_header'
6
- require 'pact_broker/configuration/configure_basic_auth'
6
+ require 'sucker_punch'
7
7
 
8
8
  module PactBroker
9
9
 
@@ -33,6 +33,7 @@ module PactBroker
33
33
  PactBroker::DB.connection = configuration.database_connection
34
34
  PactBroker::DB.connection.timezone = :utc
35
35
  PactBroker::DB.validate_connection_config if configuration.validate_database_connection_config
36
+ SuckerPunch.logger = configuration.logger
36
37
 
37
38
  if configuration.auto_migrate_db
38
39
  logger.info "Migrating database"
@@ -71,12 +72,12 @@ module PactBroker
71
72
  apps << PactBroker::UI::App.new
72
73
  apps << PactBroker::API
73
74
 
74
- cascade = Rack::Cascade.new(apps)
75
- app_with_basic_auth = PactBroker::Configuration::ConfigureBasicAuth.call(cascade, configuration)
76
-
77
75
  @app.map "/" do
78
- run app_with_basic_auth
76
+ run Rack::Cascade.new(apps)
79
77
  end
78
+
80
79
  end
80
+
81
81
  end
82
- end
82
+
83
+ end
@@ -4,33 +4,13 @@ module PactBroker
4
4
  @@configuration ||= Configuration.default_configuration
5
5
  end
6
6
 
7
- def self.reset_configuration
8
- @@configuration = Configuration.default_configuration
9
- end
10
-
11
7
  class Configuration
12
8
 
13
- REQUEST_METHOD = 'REQUEST_METHOD'.freeze
14
- GET = 'GET'.freeze
15
- PATH_INFO = 'PATH_INFO'.freeze
16
- DIAGNOSTIC = '/diagnostic/'.freeze
17
-
18
9
  attr_accessor :log_dir, :database_connection, :auto_migrate_db, :use_hal_browser, :html_pact_renderer
19
10
  attr_accessor :validate_database_connection_config, :enable_diagnostic_endpoints, :version_parser
20
- attr_accessor :use_case_sensitive_resource_names, :basic_auth_predicates
11
+ attr_accessor :use_case_sensitive_resource_names, :order_versions_by_date
21
12
  attr_writer :logger
22
13
 
23
- def initialize
24
- @basic_auth_config = {}
25
- @basic_auth_predicates = [
26
- [:diagnostic, ->(env) { env[PATH_INFO].start_with? DIAGNOSTIC }],
27
- [:app, ->(env) { !env[PATH_INFO].start_with? DIAGNOSTIC } ],
28
- [:app_read, ->(env) { env[REQUEST_METHOD] == GET }],
29
- [:app_write, ->(env) { env[REQUEST_METHOD] != GET }],
30
- [:all, ->(env) { true }]
31
- ]
32
- end
33
-
34
14
  def logger
35
15
  @logger ||= create_logger log_path
36
16
  end
@@ -46,10 +26,12 @@ module PactBroker
46
26
  config.use_case_sensitive_resource_names = true
47
27
  config.html_pact_renderer = default_html_pact_render
48
28
  config.version_parser = PactBroker::Versions::ParseSemanticVersion
29
+ # Not recommended to set this to true unless there is no way to
30
+ # consistently extract an orderable object from the consumer application version number.
31
+ config.order_versions_by_date = false
49
32
  config
50
33
  end
51
34
 
52
- # public
53
35
  def self.default_html_pact_render
54
36
  lambda { |pact|
55
37
  require 'pact_broker/api/renderers/html_pact_renderer'
@@ -57,28 +39,8 @@ module PactBroker
57
39
  }
58
40
  end
59
41
 
60
- # public
61
- def protect_with_basic_auth scopes, credentials
62
- [*scopes].each do | scope |
63
- basic_auth_config[scope] ||= []
64
- basic_auth_config[scope] << credentials
65
- end
66
- end
67
-
68
- # private
69
- def protect_with_basic_auth? scope
70
- !!basic_auth_credentials_list_for(scope)
71
- end
72
-
73
- # private
74
- def basic_auth_credentials_list_for scope
75
- basic_auth_config[scope]
76
- end
77
-
78
42
  private
79
43
 
80
- attr_reader :basic_auth_config
81
-
82
44
  def create_logger path
83
45
  FileUtils::mkdir_p File.dirname(path)
84
46
  logger = Logger.new(path)
@@ -4,9 +4,17 @@ module PactBroker
4
4
  module Domain
5
5
  class OrderVersions
6
6
 
7
+ include PactBroker::Logging
8
+ # TODO select for update
7
9
  def self.call pacticipant_id
8
- orderable_versions = PactBroker::Domain::Version.where(:pacticipant_id => pacticipant_id).all.collect{| version | OrderableVersion.new(version) }
9
- orderable_versions.sort.each_with_index{ | version, i | version.update_model(i) }
10
+
11
+ orderable_versions = PactBroker::Domain::Version.for_update.where(:pacticipant_id => pacticipant_id).order(:created_at, :id).collect{| version | OrderableVersion.new(version) }
12
+ ordered_versions = if PactBroker.configuration.order_versions_by_date
13
+ orderable_versions # already ordered in SQL
14
+ else
15
+ orderable_versions.sort
16
+ end
17
+ ordered_versions.each_with_index{ | version, i | version.update_model(i) }
10
18
  end
11
19
 
12
20
  class OrderableVersion
@@ -23,9 +31,11 @@ module PactBroker
23
31
  end
24
32
 
25
33
  def update_model new_order
26
- # Sequel will only run the update if the column value has changed, so in 99% of
27
- # cases, only one update will occur.
28
- version_model.update(:order => new_order)
34
+ if version_model.order != new_order
35
+ # Avoid modifying the updated_at flag by doing a manual update
36
+ # In 99% of cases, this will only set the order of the most recent version
37
+ PactBroker::Domain::Version.where(id: version_model.id).update(order: new_order)
38
+ end
29
39
  end
30
40
  end
31
41
  end
@@ -33,7 +33,6 @@ module PactBroker
33
33
  request && request.description
34
34
  end
35
35
 
36
- #TODO retries
37
36
  def execute
38
37
  logger.info "Executing #{self}"
39
38
  request.execute
@@ -22,7 +22,7 @@ module PactBroker
22
22
  include PactBroker::Logging
23
23
  include PactBroker::Messages
24
24
 
25
- attr_accessor :method, :url, :headers, :body, :username, :password
25
+ attr_accessor :method, :url, :headers, :body, :username, :password, :uuid
26
26
 
27
27
  # Reform gets confused by the :method method, as :method is a standard
28
28
  # Ruby method.
@@ -35,6 +35,7 @@ module PactBroker
35
35
  @password = attributes[:password]
36
36
  @headers = attributes[:headers] || {}
37
37
  @body = attributes[:body]
38
+ @uuid = attributes[:uuid]
38
39
  end
39
40
 
40
41
  def description
@@ -64,17 +65,18 @@ module PactBroker
64
65
  end
65
66
  end
66
67
 
67
- logger.info "Making webhook request #{to_s}"
68
+ logger.info "Making webhook #{uuid} request #{to_s}"
68
69
  response = Net::HTTP.start(uri.hostname, uri.port,
69
70
  :use_ssl => uri.scheme == 'https') do |http|
70
71
  http.request req
71
72
  end
72
73
 
73
- logger.info "Received response status=#{response.code} body=#{response.body}"
74
+ logger.info "Received response for webhook #{uuid} status=#{response.code}"
75
+ logger.debug "body=#{response.body}"
74
76
  WebhookExecutionResult.new(response)
75
77
 
76
78
  rescue StandardError => e
77
- logger.error "Error executing webhook #{e.class.name} - #{e.message}"
79
+ logger.error "Error executing webhook #{uuid} #{e.class.name} - #{e.message}"
78
80
  logger.error e.backtrace.join("\n")
79
81
  WebhookExecutionResult.new(nil, e)
80
82
  end
@@ -17,6 +17,10 @@ module PactBroker
17
17
  @@logger = logger
18
18
  end
19
19
 
20
+ def log_error e
21
+ logger.error "#{e.class} #{e.message} #{e.backtrace.join("\n")}"
22
+ end
23
+
20
24
  def logger
21
25
  @@logger ||= begin
22
26
  FileUtils.mkdir_p(LOG_DIR)
@@ -20,11 +20,12 @@ module PactBroker
20
20
  PactBroker::Domain::Pacticipant.order(:name).all
21
21
  end
22
22
 
23
- def find_all_pacticipant_versions name
23
+ def find_all_pacticipant_versions_in_reverse_order name
24
24
  PactBroker::Domain::Version
25
25
  .select(:versions__id, :versions__number, :versions__pacticipant_id, :versions__order, :versions__created_at, :versions__updated_at)
26
26
  .join(:pacticipants, {id: :pacticipant_id})
27
27
  .where(name_like(:name, name))
28
+ .reverse_order(:order)
28
29
  end
29
30
 
30
31
  def find_by_name_or_create name
@@ -41,8 +41,8 @@ module PactBroker
41
41
  pacticipant_repository.find_by_name(name)
42
42
  end
43
43
 
44
- def self.find_all_pacticipant_versions name
45
- pacticipant_repository.find_all_pacticipant_versions(name)
44
+ def self.find_all_pacticipant_versions_in_reverse_order name
45
+ pacticipant_repository.find_all_pacticipant_versions_in_reverse_order(name)
46
46
  end
47
47
 
48
48
  def self.find_pacticipant_repository_url_by_pacticipant_name name
@@ -1,3 +1,3 @@
1
1
  module PactBroker
2
- VERSION = '1.18.0.beta.1'
2
+ VERSION = '1.18.0'
3
3
  end
@@ -0,0 +1,46 @@
1
+ require 'sucker_punch'
2
+ require 'pact_broker/webhooks/service'
3
+ require 'pact_broker/logging'
4
+
5
+ module PactBroker
6
+ module Webhooks
7
+ class Job
8
+
9
+ BACKOFF_TIMES = [10, 60, 120, 300, 600, 1200] #10 sec, 1 min, 2 min, 5 min, 10 min, 20 min => 38 minutes
10
+
11
+ include SuckerPunch::Job
12
+ include PactBroker::Logging
13
+
14
+ def perform data
15
+ @webhook = data[:webhook]
16
+ @error_count = data[:error_count] || 0
17
+ begin
18
+ webhook_execution_result = PactBroker::Webhooks::Service.execute_webhook_now webhook
19
+ reschedule_job unless webhook_execution_result.success?
20
+ rescue StandardError => e
21
+ handle_error e
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :webhook, :error_count
28
+
29
+ def handle_error e
30
+ log_error e
31
+ reschedule_job
32
+ end
33
+
34
+ def reschedule_job
35
+ case error_count
36
+ when 0...BACKOFF_TIMES.size
37
+ logger.debug "Re-enqeuing job for webhook #{webhook.uuid} to run in #{BACKOFF_TIMES[error_count]} seconds"
38
+ Job.perform_in(BACKOFF_TIMES[error_count], {webhook: webhook, error_count: error_count+1})
39
+ else
40
+ logger.error "Failed to execute webhook #{webhook.uuid} after #{BACKOFF_TIMES.size} times."
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end