pact-plugin-driver 0.5.2

Pact support library that provides an interface for interacting with Pact plugins
Documentation
// Proto file for Pact plugin interface V1

syntax = "proto3";

import "google/protobuf/struct.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/empty.proto";

package io.pact.plugin;
option go_package = "io.pact.plugin";

// Request to verify the plugin has loaded OK
message InitPluginRequest {
  // Implementation calling the plugin
  string implementation = 1;
  // Version of the implementation
  string version = 2;
}

// Entry to be added to the core catalogue. Each entry describes one of the features the plugin provides.
// Entries will be stored in the catalogue under the key "plugin/$name/$type/$key".
message CatalogueEntry {
  enum EntryType {
    // Matcher for contents of messages, requests or response bodies
    CONTENT_MATCHER = 0;
    // Generator for contents of messages, requests or response bodies
    CONTENT_GENERATOR = 1;
    // Transport for a network protocol
    TRANSPORT = 2;
    // Matching rule for content field/values
    MATCHER = 3;
    // Type of interaction
    INTERACTION = 4;
  }
  // Entry type
  EntryType type = 1;
  // Entry key
  string key = 2;
  // Associated data required for the entry. For CONTENT_MATCHER and CONTENT_GENERATOR types, a "content-types"
  // value (separated by semi-colons) is required for all the content types the plugin supports.
  map<string, string> values = 3;
}

// Response to init plugin, providing the catalogue entries the plugin provides
message InitPluginResponse {
  // List of entries the plugin supports
  repeated CatalogueEntry catalogue = 1;
}

// Catalogue of Core Pact + Plugin features
message Catalogue {
  // List of entries from the core catalogue
  repeated CatalogueEntry catalogue = 1;
}

// Message representing a request, response or message body
message Body {
  // The content type of the body in MIME format (i.e. application/json)
  string contentType = 1;
  // Bytes of the actual content
  google.protobuf.BytesValue content = 2;
  // Enum of content type override. This is a hint on how the content type should be treated.
  enum ContentTypeHint {
    // Determine the form of the content using the default rules of the Pact implementation
    DEFAULT = 0;
    // Contents must always be treated as a text form
    TEXT = 1;
    // Contents must always be treated as a binary form
    BINARY = 2;
  }
  // Content type override to apply (if required). If omitted, the default rules of the Pact implementation
  // will be used
  ContentTypeHint contentTypeHint = 3;
}

// Request to preform a comparison on an actual body given the expected one
message CompareContentsRequest {
  // Expected body from the Pact interaction
  Body expected = 1;
  // Actual received body
  Body actual = 2;
  // If unexpected keys or attributes should be allowed. Setting this to false results in additional keys or fields
  // will cause a mismatch
  bool allow_unexpected_keys = 3;
  // Map of expressions to matching rules. The expressions follow the documented Pact matching rule expressions
  map<string, MatchingRules> rules = 4;
  // Additional data added to the Pact/Interaction by the plugin
  PluginConfiguration pluginConfiguration = 5;
}

// Indicates that there was a mismatch with the content type
message ContentTypeMismatch {
  // Expected content type (MIME format)
  string expected = 1;
  // Actual content type received (MIME format)
  string actual = 2;
}

// A mismatch for an particular item of content
message ContentMismatch {
  // Expected data bytes
  google.protobuf.BytesValue expected = 1;
  // Actual data bytes
  google.protobuf.BytesValue actual = 2;
  // Description of the mismatch
  string mismatch = 3;
  // Path to the item that was matched. This is the value as per the documented Pact matching rule expressions.
  string path = 4;
  // Optional diff of the contents
  string diff = 5;
  // Part of the interaction that the mismatch is for: body, headers, metadata, etc.
  string mismatchType = 6;
}

// List of content mismatches
message ContentMismatches {
  repeated ContentMismatch mismatches = 1;
}

// Response to the CompareContentsRequest with the results of the comparison
message CompareContentsResponse {
  // Error message if an error occurred. If this field is set, the remaining fields will be ignored and the
  // verification marked as failed
  string error = 1;
  // There was a mismatch with the types of content. If this is set, the results may not be set.
  ContentTypeMismatch typeMismatch = 2;
  // Results of the match, keyed by matching rule expression
  map<string, ContentMismatches> results = 3;
}

// Request to configure/setup an interaction so that it can be verified later
message ConfigureInteractionRequest {
  // Content type of the interaction (MIME format)
  string contentType = 1;
  // This is data specified by the user in the consumer test
  google.protobuf.Struct contentsConfig = 2;
}

// Represents a matching rule
message MatchingRule {
  // Type of the matching rule
  string type = 1;
  // Associated data for the matching rule
  google.protobuf.Struct values = 2;
}

// List of matching rules
message MatchingRules {
  repeated MatchingRule rule = 1;
}

// Example generator
message Generator {
  // Type of generator
  string type = 1;
  // Associated data for the generator
  google.protobuf.Struct values = 2;
}

// Plugin configuration added to the pact file by the ConfigureInteraction step
message PluginConfiguration {
  // Data to be persisted against the interaction
  google.protobuf.Struct interactionConfiguration = 1;
  // Data to be persisted in the Pact file metadata (Global data)
  google.protobuf.Struct pactConfiguration = 2;
}

// Response to the configure/setup an interaction request
message InteractionResponse {
  // Contents for the interaction
  Body contents = 1;
  // All matching rules to apply
  map<string, MatchingRules> rules = 2;
  // Generators to apply
  map<string, Generator> generators = 3;
  // For message interactions, any metadata to be applied
  google.protobuf.Struct messageMetadata = 4;
  // Plugin specific data to be persisted in the pact file
  PluginConfiguration pluginConfiguration = 5;
  // Markdown/HTML formatted text representation of the interaction
  string interactionMarkup = 6;
  // Type of markup used
  enum MarkupType {
    // CommonMark format
    COMMON_MARK = 0;
    // HTML format
    HTML = 1;
  }
  MarkupType interactionMarkupType = 7;
  // Description of what part this interaction belongs to (in the case of there being more than one, for instance,
  // request/response messages)
  string partName = 8;
  // All matching rules to apply to any message metadata
  map<string, MatchingRules> metadata_rules = 9;
  // Generators to apply to any message metadata
  map<string, Generator> metadata_generators = 10;
}

// Response to the configure/setup an interaction request
message ConfigureInteractionResponse {
  // If an error occurred. In this case, the other fields will be ignored/not set
  string error = 1;
  // The actual response if no error occurred.
  repeated InteractionResponse interaction = 2;
  // Plugin specific data to be persisted in the pact file
  PluginConfiguration pluginConfiguration = 3;
}

// Request to generate the contents using any defined generators
message GenerateContentRequest {
  // Original contents
  Body contents = 1;
  // Generators to apply
  map<string, Generator> generators = 2;
  // Additional data added to the Pact/Interaction by the plugin
  PluginConfiguration pluginConfiguration = 3;
  // Context data provided by the test framework
  google.protobuf.Struct testContext = 4;

  // The mode of the generation, if running from a consumer test or during provider verification
  enum TestMode {
    Unknown = 0;
    // Running on the consumer side
    Consumer = 1;
    // Running on the provider side
    Provider = 2;
  }
  TestMode testMode = 5;

  // Which part the content is for
  enum ContentFor {
    Request = 0;
    Response = 1;
  }
  ContentFor contentFor = 6;
}

// Generated body/message response
message GenerateContentResponse {
  Body contents = 1;
}

// Request to start a mock server
message StartMockServerRequest {
  // Interface to bind to. Will default to the loopback adapter
  string hostInterface = 1;
  // Port to bind to. Default (or a value of 0) get the OS to open a random port
  uint32 port = 2;
  // If TLS should be used (if supported by the mock server)
  bool tls = 3;
  // Pact as JSON to use for the mock server behaviour
  string pact = 4;
  // Context data provided by the test framework
  google.protobuf.Struct testContext = 5;
}

// Response to the start mock server request
message StartMockServerResponse {
  oneof response {
    // If an error occurred
    string error = 1;

    // Mock server details
    MockServerDetails details = 2;
  }
}

// Details on a running mock server
message MockServerDetails {
  // Mock server unique ID
  string key = 1;
  // Port the mock server is running on
  uint32 port = 2;
  // IP address the mock server is bound to. Probably an IP6 address, but may be IP4
  string address = 3;
}

// Request to shut down a running mock server
// TODO: replace this with MockServerRequest in the next major version
message ShutdownMockServerRequest {
  // The server ID to shutdown
  string serverKey = 1;
}

// Request for a running mock server by ID
message MockServerRequest {
  // The server ID to shutdown
  string serverKey = 1;
}

// Result of a request that the mock server received
message MockServerResult {
  // service + method that was requested
  string path = 1;
  // If an error occurred trying to handle the request
  string error = 2;
  // Any mismatches that occurred
  repeated ContentMismatch mismatches = 3;
}

// Response to the shut down mock server request
// TODO: replace this with MockServerResults in the next major version
message ShutdownMockServerResponse {
  // If the mock status is all ok
  bool ok = 1;
  // The results of the test run, will contain an entry for each request received by the mock server
  repeated MockServerResult results = 2;
}

// Matching results of the mock server.
message MockServerResults {
  // If the mock status is all ok
  bool ok = 1;
  // The results of the test run, will contain an entry for each request received by the mock server
  repeated MockServerResult results = 2;
}

// Request to prepare an interaction for verification
message VerificationPreparationRequest {
  // Pact as JSON to use for the verification
  string pact = 1;
  // Interaction key for the interaction from the Pact that is being verified
  string interactionKey = 2;
  // Any data supplied by the user to verify the interaction
  google.protobuf.Struct config = 3;
}

// Request metadata value. Will either be a JSON-like value, or binary data
message MetadataValue {
  oneof value {
    google.protobuf.Value nonBinaryValue = 1;
    bytes binaryValue = 2;
  }
}

// Interaction request data to be sent or received for verification
message InteractionData {
  // Request/Response body as bytes
  Body body = 1;
  // Metadata associated with the request/response
  map<string, MetadataValue> metadata = 2;
}

// Response for the prepare an interaction for verification request
message VerificationPreparationResponse {
  oneof response {
    // If an error occurred
    string error = 1;

    // Interaction data required to construct any request
    InteractionData interactionData = 2;
  }
}

// Request data to verify an interaction
message VerifyInteractionRequest {
  // Interaction data required to construct the request
  InteractionData interactionData = 1;
  // Any data supplied by the user to verify the interaction
  google.protobuf.Struct config = 2;
  // Pact as JSON to use for the verification
  string pact = 3;
  // Interaction key for the interaction from the Pact that is being verified
  string interactionKey = 4;
}

message VerificationResultItem {
  oneof result {
    string error = 1;
    ContentMismatch mismatch = 2;
  }
}

// Result of running the verification
message VerificationResult {
  // Was the verification successful?
  bool success = 1;
  // Interaction data retrieved from the provider (optional)
  InteractionData responseData = 2;
  // Any mismatches that occurred
  repeated VerificationResultItem mismatches = 3;
  // Output for the verification to display to the user
  repeated string output = 4;
}

// Result of running the verification
message VerifyInteractionResponse {
  oneof response {
    // If an error occurred trying to run the verification
    string error = 1;

    VerificationResult result = 2;
  }
}

service PactPlugin {
  // Check that the plugin loaded OK. Returns the catalogue entries describing what the plugin provides
  rpc InitPlugin(InitPluginRequest) returns (InitPluginResponse);
  // Updated catalogue. This will be sent when the core catalogue has been updated (probably by a plugin loading).
  rpc UpdateCatalogue(Catalogue) returns (google.protobuf.Empty);
  // Request to perform a comparison of some contents (matching request)
  rpc CompareContents(CompareContentsRequest) returns (CompareContentsResponse);
  // Request to configure/setup the interaction for later verification. Data returned will be persisted in the pact file.
  rpc ConfigureInteraction(ConfigureInteractionRequest) returns (ConfigureInteractionResponse);
  // Request to generate the content using any defined generators
  rpc GenerateContent(GenerateContentRequest) returns (GenerateContentResponse);

  // Start a mock server
  rpc StartMockServer(StartMockServerRequest) returns (StartMockServerResponse);
  // Shutdown a running mock server
  // TODO: Replace the message types with MockServerRequest and MockServerResults in the next major version
  rpc ShutdownMockServer(ShutdownMockServerRequest) returns (ShutdownMockServerResponse);
  // Get the matching results from a running mock server
  rpc GetMockServerResults(MockServerRequest) returns (MockServerResults);

  // Prepare an interaction for verification. This should return any data required to construct any request
  // so that it can be amended before the verification is run
  rpc PrepareInteractionForVerification(VerificationPreparationRequest) returns (VerificationPreparationResponse);
  // Execute the verification for the interaction.
  rpc VerifyInteraction(VerifyInteractionRequest) returns (VerifyInteractionResponse);
}