Giter VIP home page Giter VIP logo

notary's Introduction


notary

A contracts broker that provides a declarative way of sharing, validating & discovering contracts between multiple projects.


Beside contracts validation, sharing & discovery, notary also allows you to generate all sort of extra artifacts out of those contracts like Client libraries, Stubbed endpoints, Dependency Graphs & much more.

Support for multiple popular integration patterns like REST APIs will be shipped out of the box, plus the ability to easily extend the project with "Integrations plugins" to support even more patterns.

What is a Contract?

A contract is either a Producer Promise or a Consumer Expectation. In notary, it's a meta-data describing how to use a specific shared integration point, e.g.: a Swagger file describing exposed REST API endpoint including API versioning, paths, supported methods, response entities, etc..

How does the provider/consumer validation work?

To validate your contracts you need to issue a request to the [validation endpoint]. Ideally, this will be done automatically in your CI pipeline.

The validation process includes:

  1. Syntactic validation
  2. Check if all of the project's promises satisfy its consumers
  3. Check if all of the project's expectations are honored by its upstream providers

What integration patterns does the project support so far?

  1. REST APIs: Define contracts for RESTful API endpoints using the Swagger spec
  2. Frontend LocalStorage: Define contracts for shared objects in the end-customer's browser LocalStorage using a specified JSON schema

notary's People

Contributors

gitter-badger avatar mmounirf avatar omarahm avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar

Forkers

gitter-badger

notary's Issues

Refactor tests to expect exceptions in a better way

Current:

try {
  await schemaFacade.validateContractSchema(projectRevision, contract);
} catch (err) {
  assert.include(err.message, "Could'nt find any non-empty");
}

which doesn't fail the test if no exception was thrown, which is incorrect.

Simplify the diff report when contract fails

From @rm-hull on Jun 29, 2017, 9:53 AM GMT+2

For example, the report as is, it is quite difficult to see what is making the contract fail:

provider-client-services:contracts/ @ bfb5911a54122b89c61a877858a2b8227200962b is not valid: 

Consumer [ bpc-libs:bpc-transaction-store/contracts/ @ master ] expectations of type (rest) is broken: 
============================================================================ 
Expectation broken: 

 { '/session/store/{sessionId}': 
   { get: 
      { produces: [ 'application/json;charset=UTF-8' ],
        parameters: [ { name: 'sessionId', in: 'path', required: true, type: 'string' } ],
        responses: 
         { '200': { description: 'OK' },
           '404': { description: 'Not Found' } } },
     put: 
      { consumes: [ 'application/json;charset=UTF-8' ],
        parameters: 
         [ { name: 'sessionId', in: 'path', required: true, type: 'string' },
           { name: 'data',
             in: 'body',
             required: true,
             schema: { type: 'string' } } ],
        responses: { '200': { description: 'OK' } } } } } 

is not a subset of: 

{ '/health': 
   { get: 
      { tags: [ 'health-controller' ],
        summary: 'Health check',
        operationId: 'healthUsingGET',
        consumes: [ 'application/json' ],
        produces: [ '*/*' ],
        responses: 
         { '200': { description: 'OK', schema: { type: 'string' } },
           '401': { description: 'Unauthorized' },
           '403': { description: 'Forbidden' },
           '404': { description: 'Not Found' } } } },
  '/session/store/{sessionId}': 
   { get: 
      { tags: [ 'transaction-storage-controller' ],
        summary: 'Fetch a transaction',
        operationId: 'getUsingGET',
        consumes: [ 'application/json' ],
        produces: [ 'application/json;charset=LATIN-1' ],
        parameters: 
         [ { name: 'sessionId',
             in: 'path',
             description: 'transactionId',
             required: true,
             type: 'string' } ],
        responses: 
         { '200': { description: 'OK', schema: { type: 'string' } },
           '401': { description: 'Unauthorized' },
           '403': { description: 'Forbidden' },
           '404': { description: 'Not Found' } } },
     put: 
      { tags: [ 'transaction-storage-controller' ],
        summary: 'Store a transaction',
        operationId: 'putUsingPUT',
        consumes: [ 'application/json;charset=UTF-8' ],
        produces: [ '*/*' ],
        parameters: 
         [ { name: 'sessionId',
             in: 'path',
             description: 'transactionId',
             required: true,
             type: 'string' },
           { in: 'body',
             name: 'data',
             description: 'data',
             required: true,
             schema: { type: 'string' } } ],
        responses: 
         { '200': { description: 'OK' },
           '201': { description: 'Created' },
           '401': { description: 'Unauthorized' },
           '403': { description: 'Forbidden' },
           '404': { description: 'Not Found' } } } } }

It might be better to show a diff for each identified mismatch, something along the lines of:

Expected: '/session/store/{sessionId}' --> get --> produces --> 'application/json;charset=UTF-8' 
Promised: '/session/store/{sessionId}' --> get --> produces --> 'application/json;charset=LATIN-1'

Client library generation

From @rdsubhas on May 19, 2017, 11:23 PM GMT+2

What we need?

  • Client library for the given provider contract
  • Must: Logging and Monitoring (log every call that's being made, measure response times, use standard metrics naming conventions)
  • Must: Client identification (User agent), Request IDs (generate a request ID header if not present) and other stuff
  • Must: API/Endpoint Versioning, Artifact versioning. both are different, each API call/entity/operation can have versioning - i.e. v1 POST booking, v2 POST booking. But at the same time, the entire client library can get a major version bump when we create dependency conflicts - i.e. we upgrade dependency versions like okhttp/swagger/hystrix/etc (e.g. protobuf-commons upgrades major versions when protobuf version changes). API by itself has no version - only endpoints have multiple versions and independent breakages per use-case. But the library itself has a technical version that can be incompatible and be bumped up as a whole
  • Must: Java (duh)
  • Optional: NodeJS (untyped, not much use having a client library)
  • Optional: HTTP/2 support, persistent connections, performance tuning
  • Optional: Exponential backoff/retry for specific cases (i.e. don't try retrying "creating a booking", define some client response codes that will be retried, e.g. server is not available or not found, idempotent GET requests, non-4xx responses, etc), circuit breaker
  • Optional: Service discovery (let the provider define their ingress URL using some format, either use kubernetes service names, or just provide some default service discovery)

Artifact lifecycle

  1. notary simply generates and publishes client libraries upon every commit to projects, directly to our nexus
  2. notary act like a nexus repo, and on-demand generate client libraries and returns them
  3. a /publish endpoint in notary, and if anyone calls that, the client libraries will be generated and published

Approach/Design

..... in progress

Track orphaned consumers

From @omarahm on May 21, 2017, 2:18 PM GMT+2

What is the problem?
The current algorithm for fetching consumers is as follows:

  1. Get all promises for the project under test
  2. Loop through all of the registered projects and check if any has one or more expectations from the project under test
  3. Match promises to expectations

If the project under test decides to drop one of the promises, because of the steps mentioned above, the current validation will be green although we have "orphaned consumers".

What is required?
Tweak the current logic to cover the above mentioned scenario.

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.