[![Build Status](https://img.shields.io/travis/TouK/http-mock-server/master.svg?style=flat)](https://travis-ci.org/TouK/http-mock-server) HTTP MOCK SERVER ================ Http Mock Server allows to mock HTTP request using groovy closures. Create server jar ----------------- ``` cd mockserver mvn clean package assembly:single ``` Start server ------------ ### Native start ``` java -jar mockserver-full.jar [PORT] [CONFIGURATION_FILE] ``` Default port is 9999. If configuration file is passed then port must be defined. Configuration file is groovy configuration script e.g. : ```groovy testRest2 { port=9998 response='{ req -> \'\' }' responseHeaders='{ _ -> [a: "b"] }' path='testEndpoint' predicate='{ req -> req.xml.name() == \'request1\'}' name='testRest2' } testRest4 { soap=true port=9999 path='testEndpoint' name='testRest4' method='PUT' statusCode=204 } testRest3 { port=9999 path='testEndpoint2' name='testRest3' } testRest6 { port=9999 path='testEndpoint2' name='testRest6' maxUses=1 cyclic=true } testRest { imports { aaa='bbb' ccc='bla' } port=10001 path='testEndpoint' name='testRest' } testHttps { soap=false port=10443 path='testHttps' name='testHttps' method='GET' https={ keystorePath='/tmp/keystore.jks' keystorePassword='keystorePass' keyPassword='keyPass' truststorePath='/tmp/truststore.jks' truststorePassword='truststorePass' requireClientAuth=true } } ``` ### Build with docker Docker and docker-compose is needed. ``` ./buildImage.sh docker-compose up -d ``` ### Docker repoository Built image is available at https://hub.docker.com/r/alien11689/mockserver/ Create mock on server --------------------- ### Via client ```java RemoteMockServer remoteMockServer = new RemoteMockServer('localhost', ) remoteMockServer.addMock(new AddMock( name: '...', path: '...', port: ..., predicate: '''...''', response: '''...''', soap: ..., statusCode: ..., method: ..., responseHeaders: ..., schema: ..., maxUses: ..., cyclic: ..., https: new Https( keystorePath: '/tmp/keystore.jks', keystorePassword: 'keystorePass', keyPassword: 'keyPass', truststorePath: '/tmp/truststore.jks', truststorePassword: 'truststorePass', requireClientAuth: true ) )) ``` ### Via HTTP Send POST request to localhost:/serverControl ```xml ... ... ... ... ... ... ... ... ... ... ... ... /tmp/keystore.jks keystorePass keyPass /tmp/truststore.jks truststorePass true ``` ### Parameters - name - name of mock, must be unique - path - path on which mock should be created - port - inteer, port on which mock should be created, cannot be the same as mock server port - predicate - groovy closure as string which must evaluate to true, when request object will be given to satisfy mock, optional, default {_ -> true} - response - groovy closure as string which must evaluate to string which will be response of mock when predicate is satisfied, optional, default { _ -> '' } - soap - true or false, is request and response should be wrapped in soap Envelope and Body elements, default false - statusCode - integer, status code of response when predicate is satisfied, default 200 - method - POST|PUT|DELETE|GET|TRACE|OPTION|HEAD|ANY_METHOD, expected http method of request, default `POST`, `ANY_METHOD` matches all HTTP methods - responseHeaders - groovyClosure as string which must evaluate to Map which will be added to response headers, default { _ -> \[:] } - schema - path to xsd schema file on mockserver classpath; default empty, so no vallidation of request is performed; if validation fails then response has got status 400 and response is raw message from validator - imports - list of imports for closures (each import is separate tag); `alias` is the name of `fullClassName` available in closure; `fullClassName` must be available on classpath of mock server - https - HTTPS configuration - maxUses - limit uses of mock to the specific number, after that mock is marked as ignored (any negative number means unlimited - default, cannot set value to 0), after this number of invocation mock history is still available, but mock does not apply to any request - cyclic - should mock be added after `maxUses` uses at the end of the mock list (by default false) #### HTTPS configuration - keystorePath - path to keystore in JKS format, keystore should contains only one privateKeyEntry - keystorePassword - keystore password - keyPassword - key password - truststorePath - path to truststore in JKS format - truststorePassword - truststore password - requireClientAuth - whether client auth is required (two-way SSL) **HTTP** and **HTTPS** should be started on separated ports. ### Closures request properties In closures input parameter (called req) contains properties: - text - request body as java.util.String - headers - java.util.Map with request headers - query - java.util.Map with query parameters - xml - groovy.util.slurpersupport.GPathResult created from request body (if request body is valid xml) - soap - groovy.util.slurpersupport.GPathResult created from request body without Envelope and Body elements (if request body is valid soap xml) - json - java.lang.Object created from request body (if request body is valid json) - path - java.util.List with not empty parts of request path Response if success: ```xml ``` Response with error message if failure: ```xml ... ``` Peek mock --------- Mock could be peeked to get get report of its invocations. ### Via client ```java List mockEvents = remoteMockServer.peekMock('...') ``` ### Via HTTP Send POST request to localhost:/serverControl ```xml ... ``` Response if success: ```xml ...
...
...
... ... ... ...
... ...
...
...
``` Response with error message if failure: ```xml ... ``` Remove mock ----------- When mock was used it could be unregistered by name. It also optionally returns report of mock invocations if second parameter is true. ### Via client ```java List mockEvents = remoteMockServer.removeMock('...', ...) ``` ### Via HTTP Send POST request to localhost:/serverControl ```xml ... ... ``` Response if success (and skipReport not given or equal false): ```xml ...
...
...
... ... ... ...
... ...
...
...
``` If skipReport is set to true then response will be: ```xml ``` Response with error message if failure: ```xml ... ``` List mocks definitions ---------------------- ### Via client ```java List mocks = remoteMockServer.listMocks() ``` ### Via HTTP Send GET request to localhost:/serverControl Response: ```xml ... ... ... ... ... ... ... ... ... ... ``` Get mocks configuration ----------------------- ### Via client ```java ConfigObject mocks = remoteMockServer.getConfiguration() ``` ### Via HTTP Send GET request to localhost:/serverControl/configuration Response: ```groovy testRest2 { port=9998 response='{ req -> \'\' }' responseHeaders='{ _ -> [a: "b"] }' path='testEndpoint' predicate='{ req -> req.xml.name() == \'request1\'}' name='testRest2' } testRest4 { soap=true port=9999 path='testEndpoint' name='testRest4' method='PUT' statusCode=204 } testRest3 { port=9999 path='testEndpoint2' name='testRest3' } testRest6 { port=9999 path='testEndpoint2' name='testRest6' } testRest { imports { aaa='bbb' ccc='bla' } port=10001 path='testEndpoint' name='testRest' } ``` This response could be saved to file and passed as it is during mock server creation. Remote repository ----------------- Mockserver is available at `philanthropist.touk.pl`. Just add repository to maven pom: ```xml ... ... touk https://philanthropist.touk.pl/nexus/content/repositories/releases ... ... ``` FAQ --- Q: *Can I have two mocks returning responses interchangeably for the same request?* A: Yes, you can. Just set two mocks with `maxUses: 1` and `cyclic: true`.