GithubHelp home page GithubHelp logo

mindprogenitor / wiremock-freemarker-extension Goto Github PK

View Code? Open in Web Editor NEW
1.0 2.0 1.0 109 KB

License: Apache License 2.0

Java 100.00%
wiremock freemarker-template wiremock-server stub stub-body

wiremock-freemarker-extension's Introduction

wiremock-freemarker-extension

Wiremock Freemarker Extension is a Wiremock extension that allows the use of the Freemarker template engine by using the stub body as a freemarker template and making the request available to be used in the template as variables (if the request is either a valid xml or json object, it will be parsed and the values may be referenced directly in the template).

NOTICE:

This extension was created initially for wiremock version 2.4.1 when it wasn't distributed with any response template mechanism (A similar extension was developed then under a proprietary license and recreated independently for open source maintenance). Handlebars was added to wiremock version 2.5, and this library was updated to continue using stubs that had already been created to use with freemarker.

Maintenance of this library is now limited as wiremock now provides a template mechanism out of the box.

How to set it up

Wiremock can run both as a standalone mock server or as a unit test server instance, as explained in the Wiremock documentation.

In order to make the extension available for stub creation, the extension needs both to be available in the wiremock server classpath as well as having the server configured to be aware of the extension. Please refer to the official documentation for a more complete overview of how to use wiremock with extensions.

  • For Unit Tests

    You need to include the wiremock freemarker extension as dependency of your project.

    Example dependencies in the pom.xml of a maven project

    <dependency>
        <groupId>com.github.tomakehurst</groupId>`
        <artifactId>wiremock</artifactId>
        <version>2.14.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.mindprogeny.wiremock.extension</groupId>
        <artifactId>wiremock-freemarker-extension</artifactId>
        <version>0.0.1</version>
        <scope>test</scope>
    </dependency>

    The extension was mainly developed for the standalone version of wiremock and as such includes all libraries required to run it on the standalone. The wiremock library includes some jackson libraries which are not available in the standalone version (since all dependencies are bundled in the same jar and the library packages are renamed to avoid conflicts), as such, using more recent versions of wiremock can potentially cause conflicts in dependencies. Check for dependency conflicts and solve them.

    To start up a Wiremock Server using a JUnit rule:

               .
               .  
    import org.junit.Rule;
    import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
    import com.github.tomakehurst.wiremock.junit.WireMockRule;
    import com.mindprogeny.wiremock.extension.freemarker.FreemarkerResponseTransformer;
               .
               .
    
    @Rule
    public WireMockRule wiremock = 
           new WireMockRule(WireMockConfiguration.wireMockConfig()
                                                 .port(55080)
                                                 .extensions(new FreemarkerResponseTransformer()));

    Where 55080 would be the port where the wiremock server would be listening.

  • For Standalone Wiremock

    Download the standalone wiremock server (as explained in the Wiremock documentation) and the wiremock freemarker extension.

    Run wiremock using the following minimal command (feel free to add any additional wiremock specific flags you need):

    java -cp "wiremock-standalone-2.14.0.jar:wiremock-freemarker-extension-0.0.2.jar" \
         com.github.tomakehurst.wiremock.standalone.WireMockServerRunner \
         --port 8080 --https-port 8443 \
         --extensions com.mindprogeny.wiremock.extension.freemarker.FreemarkerResponseTransformer

How to use it

You may use wiremock as normal, except that you may define the body of your stub as a freemarker template, associate the stub with the freemarker extension and the extension will transform the stub body with freemarker before returning it to the requesting agent.

For example:

wiremock.stubFor(get(urlEqualTo("/test"))
        .willReturn(aResponse().withStatus(200)
                               .withHeader("content-type", "application/xml")
                               .withBody("<root><date>${.now}</date></root>")
                               .withTransformers("freemarker-transformer")));

Or through the REST API:

{
  "request": {
    "url": "/test",
    "method": "GET" },
  "response": {
    "status": 200,
    "body": "<root><date>${.now}</date></root>",
    "headers": {
    "Content-Type": "application/xml" },
    "transformers": ["freemarker-transformer"] }
}

Calls to endpoints configured with the extension will take the following steps:

Freemarker Extension Processing flow

  1. Request for /test is received
  2. Wiremock finds configured matching stub and identifies it as using the freemarker transformer.
  3. The extension is called with the stubbed response as well as the received request
  4. Extension parses the request and creates a request object to be used as a variable in the freemarker template.
  5. Freemarker template is called using the stub body as the template and the request object as a variable.
  6. Extension returns processed template as the response body.
  7. Wiremock returns response to calling agent.

In this simple example, regardless of the request contents, the response is a simple xml object with a date tag containing the timestamp of the response generation.

The Request Object

The request is processed by the extension and transformed into a map which is made available to the template.

The Request Object has the following format:

.-> request
|     |-> body                     - The original request body. May be null if request has no content.
|     |-> url                      - The endpoint, with parameters, used to access the stub
|     |-> cookies                  - attribute containing all cookies received. May be null if no cookies.
|     |     |-> <cookie name_1>    - Each cookie value can be directly accessed by name
|     |     |-> <cookie name_2>
|     |     |       ..
|     |     \-> <cookie name_n>
|     \-> parameters               - Query parameters received. May be null if no query parameters present.
|           |-> <parameter name_1> - Each query parameter value can be accessed directly by name
|           |-> <parameter name_2>
|           |       ..
|           \-> <parameter name_n>
|
|   If the request body is either an xml or a json object, the request object is filled with additional map entries
|   taking values from the xml or json objects.
|
|-> <request attribute/tag>
|-> <request attribute/tag>
|       ..
\-> <request attribute/tag>

The variable structure made available in the request object is dependent on the kind of object present in the request.

Refer to the Request Object Documentation for more information.

Using Variables for dynamic stubbing

The Extension also allows you to create variable sets which can be used in templates allowing for dynamic stub generation (using part of the request to choose a set of variables to use) or simplified templates (for example, using loops to generate repetitive blocks).

Refer to the dynamic templates documentation for additional information.

wiremock-freemarker-extension's People

Contributors

mindprogenitor avatar spaisey avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

spaisey

wiremock-freemarker-extension's Issues

JsonArray request payload fails to parse

Should a request payload represent an array, the request fails to be parsed and causes a runtime exception. For example:

[
    {
        "idType": "ID_ISIN",
        "includeUnlistedEquities": true,
        "idValue": "US01609W1027"
    },
    {
        "idType": "ID_ISIN",
        "includeUnlistedEquities": true,
        "idValue": "CH0244767585"
    }
]

The issue is that the any request Json is expected to parse as a Map:

    private Map parseJson(String request) throws IOException {
        return jsonMapper.readValue(request, Map.class);
    }

Suggest checking for initial [character and parsing accordingly.
Will fix and raise PR.

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.