Extensions
You can use extensions to add dynamic content to response headers and response
body.
For example, if you create a response with body
{ "Number": "{{randomInteger}}", "Date": "{{httpNow}}" }
it will be rendered as
{ "Number": "165007562", "Date": "Sat, 02 Apr 2017 18:41:35 GMT" }
Below you will find all available extensions.
Load CSV data file
Save your data in trafficparrot-release-x.y.z/data/data.csv in CSV format.
To load the data in the response use {{csvDataFile 'row,col'}} in the response definition.
For example,
{{csvDataFile '2,4'}} will read file trafficparrot-release-x.y.z/data/data.csv
then load the 2nd row in the file and then lookup the 4th column value.
Generate random values
To generate a random value in the response use one of the following:
- {{randomInteger}} - A random integer, e.g. 1543243211
- {{randomDouble}} - A random double, e.g. -0.3476573
- {{randomString}} - A random String, e.g. lW7H2gRfFqALsev0zDoJ4o3qGMtNYYgs
- {{randomUUID}} - A random UUID, e.g. 5d0d4989-b5c1-412e-bbe6-457fd5d58493
Use request data in response *
To use request attributes in the response:
- {{request.url}} - URL
- {{request.path}} - Path
- {{request.path.[n]}} - N-th path element
- {{request.query.parameterName}} - Parameter value
- {{request.query.parameterName.[n]}} - N-th parameter value
- {{request.headers.headerName}} - First value of a header
- {{request.headers.[headerName]}} - First value of a header
- {{request.headers.headerName.[n]}}- N-th value of header
- {{request.cookies.cookieName}} - Cookie value
- {{request.body}} - Request body
Handlebars extension functions
All of jknack Handlebars string helpers are available for use in response headers and body.
- {{defaultIfEmpty value ["default value"]}}} - Render a default value if the specified value is not available, for example {{defaultIfEmpty request.query.username "Username parameter was not present in the request"}}
- {{substring value start end}} - Render the beginning of the string value, for example {{defaultIfEmpty request.query.username 0 3}}
- {{substring value start}} - Render the end of the string value, for example {{defaultIfEmpty request.query.username 5}}
- {{replace value "aaa" "bbb"}} - Replace string aaa with bbb
- {{abbreviate value 5}} - Render a truncated version of a string. Minimum value is 4.
- {{yesno value [yes="yes"] [no="no"] maybe=["maybe"]}} - Convert a boolean "true", "false" to a string representation
- {{capitalize value [fully=false]}} - Capitalize a string
- {{stripTags value}} - Remove all HTML or XML tags from the string
- {{stringFormat string param0 param1 ... paramN}} - Format the string
- {{slugify value}} - Create a slug, for example "a b c" will be rendered as "a-b-c"
- {{numberFormat number ["format"] [locale=default]}} - Format a number for a given locale or format
- {{now ["format"] [tz=timeZone|timeZoneId]}} - Date is a specified format and timezone
- {{upper value}} - Uppercase string
- {{lower value}} - Lowercase string
- {{rjust value 20 [pad=" "]}} - Right adjust string
- {{ljust value 20 [pad=" "]}} - Left adjust string
- {{cut value [" "]}} - Cut out all the occurrences in the string
- {{center value size=19 [pad="char"]}} - Center string value padded with the specified character
- {{capitalizeFirst value}} - Capitalize first word
- {{join value "," [prefix="aPrefix"] [suffix="aSuffix"]}} - Join an array of values
Loops and iterators
All block helpers
defined in handlebars specification are available.
As an example the following use of
{{#each}} in a response body will render all request headers:
<requestHeaders>
{{#each request.headers}}
<name>{{@key}}</name>
<value>{{this}}</value>
{{/each}}
</requestHeaders>
Conditionals (if, else)
All block helpers
defined in handlebars specification are available.
As an example the following use of
{{#if}} in a response body will render a different response based on availability of a request paramater:
{{#if request.query.password}}
Password was present in the request.
{{else}}
Please provide a password!
{{/if}}
Assorted
- {{httpNow}} - Date in RFC 1123 format (HTTP date format), e.g. Date: {{httpNow}} can be rendered as Date: Sat, 01 Apr 2017 10:55:05 GMT. Typically used as a value for the "Date" header.
Disabling {{...}}
If you would like to use
{{...}} notation in your templates and not having it interpreted as
an attempt to use an extension you need to do
one of the following things:
- For individual responses, use escaped syntax: \{{...}}
- Or, disable extensions globally by setting both
trafficparrot.jms.handlebars.enabled=false
and
trafficparrot.http.handlebars.enabled=false in trafficparrot.properties
and restarting Traffic Parrot
Create your own custom extensions
Custom handlebar helpers
Traffic Parrot allows for Handlebars
notation in the responses. They are typically used to add dynamic content to the responses.
They can be used for both HTTP and JMS.
For example, all of these existing extensions are handlebar helpers:
If you would like to add new Handlebars Helpers, have a look at the following example:
- Download and open the
SDK workspace project
in an IDE like IntelliJ IDEA or Eclipse
- Explore the project and the Java classes available in the SDK.
Look for usages of TrafficParrotHelper
They provide example usages of Handlebars Helpers.
Have a look at both main and test classes.
-
Create a new extension class based on the examples provided in the
SDK (by extending TrafficParrotHelper class). For example:
package com.trafficparrot.sdk.example.http.template;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Options;
import com.trafficparrot.sdk.handlebars.TrafficParrotHelper;
import java.io.IOException;
import java.util.Random;
public class RandomInteger extends TrafficParrotHelper<Object> {
@Override
public Handlebars.SafeString doApply(Object context, Options options) throws IOException {
return new Handlebars.SafeString(String.valueOf(new Random().nextInt()));
}
}
- Build the project ./mvnw clean install
- Copy
target/trafficparrot-sdk-workspace-x.y.z.jar
to directory trafficparrot-enterprise-release-x.y.z/lib/virtualservice-x.y.z to use with HTTP
or to directory trafficparrot-enterprise-release-x.y.z/lib/external to use with JMS
-
Look for properties trafficparrot.http.handlebars.helpers
and trafficparrot.jms.handlebars.helpers in
trafficparrot.properties and add your new class to the list of
extension classes there. (Why do I have to edit the extensions properties every time?)
- Stop Traffic Parrot
- Start Traffic Parrot
-
If the name of the class you have created is RandomInteger
the extension you will use in response templates
will be called {{randomInteger}} by default.
The name can be changed by implementing the TrafficParrotHelper.getName method.
-
Edit an existing mapping and put {{randomInteger}} anywhere in the response body.
-
Make a request to the virtual service
-
The response you receive should contain the randomly generated integer.
Traffic Parrot allows for creating custom HTTP response transformers.
They allow for altering any part of the HTTP response in any way you like,
and have access to the request data.
If you would like to add a new HTTP response transformer, have a look at the following example:
- Download and open the
SDK workspace project
in an IDE like IntelliJ IDEA or Eclipse
- Explore the project and the Java classes available in the SDK.
They provide example usages of HTTP response transformers.
Look for usages of HttpResponseTransformer and
HttpResponseDefinitionTransformer.
Have a look at both main and test classes.
-
Create a new extension class based on the examples provided in the
SDK (by extending HttpResponseTransformer class). For example:
package com.trafficparrot.sdk.example.http.responsetransformer;
import com.github.tomakehurst.wiremock.common.FileSource;
import com.github.tomakehurst.wiremock.extension.Parameters;
import com.github.tomakehurst.wiremock.http.Request;
import com.github.tomakehurst.wiremock.http.Response;
import com.trafficparrot.sdk.http.HttpResponseTransformer;
import java.util.Random;
import static com.github.tomakehurst.wiremock.http.HttpHeaders.noHeaders;
public class RandomServerFailure extends HttpResponseTransformer {
@Override
protected Response doTransform(Request request, Response response, FileSource fileSource, Parameters parameters) {
if (new Random().nextBoolean()) {
return Response.Builder
.like(response)
.but()
.status(500)
.headers(noHeaders())
.body("Server error!")
.build();
} else {
return response;
}
}
@Override
public String getName() {
return getClass().getSimpleName();
}
}
- Build the project ./mvnw clean install
- Copy
target/trafficparrot-sdk-workspace-x.y.z.jar to directory
trafficparrot-enterprise-release-x.y.z/lib/virtualservice-x.y.z
-
Look for property trafficparrot.http.responsetransformers
in trafficparrot.properties and add your new class to the list of
extension classes there. (Why do I have to edit the extensions properties every time?)
- Stop Traffic Parrot
- Start Traffic Parrot
-
If the name of the class you have created is RandomServerFailure
the extension you will use in response templates
will be automatically called {{randomServerFailure}}
-
Edit an existing mapping and put {{randomServerFailure}} anywhere in the response body.
-
Make a few requests to the virtual service
-
The response you receive should randomly fail, as defined
in the response transformer RandomServerFailure.
Traffic Parrot allows for creating custom JMS response transformers.
They allow for altering any part of the JMS response message in any way you like,
and have access to the request data.
If you would like to add a new JMS response transformer, have a look at the following example:
- Download and open the
SDK workspace project
in an IDE like IntelliJ IDEA or Eclipse
- Explore the project and the Java classes available in the SDK.
They provide example usages of JMS response transformers.
Look for usages of JmsResponseTransformer and
TextJmsResponseTransformer.
Have a look at both main and test classes.
-
Create a new extension class based on the examples provided in the
SDK (by extending TextJmsResponseTransformer class). For example:
package com.trafficparrot.sdk.example.jms;
import com.github.tomakehurst.wiremock.common.Json;
import com.trafficparrot.sdk.jms.Destination;
import com.trafficparrot.sdk.jms.JmsResponse;
import com.trafficparrot.sdk.jms.JmsResponseBuilder;
import com.trafficparrot.sdk.jms.TextJmsResponseTransformer;
import javax.jms.JMSException;
import javax.jms.TextMessage;
public class ChooseResponseQueueBasedOnRequestMessageBody extends TextJmsResponseTransformer {
@Override
protected JmsResponse doTransform(Destination requestDestination, TextMessage requestMessage, JmsResponse response) throws JMSException {
Req payment = Json.read(requestMessage.getText(), Req.class);
String newDestinationName;
if ("foo".equals(payment.requestField)) {
newDestinationName = "response_queue_1";
} else if ("bar".equals(payment.requestField)) {
newDestinationName = "response_queue_2";
} else {
logger.error("Destination not configured for req.requestField '" + payment.requestField + "'");
throw new UnsupportedOperationException(payment.requestField);
}
logger.info("Redirecting message to " + newDestinationName);
return new JmsResponseBuilder()
.like(response)
.withDestination(new Destination(newDestinationName, response.destination.type))
.build();
}
}
class Req {
public String requestField;
}
- Build the project ./mvnw clean install
- Copy
target/trafficparrot-sdk-workspace-x.y.z.jar to directory
trafficparrot-enterprise-release-x.y.z/lib/external
-
Look for property trafficparrot.jms.responsetransformers
in trafficparrot.properties and add your new class to the list of
extension classes there. (Why do I have to edit the extensions properties every time?)
- Stop Traffic Parrot
- Start Traffic Parrot
-
Edit an existing JMS mapping and select ChooseResponseQueueBasedOnRequestMessageBody
from the "Response transformer" dropdown.
-
Start the JMS virtual service in replay mode and send a JMS request
with content {"requestField": "foo"}
-
The response message should be sent to queue response_queue_1
-
Send a JMS request with content {"requestField": "bar"}
-
The response message should be sent to queue response_queue_2
Video
The following video describes usage of Traffic Parrot extensions in
version 3.7.x and below.
Note: property names and class names have changed since.
Old version warning!
This documentation is for an old version of Traffic Parrot. There is a more recent Traffic Parrot version available for download at trafficparrot.com
Browse documentation for recent version