Matching requests to send responses

When Traffic Parrot receives a request via any protocol or technology like HTTP, JMS, gRPC and others, it will try to simulate the system it is replacing by sending back a response to the client that sent the request.

To decide which response to send, it will go through all the request to response mappings it has available to find the response to be returned.

What is a request to response mapping?

A request to response mapping defines which response to return given a request. For example, in HTTP, you could say:

For any request to URL '/hello' that is a GET request return a response with body 'Hello World!'

The way you do that in Traffic Parrot is by using the user interface to record mappings, import them or add them manually.

Here is an example HTTP request to response mapping viewed in Traffic Parrot web user interface:
Sample HTTP request to response mapping in Traffic Parrot
All of the mappings Traffic Parrot has access to are stored on the filesystem in JSON files. Here is the same mapping you just saw above in the web user interface but now in JSON formad stored in trafficparrot-enterprise-x.y.z/mappings folder on the disk:
{
  "id" : "a6263f39-5826-48a5-a409-4d78037c303e",
  "request" : {
    "url" : "/MODApis/Api/v2/Quote/json?AAPL",
    "method" : "GET"
  },
  "response" : {
    "status" : 200,
    "body" : "{\r\n  \"Status\": \"SUCCESS\",\r\n  \"High\": 116.91,\r\n  \"MSDate\": 42664,\r\n  \"Change\": -0.46,\r\n  \"LastPrice\": 116.6,\r\n  \"Timestamp\": \"Fri Oct 21 00:00:00 UTC-04:00 2016\",\r\n  \"ChangePercentYTD\": 105.26,\r\n  \"Name\": \"Apple Inc\",\r\n  \"Open\": 116.81,\r\n  \"Volume\": 23192665,\r\n  \"Low\": 116.28,\r\n  \"ChangeYTD\": 105.26,\r\n  \"ChangePercent\": -0.3929608748,\r\n  \"MarketCap\": 628292453800\r\n}",
    "headers" : {
      "Content-Type" : "text/javascript; charset=UTF-8"
    }
  },
  "uuid" : "a6263f39-5826-48a5-a409-4d78037c303e"
}

Workflow: matching a request to find a response

After the mappings have been created, a typical workflow when Traffic Parrot is simulating a system (replaying the responses) will be:
  1. Traffic Parrot receives a request
  2. Traffic Parrot goes through the list of all mappings (for example for http it lists all files in trafficparrot-enterprise-x.y.z/mappings folder on the disk) and tries to use the request matchers in a given mapping to match the request it just received
  3. If the request received matches the request in the mapping, it returns the response defined in that same mapping
  4. If the request received does not match the request in the mapping, it tries to match the next mapping in the list of mappings
  5. If there are no mappings left to match in the list of mappings, it returns the default response indicating a mapping was not found. For example for HTTP it will return a status code 900 and response body "Traffic Parrot Virtual Service: No responses matched the given request"

Available request matchers

Traffic Parrot support matching attributes of requests using the following matchers.

Protocol/technology Matchers available
HTTP(S) list of HTTP(S) matchers
JMS list of JMS matchers
Native IBM MQ list of MQ matchers
gRPC list of gRPC matchers
Thrift list of Thrift matchers
Files list of files matchers

Request matcher examples

Here is a collection of matcher examples that cover typical request matching use cases.

Matches JSONPath
Use case JSON to match JSONPath
Has field that exists, even if it contains a null value
{
  "field" : null
}
$[?(@.field)]
Does not have a particular field at all
{
  "other" : "any"
}
$[?(!(@.field))]
Has field matching regular expression
{
  "name" : "John"
}
$[?(@.name =~ /^J[a-z]+$/)]
Has field not matching regular expression
{
  "name" : "Other"
}
$[?(!(@.name =~ /^J[a-z]+$/))]
Has field with value equal to
{
  "name" : "John"
}
$[?(@.name == 'John')]
Has multiple fields with value equal to
{
  "name" : "John",
  "lastName" : "Smith"
}
$[?(@.name == 'John' && @.lastName == 'Smith')]
Has field with value equal to either
{
  "name" : "Bob"
}
{
  "name" : "John"
}
$[?(@.name == 'John' || @.name == 'Bob')]
Has array containing field with value equal to
{
  "root" : {
    "items" : [
      {
        "id": "1111"
      }
    ]
  }
}
$.root[?('1' in @.items[*].id)]
Has array containing fields with values equal to
{
  "root" : {
    "items" : [
      {
        "id": "1"
      },
      {
        "id": "2"
      }
    ]
  }
}
$.root[?('1' in @.items[*].id && '2' in @.items[*].id)]
Has fields at multiple depths
{
  "id": 1,
  "items": [
    {
      "id": 2,
    }
  ]
}
$[?(@.id == 1 && 2 in @.items[*].id)]

Mapping folder (directory) structure

Traffic Parrot stores request to response mappings on the filesystem.

Protocol/technology Mappings location
HTTP(S) mappings and __files (where it stores bodies of responses during a recording)
JMS jms-mappings
Native IBM MQ ibm-mq-mappings
gRPC grpc-mappings
Thrift thrift-mappings
Files file-mappings

You can change the root directory by changing the value of the trafficparrot.virtualservice.trafficFilesRootUrl property.

XPath tutorials

XPath (XML Path Language) is a query language for finding and selecting elements in an XML document. Traffic Parrot allows to match requests using XPath.

We recommend the following reading to users who would like to take their XPaths skills to an advanced level: