Giter Site home page Giter Site logo

pact-foundation / pact_broker Goto Github PK

View Code? Open in Web Editor NEW
702.0 44.0 172.0 11.28 MB

Enables your consumer driven contracts workflow

Home Page: http://pactflow.io

License: MIT License

Ruby 85.45% HTML 0.68% JavaScript 11.91% CSS 0.45% Shell 0.44% Dockerfile 0.05% Haml 1.02%
pact-broker hal-browser contract-testing consumer consumer-driven-contracts verification provider hacktoberfest smartbear-supported

pact_broker's Introduction

Pact Broker

Gem Version Build status Join the chat at https://pact-foundation.slack.com/

The Pact Broker is an application for sharing of consumer driven contracts and verification results. It is optimised for use with "pacts" (contracts created by the Pact framework), but can be used for any type of contract that can be serialized to JSON.



You can try out a Pact Broker for free at pactflow.io. Built by a group of core Pact maintainers, PactFlow is a fork of the OSS Pact Broker with extra goodies like an improved UI, field level verification results and federated login.

Why do I need a Pact Broker?

Contract testing is an alternative approach to traditional integration testing that gives you tests that are quicker to execute, and that are more maintainable at scale. One down side of the approach is that the important information that would be available all in one place at the end of an integration test suite execution (that is, the version numbers of all the applications that were tested together, and whether the tests passed or failed) is now spread out across many different builds. The Pact Broker is a tool that brings all this information back together again, and allows you to deploy with safety.

It:

  • allows you to release customer value quickly and confidently by deploying your services independently and avoiding the bottleneck of integration tests
  • solves the problem of how to share contracts and verification results between consumer and provider projects
  • tells you which versions of your applications can be deployed safely together
  • automatically versions your contracts
  • allows you to ensure backwards compatibility between multiple consumer and provider versions (eg. in a mobile or multi-tenant environment)
  • provides API documentation of your applications that is guaranteed to be up-to date
  • shows you real examples of how your services interact
  • allows you to visualise the relationships between your services

Features:

  • A RESTful API for publishing and retrieving pacts.
  • An embedded API browser for navigating the API.
  • Autogenerated documentation for each pact.
  • Dynamically generated network diagrams so you can visualise your microservice network.
  • Displays provider verificaton results so you know if you can deploy safely.
  • Provides a "matrix" of compatible consumer and provider versions, so you know which versions can be safely deployed together.
  • Provides badges to display pact verification statuses in your READMEs.
  • Enables an application version to be tagged (ie. "prod", "feat/customer-preferences") to allow repository-like workflows.
  • Provides webhooks to trigger actions when pacts change eg. run provider build, notify a Slack channel.
  • View diffs between Pact versions so you can tell what expectations have changed.
  • Docker Pact Broker
  • A CLI for encorporating the Pact workflow into your continuous integration process.

How would I use the Pact Broker?

Step 1. Consumer CI build

  1. The consumer project runs its tests using the Pact library to provide a mock service.
  2. While the tests run, the mock service writes the requests and the expected responses to a JSON "pact" file - this is the consumer contract.
  3. The generated pact is then published to the Pact Broker. Most Pact libraries will make a task available for you to do this easily, however, at its simplest, it is a PUT to a resource that specifies the consumer name and application version, and the provider name. eg http://my-pact-broker/pacts/provider/Animal%20Service/consumer/Zoo%20App/version/1.0.0 (Note that you are specifying the consumer application version in the URL, not the pact version. The broker will take care of versioning the pact behind the scenes when its content changes. It is expected that the consumer application version will increment with every CI build.)
  4. When a pact is published, a webhook in the Pact Broker kicks off a build of the provider project if the pact content has changed since the previous version.

Step 2. Provider CI build

  1. The provider has a verification task that is configured with the URL to retrieve the latest pact between itself and the consumer. eg http://my-pact-broker/pacts/provider/Animal%20Service/consumer/Zoo%20App/latest.
  2. The provider build runs the pact verification task, which retrieves the pact from the Pact Broker, replays each request against the provider, and checks that the responses match the expected responses.
  3. If the pact verification fails, the build fails. The Pact Broker CI Nerf Gun magically determines who caused the verification to fail, and shoots them.
  4. The results of the verification are published back to the Pact Broker by the pact verification tool, so the consumer team will know if the code they have written will work in real life.

If you don't have a Pact Broker CI Nerf Gun, you'll probably want to read about using pact when the consumer and provider are being written by different teams.

Step 3. Back to the Consumer CI build

  1. The Consumer CI determines if the pact has been verified by running pact-broker can-i-deploy --pacticipant CONSUMER_NAME --version CONSUMER_VERSION ... (see documentation here)
  2. If the pact has been verified, the deployment can proceed.

Read more about how to use the Pact Broker in the overview on the wiki page.

Documentation

See the wiki for documentation on the Pact Broker. Please read the overview page first to get an understanding of the HTTP resources in the broker, and how they relate to each other.

Support

  • Check the wiki first.
  • See if there is an existing or closed issue and raise a new issue if not.
  • See if there is an existing question on stackoverflow tagged with pact-broker, and ask a new question if not.
  • Have a chat to us on the Pact slack.
  • Tweet us at @pact_up on the twitters.

Screenshots

Index


Autogenerated documentation

Paste the pact URL into a browser to view a HTML version of the pact.


Network diagram


HAL browser

Use the embedded HAL browser to navigate the API.


HAL documentation

Use the HAL browser to view documentation as you browse.


Usage

To have a play around on your local machine

Using Docker Compose

Download a copy of the example Docker Compose file from the Pact Broker Docker repository and run:

docker compose up

Then open a browser at http://localhost:9292.

Using Ruby

  • Install Ruby 2.7 and Bundler (check the automated tests to find the most recent version of Ruby and Bundler that are supported)
    • Windows users: get a Rails/Ruby installer from RailsInstaller and run it
    • unix users just use your package manager
  • Run git clone [email protected]:pact-foundation/pact_broker.git && cd pact_broker/example
  • Run bundle install
  • Run bundle exec rackup -p 9292 -o 0.0.0.0 (this will use a Sqlite database. If you want to try it out with a Postgres database, see the README in the example directory.)
  • Open http://localhost:9292 and you should see a list containing the pact between the Zoo App and the Animal Service.
  • Click on the arrow to see the generated HTML documentation.
  • Click on either service to see an autogenerated network diagram.
  • Click on the HAL Browser link to have a poke around the API.
  • Click on the book icon under "docs" to view documentation related to a given relation.

For reals

Hosted

In a hurry? Hate having to run your own infrastructure? Check out pactflow.io - it's fast, it's secure and it's free to trial!

Container solutions

You can use the Pact Broker Docker image or Terraform on AWS. See the wiki for instructions on using a reverse proxy with SSL.

Rolling your own

  • Are you sure you don't just want to use the Pact Broker Docker image? No Docker at your company yet? Ah well, keep reading.
  • Create a PostgreSQL database.
    • To ensure you're on a supported version of the database that you choose, check the .github/workflows/test.yml file to see which versions we're currently running our tests against.
    • MySQL was supported for the native Ruby application until around 2021, but the official pactfoundation/pact-broker Docker image does not support it. New features will not be optimised for MySQL, and some new features may not even be supported on it (eg. the database clean feature).
  • You'll find a sample database creation script in the example/config.ru.
  • Install ruby 2.7 and the latest version of bundler (if you've come this far, I'm assuming you know how to do both of these. Did I mention there was a Docker image?)
  • Copy the pact_broker directory from the Pact Broker Docker project. This will have the recommended settings for database connections, logging, basic auth etc. Note that the Docker image uses Phusion Passenger as the web application server in front of the Pact Broker Ruby application, which is the recommended set up if you are not using a containerized solution.
  • Modify the config.ru and Gemfile as desired (eg. choose database driver gem, set your database credentials. Use the "pg" gem for Postgres)
    • example Sequel configuration for postgres { adapter: "postgres", database: "pact_broker", username: 'pact_broker', password: 'pact_broker', :encoding => 'utf8' }
  • Please ensure you use encoding: 'utf8' in your Sequel options to avoid encoding issues.
  • For production usage, use a web application server like Phusion Passenger or Nginx to serve the Pact Broker application. You'll need to read up on the documentation for these yourself as it is beyond the scope of this documentation. See the wiki for instructions on using a reverse proxy with SSL.
  • Ensure the environment variable RACK_ENV is set to production.
  • Deploy to your location of choice.

Upgrading

Please read the UPGRADING.md documentation before upgrading your Pact Broker, for information on the supported upgrade paths.

Versioning

The Pact Broker follows the semantic versioning scheme.

pact_broker's People

Contributors

andresf avatar bangn avatar barthez avatar bethesque avatar bookofgreg avatar cdent avatar col avatar dependabot[bot] avatar dtsato avatar elgalu avatar factorypreset avatar inksprout avatar ismasan avatar joshco avatar mefellows avatar mikekelly avatar pahnin avatar pitschr avatar rashiagarwal avatar richard-reece avatar saup21 avatar sbrauer avatar sergei-matheson avatar snyk-bot avatar taiki45 avatar tancnle avatar timothyjones avatar vashistha avatar vwong avatar you54f avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pact_broker's Issues

Web hook support to receive notification that a pact changed

As a provider who's not in control of the consumer(s), we'd like to be notified when a pact has changed in the broker, so that we can run a build against it. If we were able to register a URL in the pact broker to say "Hit this URL whenever this pact changes", then we'd be able to achieve that. IIRC, GitHub, Bamboo, Jenkins all accept a single URL that you can just send a POST to to trigger a build. May warrant further investigation to be sure though.

Html Rendering

We used PACT in one of our smaller projects. We found the PACT was extremely useful for designing and testing integrations. So we decided use PACT in one of large and more complex projects and use PACT Broker for API documentation. The new service has about 10 endpoints and we have a single PACT file that includes all the interactions for each endpoint. We would like to keep one PACT file per service to keep the Network graph simple as we like to use PACT Broker to show intra-organisation service integrations.

The issue we are facing with PACT Broker is when PACT Broker renders the interactions, it sorts the interactions by interaction description. So it is difficult to read the interactions as we donโ€™t have control over the rendering. It would be great to have the ability to group and order the interactions when displayed on the PACT Broker.

Are there any plans to add these types of rendering features? We are happy to work on a pull request. We would just need some guidance on the best way to implement it.

Should similar pact upload generate 400 or 409

Currently, when uploading a pact with a similar name to an existing pact, a 400 error is returned. When using this programmatically, it is unclear as to the real reason for failure until one looks at the actual response body which explains the error.

Returning a 409 Conflict might give a better hint as to the real reason for failure. Not such much a bad request but more of a duplicate pact ...

Shouldn't consumer_name and provider_name be downcases?

I ran into an "issue" where the consumer name was downcased on the provider side and turns out it hasn't been found cause the consumer/provider_name are case sensitive.

What about:

  • downcasing consumer/provider_name when saving
  • downcasing names when querying
  • writing a db migration to downcase the names?

Merge pacts from parallel builds

Our project has a build that executes in parallel across multiple machines (leading to the pact being split across several files). Does the pact broker have the ability to merge a pushed pact with the same version as an existing same-name pact into that pact? If not, I'm willing to work that up and create a PR for it.

Make name similarity check configurable or optional

The similarity check during publishing pacts can be too restrictive at times. If we wish to publish pacts with similar names, we are forced to manually create "pacticipants" when similarity check fails.

It would be helpful to to have one or both of the following

  1. Provide an ability to configure similarity check
  2. Suppress similarity check all together

This would be helpful if pacts names are auto-generated using some type of naming convention.

See https://groups.google.com/forum/#!topic/pact-support/airBOo9qeLs

Example sqlite database does not fit to current source code

I'm trying to run the example application.
For this I followed the steps described under: https://github.com/bethesque/pact_broker#to-have-a-play-around-on-your-local-machine

With "bundle exec rackup" the application starts as expected,
but when I'm trying to access the application with the browser, I only get a json/hal response.

When I'm trying to access the url http://localhost:9292/pacts/latest, I'm getting an SQLException.

{"message":"SQLite3::SQLException: no such table: latest_pacts","backtrace":["/var/lib/gems/1.9.1/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:91:in `initialize'","/var/lib/gems/1.9.1/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:91:in `new'","/var/lib/gems/1.9.1/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:91:in `prepare'","/var/lib/gems/1.9.1/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:266:in `query'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/adapters/sqlite.rb:185:in `block (2 levels) in _execute'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/database/logging.rb:37:in `log_yield'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/adapters/sqlite.rb:185:in `block in _execute'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/database/connecting.rb:250:in `block in synchronize'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/connection_pool/threaded.rb:98:in `hold'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/database/connecting.rb:250:in `synchronize'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/adapters/sqlite.rb:178:in `_execute'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/adapters/sqlite.rb:128:in `execute'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/dataset/actions.rb:908:in `execute'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/adapters/sqlite.rb:362:in `fetch_rows'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/dataset/actions.rb:137:in `each'","/var/lib/gems/1.9.1/gems/sequel-4.18.0/lib/sequel/model/plugins.rb:28:in `each'","/home/hendrik/git/pact_broker/lib/pact_broker/pacts/repository.rb:57:in `collect'","/home/hendrik/git/pact_broker/lib/pact_broker/pacts/repository.rb:57:in `find_latest_pacts'","/home/hendrik/git/pact_broker/lib/pact_broker/services/pact_service.rb:18:in `find_latest_pacts'","/home/hendrik/git/pact_broker/lib/pact_broker/api/resources/latest_pacts.rb:22:in `pacts'","/home/hendrik/git/pact_broker/lib/pact_broker/api/resources/latest_pacts.rb:18:in `to_json'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/decision/flow.rb:465:in `o18'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/decision/fsm.rb:27:in `block (2 levels) in run'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/decision/fsm.rb:47:in `handle_exceptions'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/decision/fsm.rb:27:in `block in run'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/decision/fsm.rb:25:in `loop'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/decision/fsm.rb:25:in `run'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/dispatcher.rb:44:in `block in dispatch'","/var/lib/gems/1.9.1/gems/as-notifications-1.0.1/lib/as/notifications.rb:161:in `instrument'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/events.rb:75:in `instrument'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/dispatcher.rb:43:in `dispatch'","/var/lib/gems/1.9.1/gems/webmachine-1.2.0/lib/webmachine/adapters/rack.rb:65:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/urlmap.rb:66:in `block in call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/urlmap.rb:50:in `each'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/urlmap.rb:50:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/static.rb:124:in `call'","/home/hendrik/git/pact_broker/lib/rack/hal_browser/redirect.rb:19:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/static.rb:124:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/tempfile_reaper.rb:15:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/lint.rb:49:in `_call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/lint.rb:37:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/showexceptions.rb:24:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/commonlogger.rb:33:in `call'","/var/lib/gems/1.9.1/gems/sinatra-1.4.5/lib/sinatra/base.rb:217:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/chunked.rb:54:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/content_length.rb:15:in `call'","/var/lib/gems/1.9.1/gems/rack-1.6.0/lib/rack/handler/webrick.rb:89:in `service'","/var/lib/gems/1.9.1/gems/webrick-1.3.1/lib/webrick/httpserver.rb:138:in `service'","/var/lib/gems/1.9.1/gems/webrick-1.3.1/lib/webrick/httpserver.rb:94:in `run'","/var/lib/gems/1.9.1/gems/webrick-1.3.1/lib/webrick/server.rb:191:in `block in start_thread'"]}

I seems that the *.sqlite3 files from the repository are outdated.

Error when executing webhook with body

Executing a webhook with a body returns the error below.

{
"error": {
"message": "undefined method bytesize' for {\"text\"=>\"json\"}:Hash", "backtrace": [ "/usr/local/lib/ruby/2.1.0/net/http/generic_request.rb:179:insend_request_with_body'",
"/usr/local/lib/ruby/2.1.0/net/http/generic_request.rb:130:in exec'", "/usr/local/lib/ruby/2.1.0/net/http.rb:1412:inblock in transport_request'",
"/usr/local/lib/ruby/2.1.0/net/http.rb:1411:in catch'", "/usr/local/lib/ruby/2.1.0/net/http.rb:1411:intransport_request'",
"/usr/local/lib/ruby/2.1.0/net/http.rb:1384:in request'", "/usr/local/bundle/gems/newrelic_rpm-3.10.0.279/lib/new_relic/agent/instrumentation/net.rb:27:inblock (2 levels) in request_with_newrelic_trace'",
"/usr/local/bundle/gems/newrelic_rpm-3.10.0.279/lib/new_relic/agent.rb:453:in disable_all_tracing'", "/usr/local/bundle/gems/newrelic_rpm-3.10.0.279/lib/new_relic/agent/instrumentation/net.rb:26:inblock in request_with_newrelic_trace'",
"/usr/local/bundle/gems/newrelic_rpm-3.10.0.279/lib/new_relic/agent/cross_app_tracing.rb:48:in tl_trace_http_request'", "/usr/local/bundle/gems/newrelic_rpm-3.10.0.279/lib/new_relic/agent/instrumentation/net.rb:23:inrequest_with_newrelic_trace'",
"/usr/local/bundle/gems/pact_broker-1.9.2/lib/pact_broker/domain/webhook_request.rb:64:in block in execute'", "/usr/local/lib/ruby/2.1.0/net/http.rb:853:instart'",
"/usr/local/lib/ruby/2.1.0/net/http.rb:583:in start'", "/usr/local/bundle/gems/pact_broker-1.9.2/lib/pact_broker/domain/webhook_request.rb:62:inexecute'",
"/usr/local/bundle/gems/pact_broker-1.9.2/lib/pact_broker/domain/webhook.rb:37:in execute'", "/usr/local/bundle/gems/pact_broker-1.9.2/lib/pact_broker/services/webhook_service.rb:44:inexecute_webhook_now'",
"/usr/local/bundle/gems/pact_broker-1.9.2/lib/pact_broker/api/resources/webhook_execution.rb:15:in `process_post'",
...
...
...
...
}

can't build with bundler 1.13.0

When I try to build from a recent release or master using bundler version 1.13 using a fresh gemset I get a number of gem compatibility errors.

In contrast pact_broker builds fine when I downgrade to bundler 1.12.5 (which is the version currently in use in the Travis CI build jobs).

A workaround is to build under bundler 1.12.5 first, then rebuild under bundler 1.13. (this is probably not ideal though).

My system is:

  • Ubuntu 14.04
  • ruby 2.3.1
  • rvm 1.27.0
  • bundler 1.13.0
$ rvm use 2.3.1@pact_broker
Using /home/bo/.rvm/gems/ruby-2.3.1 with gemset pact_broker
$ rvm gemset empty pact_broker
Are you SURE you wish to remove the installed gems for /home/bo/.rvm/gems/ruby-2.3.1@pact_broker?
(anything other than 'yes' will cancel) > yes
installing gem /home/bo/.rvm/gem-cache/gem-empty-1.1.2.gem --local --no-ri --no-rdoc.
Removing bundle
Removing bundler
Successfully uninstalled bundler-1.13.0
Successfully uninstalled gem-empty-1.1.2
Removed successfully.

$ gem list

*** LOCAL GEMS ***

bigdecimal (1.2.8)
bundler-unload (1.0.2)
did_you_mean (1.0.0)
executable-hooks (1.3.2)
gem-wrappers (1.2.7)
io-console (0.4.5)
json (1.8.3)
minitest (5.8.3)
net-telnet (0.1.1)
power_assert (0.2.6)
psych (2.0.17)
rake (10.4.2)
rdoc (4.2.1)
rubygems-bundler (1.4.4)
rvm (1.11.3.9)
test-unit (3.1.5)

$ gem install bundler --version 1.13.0
Fetching: bundler-1.13.0.gem (100%)
Successfully installed bundler-1.13.0
Parsing documentation for bundler-1.13.0
Installing ri documentation for bundler-1.13.0
Done installing documentation for bundler after 3 seconds
1 gem installed

$ bundle
Fetching gem metadata from https://rubygems.org/...........
Fetching version metadata from https://rubygems.org/.
Resolving dependencies.....................................
Bundler could not find compatible versions for gem "activesupport":
  In Gemfile:
    pact_broker was resolved to 1.11.0, which depends on
      trailblazer (~> 0.1.0) was resolved to 0.1.0, which depends on
        actionpack (>= 3.0.0) was resolved to 3.0.0, which depends on
          activesupport (= 3.0.0)

    pact_broker was resolved to 1.11.0, which depends on
      trailblazer (~> 0.1.0) was resolved to 0.1.0, which depends on
        actionpack (>= 3.0.0) was resolved to 3.0.0, which depends on
          actionview (= 5.0.0.1) depends on
            activesupport (= 5.0.0.1)

    pact_broker was resolved to 1.11.0, which depends on
      padrino-core (~> 0.12.4) was resolved to 0.12.4, which depends on
        padrino-support (= 0.12.4) was resolved to 0.12.4, which depends on
          activesupport (>= 3.1)

    pact_broker was resolved to 1.11.0, which depends on
      padrino-core (~> 0.12.4) was resolved to 0.12.4, which depends on
        padrino-support (= 0.12.4) was resolved to 0.12.4, which depends on
          activesupport (>= 3.1)
Bundler could not find compatible versions for gem "rack":
  In Gemfile:
    pact_broker was resolved to 1.11.0, which depends on
      trailblazer (~> 0.1.0) was resolved to 0.1.0, which depends on
        actionpack (>= 3.0.0) was resolved to 5.0.0.1, which depends on
          rack (~> 2.0)

    pact_broker was resolved to 1.11.0, which depends on
      padrino-core (~> 0.12.4) was resolved to 0.12.4, which depends on
        http_router (~> 0.11.0) was resolved to 0.11.2, which depends on
          rack (>= 1.0.0)

    pact_broker was resolved to 1.11.0, which depends on
      padrino-core (~> 0.12.4) was resolved to 0.12.4, which depends on
        rack-protection (>= 1.5.0) was resolved to 1.5.3, which depends on
          rack

    pact_broker was resolved to 1.11.0, which depends on
      padrino-core (~> 0.12.4) was resolved to 0.12.4, which depends on
        rack-protection (>= 1.5.0) was resolved to 1.5.3, which depends on
          rack

    pact_broker was resolved to 1.11.0, which depends on
      padrino-core (~> 0.12.4) was resolved to 0.12.4, which depends on
        rack-protection (>= 1.5.0) was resolved to 1.5.3, which depends on
          rack

    pact_broker was resolved to 1.11.0, which depends on
      trailblazer (~> 0.1.0) was resolved to 0.1.0, which depends on
        actionpack (>= 3.0.0) was resolved to 5.0.0.1, which depends on
          rack-test (~> 0.6.3) was resolved to 0.6.3, which depends on
            rack (>= 1.0)

    pact_broker was resolved to 1.11.0, which depends on
      padrino-core (~> 0.12.4) was resolved to 0.12.4, which depends on
        sinatra (~> 1.4.2) was resolved to 1.4.2, which depends on
          rack (>= 1.5.2, ~> 1.5)

Config.ru for Postgres.

Hi,

Can someone point us on how to add the postgresql database details in config.ru.

We are planning to use pact broker for our microservices testing.

Thank you.

Thanks,
Guru.

Error when running Sequel migrations for MySQL DB

Hi,

I'm trying to install pact_broker connecting to a MySQL DB. I'm connecting via the 'mysql2' adapter. DB is empty initially, no tables exist. When I first started pact_broker, I got the error below:

/usr/lib64/ruby/gems/2.1.0/gems/sequel-4.25.0/lib/sequel/adapters/mysql2.rb:78:in `query': Mysql2::Error: Cannot change column 'pact_version_content_sha': used in a foreign key constraint 'fk_pact_version_content' (Sequel::DatabaseError)
    from /usr/lib64/ruby/gems/2.1.0/gems/sequel-4.25.0/lib/sequel/adapters/mysql2.rb:78:in `block in _execute'
    from /usr/lib64/ruby/gems/2.1.0/gems/sequel-4.25.0/lib/sequel/database/logging.rb:37:in `log_yield'
    from /usr/lib64/ruby/gems/2.1.0/gems/sequel-4.25.0/lib/sequel/adapters/mysql2.rb:78:in `_execute'
    ...

Any idea how to get past this?

Thank you,
R.

versions and latest-version links from a pacticipant return 404 with an HTML response

Using the latest version of the broker (1.9.3), if I follow the links from root, the versions and latest-version links for a participant don't work.

To re-produce from the HAL browser, select:
pb:pacticipants
select a pacticipant (in my case pacticipants index 0)

I get this response:

{
  "name": "Activity Service",
  "createdAt": "2016-07-06T02:01:43+00:00",
  "_links": {
    "self": {
      "href": "http://localhost:8080/pacticipants/Activity%20Service"
    },
    "latest-version": {
      "href": "http://localhost:8080/pacticipants/Activity%20Service/versions/latest"
    },
    "versions": {
      "href": "http://localhost:8080/pacticipants/Activity%20Service/versions"
    }
  }
}

selecting either "versions" or "latest-version" link:

404 Not Found

Server: Webmachine-Ruby/1.2.0 Rack/1.3
Connection: keep-alive
Content-Length: 213
Content-Type: text/html

P.S. I'm assuming the play on words (pacticipant) is intentional. :-D

authentication flexibility

Would it be reasonable to enable further flexibility for auth configuration? I would really like to be able enable read access in a far more public way, but still require elevated privileges to publish any changes.

Webhook can't execute HTTPS endpoints

If I attempt to execute a webhook that is configured for a URL with a https scheme I get a response with the error 400 The plain HTTP request was sent to HTTPS port.

To fix this, the use_ssl option should be set when creating a HTTP request for a URL with a https scheme. I'll submit a PR with the fix.

Templating support in pact broker webhooks

I need to create a webhook in the pact broker that will queue a provider test build in TeamCity. I would like to send information about the published pact that triggered the webhook in the webhook request body. Specifically the tag name that the published pact was tagged with (if it was tagged), but the pact version would also suffice.

This information will be used by the TeamCity job to fetch the correct version of the pact file from the pact broker when running the provider tests.

Add support for providers to auto-discover consumers

I would like to start a conversation about scaling with pact.

Today when a provider wants to verify a consumers pact file it needs to explicitly run the verify for every consumer. As the number of consumers for a provider grows this creates friction, with each consumer needing to involve the provider in order to setup the pact tests end to end.

If we shifted toward a more self service model here is how I imagine it would work. The provider would specify their name and the Pact Broker base url when running the verify. The verify would ask the Pact Broker for every registered consumer, download all the pact files and verify each one. If a new consumer comes along the act of uploading the pact file to the Pact Broker is all that is required to get the provider to start verifying it. The provider would also want the ability to specify a tag when asking for all the registered consumers. This allows the verify to be run against production versions of the consumer for example.

I'm thinking the work required for this feature would be to add the API to the Pact Broker, and then update each of the verify implementations to support running the tests in this way. The provider we are working with right now is using pact-jvm and we are happy to contribute to this library to help get this built.

What are your thoughts on this?

Why does Pact Broker care about the format of the version number?

When trying to upload a Pact file for a new Pacticipant I encountered this error:

{"errors":["Consumer version number '2015-04-13_06-30_39d5d8c919' is not recognised as a standard semantic version. eg. 1.3.0 or 2.0.4.rc1"]}

Digging through the code I found this validation the version number goes through:

def invalid_consumer_version_number?
  begin
    Versionomy.parse(consumer_version_number)
    false
  rescue Versionomy::Errors::ParseError => e
    true
  end
end

Why does the Pact broker need to be opinionated about the version number we use? While I agree that semantic versioning is the preferred way to version code, we have legacy codebases that do not follow this convention and it is not a trivial amount of work to change this. What are your thoughts on relaxing this validation?

need to update the gemspec

hey guys,
Not sure if i'm write, but looks like the repo mentioned in your gemspec hasn't been updated since 2013.

Since this is used by rubygems, i'd suggest that you update the link to show people that is repo is actually maintained :)

cheers

Documentation and examples for consumer/provider build configuration

I have read the blog post about the consumer/provider testing matrix, and am looking to setup our consumer and provider builds to test the cases identified. But reading all the documentation I can't find any examples or details on what the options are to do this.

I'll walk through the examples and ask questions as I go.

The consumer makes a change (updates the head commit)

  • The consumer build would need to run the pact tests and generate a pact file, which is uploaded to the pact broker as the latest version.
  • The provider would then need to pull this new version of the pact file and verify it works against the head version and the production version of the provider.
    • How do you trigger this build? I know Pact Broker has webhooks which are an option, but dealing with the permissions required to allow pact broker to do this is painful (for us anyway). Are there other options you have tried?
    • Running the build against the head version seems straight forward, just checkout the head version and run the verify. What is less straight forward is how do you run the verify against the production version of the provider?
    • How do you feed the success or failure of these provider test runs back to the consumer? Ideally the consumers deploy tasks would refuse to deploy until the provider builds are green (or at least the production provider anyway).

The consumer deploys to production

  • The consumer would tag the pact for this particular version of the app with "production".
  • Do you do anything else here? It seems no further tests are required as they should already have been green to get to this point.

The provider makes a change (updates the head commit)

  • The provider would need to verify this change against both the production and head versions of the consumer pact. This seems straight forward, just run the verify two times.

The provider deploys to production

  • Since the provider should have verified it is already compatible with all the consumers there should be nothing required here.

There should probably be a page in the documentation dedicated to this topic.

Does pact broker client support base_authentication of pact broker server

Hi,

We've set up the base authentication in our pact broker which runs on the nginx server.

Initially we thought we can pass the pact url like http://username:password@pact_broker_url, however, after reading the code, we found the pact:verify uses openuri and publish task to httpparty, both of them needs to pass additional options for the base_authentication. Is there any pact configuration that we can use to pass the options through?

It will be great that the pact client and support can provide this feature, as the pact broker server can be shared by our multiple api users with basic authenticated access. Thanks.

Create a pact broker docker image

Spinning up a pact broker service for use in a production environment is a reasonable amount of investment. By creating a docker image all the details of setting up and configuring the service could be abstracted away. It also makes bumping to the latest version of pact broker more seamless.

This image should be updated each time the pact broker service is updated.

I have created a docker image using this docker file already, although I have little experience hosting ruby apps in production so there is likely room for improvement here:

FROM ruby:1.9.3-p551

WORKDIR /service
ADD example /service
RUN bundle install

EXPOSE 8080
CMD bundle exec rackup --port 8080 --host 0.0.0.0

To configure the database I updated the config.ru file to use environment variables as the way of passing the database configuration to the server (I happened to use postgres but this could be another variable):

DATABASE_CREDENTIALS = {
    :adapter => 'postgres',
    :database => ENV['PG_PACT_BROKER_SCHEMA'],
    :encoding => 'utf8',
    :host => ENV['PG_PACT_BROKER_HOST'],
    :password => ENV['PG_PACT_BROKER_PASSWORD'],
    :user => ENV['PG_PACT_BROKER_ROLE']
}

An unanswered question I have is how you would support monitoring or other kinds of configuration customisation. For example we wanted to monitor this service using newrelic so we added require 'newrelic_rpm' to the top of the config file. Perhaps you could look in a well known location for additional config? Or perhaps letting the user of the image drop the entire config file as is will be easier.

Endpoint to discover a providers consumers

Is there a way to discover which consumers have pacts registered for a given provider. I'd rather dynamically run the ones available rather than hard code the ones I know about.

No logging provided when Pact fails to render

I have a published pact that fails to render, just displaying Note: this contract could not be parsed to a Pact, showing raw content instead.

There is nothing in the logs to indicate why this pact can not be parsed.

Unable to run pact_broker example on windows

  1. Try to install pack broker according to instruction in https://github.com/bethesque/pact_broker#to-have-a-play-around-on-your-local-machine on Windows.

Expected result:
Pack broker is up and running

Actual result:

  • bundle gem installation is missing
  • rack gem installation is missing
  • finally I receive the following error:
    C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/resolver.rb:366:in block in verify_gemfile_dependencies_are_found!': Could not find gem 'pact_broker (~> 1.9.3) x64-mingw32' in any of the gem sources listed in your Gemfile or available on this machine. (Bundler::GemNotFound) from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/resolver.rb:341:ineach'
    from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/resolver.rb:341:in verify_gemfile_dependencies_are_found!' from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/resolver.rb:199:instart'
    from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/resolver.rb:181:in resolve' from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/definition.rb:252:inresolve'
    from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/definition.rb:176:in specs' from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/definition.rb:235:inspecs_for'
    from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/definition.rb:224:in requested_specs' from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/runtime.rb:118:inblock in definition_method'
    from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/runtime.rb:19:in setup' from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler.rb:99:insetup'
    from C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/bundler-1.13.0/lib/bundler/setup.rb:20:in <top (required)>' from C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:inrequire'
    from C:/Ruby23-x64/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'

Allow pacticipants with similar name

We get the following message in the logs when we attempt to add a pact to the pact-broker

"The following potential duplicate pacticipants were found for service-gateway: service "

Looking over the code, I can see this is quite deliberate. Is there a reason why pacticipants can not have similar names?

Show last Provider pact:verify date and result

Having a copy of the provider build run on the Consumer CI that just runs the unit tests and pact verification is an effective way to know when the last verify was run and how it resulted.

However moving the last pact:verify date and result (just failed or success) to the pact_broker service would be quite convenient for Consumers to quickly get to know if the Provider is actually verifying her pacts and what was the last status given all these can go cross-teams and even cross companies.

image

I guess this feature would require to implement a new endpoint in the pact_broker and also update the clients to automatically POST this (date, status) tuple to the broker, if configured to do so.

pact broker should validate incoming pacts

Due to my own failures as a miserable user, I have posted invalid json strings to the pact broker.

When attempting to read those pacts I get nasty looking ruby stack traces.

It would be nicer if the server refused to store invalid data earlier on in the process

Log error details to the console

As an administrator of the Pact Broker I want to be able to see the error details in my logs so I can work out what is going wrong when the Pact Broker starts to return 500 responses.

Often the full error is returned in the response, but depending on the client it may not be logged. Even if the client did happen to log the error, as the administrator of the Pact Broker I may not know who to talk to or where to find those logs.

Today when a 500 occurs on the server the log line looks something like this:

123.456.789.101 - - [27/Sep/2016:23:33:12 +0000] "GET /pacts/provider/providername/consumer/consumername/version/1.0 HTTP/1.1" 500 6073 0.0154

This line is useful, but in addition it would be good if the full exception details and stack trace were also output to the console.

Sequel::DatabaseDisconnectError at /ui/relationships

Hi, I'm getting this error while using the broker with postresql, it gets solved after a page refresh:

PG::ConnectionBad: PQconsumeInput() server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request.
file: postgres.rb location: async_exec line: 180

BACKTRACE

/home/app/pact_broker/vendor/bundle/ruby/2.2.0/gems/sequel-4.24.0/lib/sequel/adapters/postgres.rb in async_exec
        @db.log_yield(sql, args){args ? async_exec(sql, args) : async_exec(sql)}
/home/app/pact_broker/vendor/bundle/ruby/2.2.0/gems/sequel-4.24.0/lib/sequel/adapters/postgres.rb in block in execute_query
        @db.log_yield(sql, args){args ? async_exec(sql, args) : async_exec(sql)}
/home/app/pact_broker/vendor/bundle/ruby/2.2.0/gems/sequel-4.24.0/lib/sequel/database/logging.rb in log_yield
        yield
/home/app/pact_broker/vendor/bundle/ruby/2.2.0/gems/sequel-4.24.0/lib/sequel/adapters/postgres.rb in execute_query
        @db.log_yield(sql, args){args ? async_exec(sql, args) : async_exec(sql)}
/home/app/pact_broker/vendor/bundle/ruby/2.2.0/gems/sequel-4.24.0/lib/sequel/adapters/postgres.rb in block in execute
        q = check_disconnect_errors{execute_query(sql, args)}
....

pact_broker_psql

requests for images giving 404s

I am probably misconfiguring something, but a brand new installation of pact_broker from source doesn't show images (such as images/doc-test.svg).

To replicate:

git clone ...
bundle install
bundle exec rackup -p 8080

then open http://127.0.0.1:8080/ui/relationships in a brower. Note that the doc-test relationships image does not show.

Workaround for me was to modify config.ru to add "/images" to the urls array on line 8.

A spec's "given" with a > sign in the description breaks the autogenerated documentation

The 'greater than' sign in the spec below, causes the documentation HTML to be generated with wrongly-escaped HTML, and thus parts of the documentation page are missing.

                pact
                    .given('there is 1 unread message and the timestamp is > 1426461081')
                    .uponReceiving('a request for a candidate messages with one notification')
                    .withRequest(request)
                    .willRespondWith(200, {}, response);

wrongquoteescaping

Notice how the first interaction's anchor tag's name attribute has its closing quote escaped when it shouldn't. Also the anchor tag's closing angle bracket is escaped when it shouldn't. I assume the angle bracket/greater-than sign in the 'given' is causing this.

Padrino is trying to log to a location within the app directory

In prod, Padrino is trying to open a log to a location within the app directory, e.g.
Permission denied - /my_app_here/vendor/bundle/ruby/1.9.1/gems/pact_broker-1.3.1/lib/pact_broker/ui/controllers/log

This is because of the default log config:
:production => { :log_level => :warn, :stream => :to_file }

(:to_file puts the logs under Padrino.root).

We can override this by configuring PADRINO_LOGGER = { :production => { :log_level => :warn, :stream => :null }} in config.ru in our app, but it'd be nice not to need to do this and have the gem take care of something like this for us.

Can't find a license

Hello can you add a license file? I searched for license in gihub and just go the licenses from the various javascript.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.