Add mocks configuration dump and restore
This commit is contained in:
parent
c02e93edc3
commit
44f44ee392
6 changed files with 285 additions and 32 deletions
|
@ -8,4 +8,4 @@ RUN mkdir /externalSchema
|
||||||
|
|
||||||
VOLUME /externalSchema
|
VOLUME /externalSchema
|
||||||
|
|
||||||
CMD java -cp /mockserver.jar:/externalSchema -jar /mockserver.jar
|
CMD java -cp /mockserver.jar:/externalSchema pl.touk.mockserver.server.Main
|
||||||
|
|
168
README.md
168
README.md
|
@ -1,24 +1,71 @@
|
||||||
[](https://travis-ci.org/TouK/http-mock-server)
|
[](https://travis-ci.org/TouK/http-mock-server)
|
||||||
|
|
||||||
# HTTP MOCK SERVER
|
HTTP MOCK SERVER
|
||||||
|
================
|
||||||
|
|
||||||
## Create server jar
|
Http Mock Server allows to mock HTTP request using groovy closures.
|
||||||
|
|
||||||
|
Create server jar
|
||||||
|
-----------------
|
||||||
|
|
||||||
```
|
```
|
||||||
cd mockserver
|
cd mockserver
|
||||||
mvn clean package assembly:single
|
mvn clean package assembly:single
|
||||||
```
|
```
|
||||||
|
|
||||||
## Start server
|
Start server
|
||||||
|
------------
|
||||||
|
|
||||||
### Native start
|
### Native start
|
||||||
|
|
||||||
```
|
```
|
||||||
java -jar mockserver.jar [PORT]
|
java -jar mockserver-full.jar [PORT] [CONFIGURATION_FILE]
|
||||||
```
|
```
|
||||||
|
|
||||||
Default port is 9999.
|
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 -> \'<response/>\' }'
|
||||||
|
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'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Start with docker
|
### Start with docker
|
||||||
|
|
||||||
Docker and docker-compose is needed.
|
Docker and docker-compose is needed.
|
||||||
|
@ -28,7 +75,8 @@ Docker and docker-compose is needed.
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
## Create mock on server
|
Create mock on server
|
||||||
|
---------------------
|
||||||
|
|
||||||
### Via client
|
### Via client
|
||||||
|
|
||||||
|
@ -47,11 +95,11 @@ remoteMockServer.addMock(new AddMock(
|
||||||
schema: ...
|
schema: ...
|
||||||
))
|
))
|
||||||
```
|
```
|
||||||
|
|
||||||
### Via HTTP
|
### Via HTTP
|
||||||
|
|
||||||
Send POST request to localhost:<PORT>/serverControl
|
Send POST request to localhost:<PORT>/serverControl
|
||||||
|
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<addMock xmlns="http://touk.pl/mockserver/api/request">
|
<addMock xmlns="http://touk.pl/mockserver/api/request">
|
||||||
<name>...</name>
|
<name>...</name>
|
||||||
|
@ -64,33 +112,35 @@ Send POST request to localhost:<PORT>/serverControl
|
||||||
<method>...</method>
|
<method>...</method>
|
||||||
<responseHeaders>...</responseHeaders>
|
<responseHeaders>...</responseHeaders>
|
||||||
<schema>...</schema>
|
<schema>...</schema>
|
||||||
|
<imports alias="..." fullClassName="..."/>
|
||||||
</addMock>
|
</addMock>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Parameters
|
### Parameters
|
||||||
|
|
||||||
* name - name of mock, must be unique
|
- name - name of mock, must be unique
|
||||||
* path - path on which mock should be created
|
- 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
|
- 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}
|
- 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 { _ -> '' }
|
- 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
|
- 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
|
- statusCode - integer, status code of response when predicate is satisfied, default 200
|
||||||
* method - POST|PUT|DELETE|GET|TRACE|OPTION|HEAD, expected http method of request, default POST
|
- method - POST|PUT|DELETE|GET|TRACE|OPTION|HEAD, expected http method of request, default POST
|
||||||
* responseHeaders - groovyClosure as string which must evaluate to Map which will be added to response headers, default { _ -> [:] }
|
- 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
|
- 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
|
||||||
|
|
||||||
### Closures request properties
|
### Closures request properties
|
||||||
|
|
||||||
In closures input parameter (called req) contains properties:
|
In closures input parameter (called req) contains properties:
|
||||||
|
|
||||||
* text - request body as java.util.String
|
- text - request body as java.util.String
|
||||||
* headers - java.util.Map with request headers
|
- headers - java.util.Map with request headers
|
||||||
* query - java.util.Map with query parameters
|
- query - java.util.Map with query parameters
|
||||||
* xml - groovy.util.slurpersupport.GPathResult created from request body (if request body is valid xml)
|
- 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)
|
- 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)
|
- json - java.lang.Object created from request body (if request body is valid json)
|
||||||
* path - java.util.List<String> with not empty parts of request path
|
- path - java.util.List<String> with not empty parts of request path
|
||||||
|
|
||||||
Response if success:
|
Response if success:
|
||||||
|
|
||||||
|
@ -104,7 +154,9 @@ Response with error message if failure:
|
||||||
<exceptionOccured xmlns="http://touk.pl/mockserver/api/response">...</exceptionOccured>
|
<exceptionOccured xmlns="http://touk.pl/mockserver/api/response">...</exceptionOccured>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Peek mock
|
Peek mock
|
||||||
|
---------
|
||||||
|
|
||||||
Mock could be peeked to get get report of its invocations.
|
Mock could be peeked to get get report of its invocations.
|
||||||
|
|
||||||
### Via client
|
### Via client
|
||||||
|
@ -114,6 +166,7 @@ List<MockEvent> mockEvents = remoteMockServer.peekMock('...')
|
||||||
```
|
```
|
||||||
|
|
||||||
### Via HTTP
|
### Via HTTP
|
||||||
|
|
||||||
Send POST request to localhost:<PORT>/serverControl
|
Send POST request to localhost:<PORT>/serverControl
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
|
@ -160,7 +213,8 @@ Response with error message if failure:
|
||||||
<exceptionOccured xmlns="http://touk.pl/mockserver/api/response">...</exceptionOccured>
|
<exceptionOccured xmlns="http://touk.pl/mockserver/api/response">...</exceptionOccured>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Remove mock
|
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.
|
When mock was used it could be unregistered by name. It also optionally returns report of mock invocations if second parameter is true.
|
||||||
|
|
||||||
|
@ -169,7 +223,9 @@ When mock was used it could be unregistered by name. It also optionally returns
|
||||||
```java
|
```java
|
||||||
List<MockEvent> mockEvents = remoteMockServer.removeMock('...', ...)
|
List<MockEvent> mockEvents = remoteMockServer.removeMock('...', ...)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Via HTTP
|
### Via HTTP
|
||||||
|
|
||||||
Send POST request to localhost:<PORT>/serverControl
|
Send POST request to localhost:<PORT>/serverControl
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
|
@ -223,7 +279,8 @@ Response with error message if failure:
|
||||||
<exceptionOccured xmlns="http://touk.pl/mockserver/api/response">...</exceptionOccured>
|
<exceptionOccured xmlns="http://touk.pl/mockserver/api/response">...</exceptionOccured>
|
||||||
```
|
```
|
||||||
|
|
||||||
## List mocks definitions
|
List mocks definitions
|
||||||
|
----------------------
|
||||||
|
|
||||||
### Via client
|
### Via client
|
||||||
|
|
||||||
|
@ -249,12 +306,69 @@ Response:
|
||||||
<soap>...</soap>
|
<soap>...</soap>
|
||||||
<method>...</method>
|
<method>...</method>
|
||||||
<statusCode>...</statusCode>
|
<statusCode>...</statusCode>
|
||||||
|
<imports alias="..." fullClassName="..."/>
|
||||||
</mock>
|
</mock>
|
||||||
...
|
...
|
||||||
</mocks>
|
</mocks>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Remote repository
|
Get mocks configuration
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
### Via client
|
||||||
|
|
||||||
|
```java
|
||||||
|
ConfigObject mocks = remoteMockServer.getConfiguration()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Via HTTP
|
||||||
|
|
||||||
|
Send GET request to localhost:<PORT>/serverControl/configuration
|
||||||
|
|
||||||
|
Response:
|
||||||
|
|
||||||
|
```groovy
|
||||||
|
testRest2 {
|
||||||
|
port=9998
|
||||||
|
response='{ req -> \'<response/>\' }'
|
||||||
|
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`.
|
Mockserver is available at `philanthropist.touk.pl`.
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,11 @@ import pl.touk.mockserver.api.request.AddMock
|
||||||
import pl.touk.mockserver.api.request.MockServerRequest
|
import pl.touk.mockserver.api.request.MockServerRequest
|
||||||
import pl.touk.mockserver.api.request.PeekMock
|
import pl.touk.mockserver.api.request.PeekMock
|
||||||
import pl.touk.mockserver.api.request.RemoveMock
|
import pl.touk.mockserver.api.request.RemoveMock
|
||||||
import pl.touk.mockserver.api.response.*
|
import pl.touk.mockserver.api.response.MockEventReport
|
||||||
|
import pl.touk.mockserver.api.response.MockPeeked
|
||||||
|
import pl.touk.mockserver.api.response.MockRemoved
|
||||||
|
import pl.touk.mockserver.api.response.MockReport
|
||||||
|
import pl.touk.mockserver.api.response.Mocks
|
||||||
|
|
||||||
import javax.xml.bind.JAXBContext
|
import javax.xml.bind.JAXBContext
|
||||||
|
|
||||||
|
@ -47,6 +51,13 @@ class RemoteMockServer {
|
||||||
return mockPeeked.mockEvents ?: []
|
return mockPeeked.mockEvents ?: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigObject getConfiguration() {
|
||||||
|
HttpGet get = new HttpGet(address + '/configuration')
|
||||||
|
CloseableHttpResponse response = client.execute(get)
|
||||||
|
String configuration = Util.extractStringResponse(response)
|
||||||
|
return new ConfigSlurper().parse(configuration)
|
||||||
|
}
|
||||||
|
|
||||||
private static StringEntity buildRemoveMockRequest(RemoveMock data) {
|
private static StringEntity buildRemoveMockRequest(RemoveMock data) {
|
||||||
return new StringEntity(marshallRequest(data), ContentType.create("text/xml", "UTF-8"))
|
return new StringEntity(marshallRequest(data), ContentType.create("text/xml", "UTF-8"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1029,4 +1029,66 @@ class MockServerIntegrationTest extends Specification {
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.removeMock('testRest')?.size() == 1
|
remoteMockServer.removeMock('testRest')?.size() == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def "should get configuration of mocks and reconfigure new mock server based on it"() {
|
||||||
|
given:
|
||||||
|
remoteMockServer.addMock(new AddMock(
|
||||||
|
name: 'testRest2',
|
||||||
|
path: 'testEndpoint',
|
||||||
|
port: 9998,
|
||||||
|
predicate: '''{ req -> req.xml.name() == 'request1'}''',
|
||||||
|
response: '''{ req -> '<response/>' }''',
|
||||||
|
responseHeaders: '{ _ -> [a: "b"] }'
|
||||||
|
))
|
||||||
|
remoteMockServer.addMock(new AddMock(
|
||||||
|
name: 'testRest4',
|
||||||
|
path: 'testEndpoint',
|
||||||
|
port: 9999,
|
||||||
|
soap: true,
|
||||||
|
statusCode: 204,
|
||||||
|
method: Method.PUT
|
||||||
|
))
|
||||||
|
remoteMockServer.addMock(new AddMock(
|
||||||
|
name: 'testRest3',
|
||||||
|
path: 'testEndpoint2',
|
||||||
|
port: 9999
|
||||||
|
))
|
||||||
|
remoteMockServer.addMock(new AddMock(
|
||||||
|
name: 'testRest5',
|
||||||
|
path: 'testEndpoint',
|
||||||
|
port: 9999
|
||||||
|
))
|
||||||
|
remoteMockServer.addMock(new AddMock(
|
||||||
|
name: 'testRest6',
|
||||||
|
path: 'testEndpoint2',
|
||||||
|
port: 9999
|
||||||
|
))
|
||||||
|
remoteMockServer.addMock(new AddMock(
|
||||||
|
name: 'testRest',
|
||||||
|
path: 'testEndpoint',
|
||||||
|
port: 9999,
|
||||||
|
schema: 'schema2.xsd',
|
||||||
|
imports: [
|
||||||
|
new ImportAlias(alias: 'aaa', fullClassName: 'bbb'),
|
||||||
|
new ImportAlias(alias: 'ccc', fullClassName: 'bla')
|
||||||
|
]
|
||||||
|
))
|
||||||
|
remoteMockServer.removeMock('testRest5')
|
||||||
|
when:
|
||||||
|
ConfigObject configObject = remoteMockServer.configuration
|
||||||
|
httpMockServer.stop()
|
||||||
|
httpMockServer = new HttpMockServer(9000, configObject)
|
||||||
|
|
||||||
|
then:
|
||||||
|
List<MockReport> mockReport = remoteMockServer.listMocks()
|
||||||
|
mockReport.size() == 5
|
||||||
|
assertMockReport(mockReport[0], [name: 'testRest', path: 'testEndpoint', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }', soap: false, statusCode: 200, method: Method.POST, schema: 'schema2.xsd'])
|
||||||
|
assertMockReport(mockReport[1], [name: 'testRest2', path: 'testEndpoint', port: 9998, predicate: '''{ req -> req.xml.name() == 'request1'}''', response: '''{ req -> '<response/>' }''', responseHeaders: '{ _ -> [a: "b"] }', soap: false, statusCode: 200, method: Method.POST])
|
||||||
|
assertMockReport(mockReport[2], [name: 'testRest3', path: 'testEndpoint2', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }', soap: false, statusCode: 200, method: Method.POST])
|
||||||
|
assertMockReport(mockReport[3], [name: 'testRest4', path: 'testEndpoint', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }', soap: true, statusCode: 204, method: Method.PUT])
|
||||||
|
assertMockReport(mockReport[4], [name: 'testRest6', path: 'testEndpoint2', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }', soap: false, statusCode: 200, method: Method.POST])
|
||||||
|
mockReport[0].imports.find { it.alias == 'aaa' }?.fullClassName == 'bbb'
|
||||||
|
mockReport[0].imports.find { it.alias == 'ccc' }?.fullClassName == 'bla'
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package pl.touk.mockserver.server
|
||||||
import com.sun.net.httpserver.HttpExchange
|
import com.sun.net.httpserver.HttpExchange
|
||||||
import groovy.util.logging.Slf4j
|
import groovy.util.logging.Slf4j
|
||||||
import pl.touk.mockserver.api.common.ImportAlias
|
import pl.touk.mockserver.api.common.ImportAlias
|
||||||
|
import pl.touk.mockserver.api.common.Method
|
||||||
import pl.touk.mockserver.api.request.AddMock
|
import pl.touk.mockserver.api.request.AddMock
|
||||||
import pl.touk.mockserver.api.request.MockServerRequest
|
import pl.touk.mockserver.api.request.MockServerRequest
|
||||||
import pl.touk.mockserver.api.request.PeekMock
|
import pl.touk.mockserver.api.request.PeekMock
|
||||||
|
@ -30,18 +31,27 @@ class HttpMockServer {
|
||||||
private final HttpServerWraper httpServerWraper
|
private final HttpServerWraper httpServerWraper
|
||||||
private final Map<Integer, HttpServerWraper> childServers = new ConcurrentHashMap<>()
|
private final Map<Integer, HttpServerWraper> childServers = new ConcurrentHashMap<>()
|
||||||
private final Set<String> mockNames = new CopyOnWriteArraySet<>()
|
private final Set<String> mockNames = new CopyOnWriteArraySet<>()
|
||||||
|
private final ConfigObject configuration = new ConfigObject()
|
||||||
|
|
||||||
private static
|
private static
|
||||||
final JAXBContext requestJaxbContext = JAXBContext.newInstance(AddMock.package.name, AddMock.classLoader)
|
final JAXBContext requestJaxbContext = JAXBContext.newInstance(AddMock.package.name, AddMock.classLoader)
|
||||||
|
|
||||||
HttpMockServer(int port = 9999) {
|
HttpMockServer(int port = 9999, ConfigObject initialConfiguration = new ConfigObject()) {
|
||||||
httpServerWraper = new HttpServerWraper(port)
|
httpServerWraper = new HttpServerWraper(port)
|
||||||
|
|
||||||
|
initialConfiguration.values()?.each { ConfigObject co ->
|
||||||
|
addMock(co)
|
||||||
|
}
|
||||||
|
|
||||||
httpServerWraper.createContext('/serverControl', {
|
httpServerWraper.createContext('/serverControl', {
|
||||||
HttpExchange ex ->
|
HttpExchange ex ->
|
||||||
try {
|
try {
|
||||||
if (ex.requestMethod == 'GET') {
|
if (ex.requestMethod == 'GET') {
|
||||||
|
if (ex.requestURI.path == '/serverControl/configuration') {
|
||||||
|
createResponse(ex, configuration.prettyPrint(), 200)
|
||||||
|
} else {
|
||||||
listMocks(ex)
|
listMocks(ex)
|
||||||
|
}
|
||||||
} else if (ex.requestMethod == 'POST') {
|
} else if (ex.requestMethod == 'POST') {
|
||||||
MockServerRequest request = requestJaxbContext.createUnmarshaller().unmarshal(ex.requestBody) as MockServerRequest
|
MockServerRequest request = requestJaxbContext.createUnmarshaller().unmarshal(ex.requestBody) as MockServerRequest
|
||||||
if (request instanceof AddMock) {
|
if (request instanceof AddMock) {
|
||||||
|
@ -95,10 +105,41 @@ class HttpMockServer {
|
||||||
Mock mock = mockFromRequest(request)
|
Mock mock = mockFromRequest(request)
|
||||||
HttpServerWraper child = getOrCreateChildServer(mock.port)
|
HttpServerWraper child = getOrCreateChildServer(mock.port)
|
||||||
child.addMock(mock)
|
child.addMock(mock)
|
||||||
|
saveConfiguration(request)
|
||||||
mockNames << name
|
mockNames << name
|
||||||
createResponse(ex, new MockAdded(), 200)
|
createResponse(ex, new MockAdded(), 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addMock(ConfigObject co) {
|
||||||
|
String name = co.name
|
||||||
|
if (name in mockNames) {
|
||||||
|
throw new RuntimeException('mock already registered')
|
||||||
|
}
|
||||||
|
Mock mock = mockFromConfig(co)
|
||||||
|
HttpServerWraper child = getOrCreateChildServer(mock.port)
|
||||||
|
child.addMock(mock)
|
||||||
|
configuration.put(name, co)
|
||||||
|
mockNames << name
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveConfiguration(AddMock request) {
|
||||||
|
ConfigObject mockDefinition = new ConfigObject()
|
||||||
|
request.metaPropertyValues.findAll { it.name != 'class' && it.value }.each {
|
||||||
|
if (it.name == 'imports') {
|
||||||
|
ConfigObject configObject = new ConfigObject()
|
||||||
|
it.value.each { ImportAlias imp ->
|
||||||
|
configObject.put(imp.alias, imp.fullClassName)
|
||||||
|
}
|
||||||
|
mockDefinition.put(it.name, configObject)
|
||||||
|
} else if (it.name == 'method') {
|
||||||
|
mockDefinition.put(it.name, it.value.name())
|
||||||
|
} else {
|
||||||
|
mockDefinition.put(it.name, it.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
configuration.put(request.name, mockDefinition)
|
||||||
|
}
|
||||||
|
|
||||||
private static Mock mockFromRequest(AddMock request) {
|
private static Mock mockFromRequest(AddMock request) {
|
||||||
Mock mock = new Mock(request.name, request.path, request.port)
|
Mock mock = new Mock(request.name, request.path, request.port)
|
||||||
mock.imports = request.imports?.collectEntries { [(it.alias): it.fullClassName] } ?: [:]
|
mock.imports = request.imports?.collectEntries { [(it.alias): it.fullClassName] } ?: [:]
|
||||||
|
@ -112,6 +153,19 @@ class HttpMockServer {
|
||||||
return mock
|
return mock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Mock mockFromConfig(ConfigObject co) {
|
||||||
|
Mock mock = new Mock(co.name, co.path, co.port)
|
||||||
|
mock.imports = co.imports
|
||||||
|
mock.predicate = co.predicate ?: null
|
||||||
|
mock.response = co.response ?: null
|
||||||
|
mock.soap = co.soap ?: null
|
||||||
|
mock.statusCode = co.statusCode ?: null
|
||||||
|
mock.method = co.method ? Method.valueOf(co.method) : null
|
||||||
|
mock.responseHeaders = co.responseHeaders ?: null
|
||||||
|
mock.schema = co.schema ?: null
|
||||||
|
return mock
|
||||||
|
}
|
||||||
|
|
||||||
private HttpServerWraper getOrCreateChildServer(int mockPort) {
|
private HttpServerWraper getOrCreateChildServer(int mockPort) {
|
||||||
HttpServerWraper child = childServers[mockPort]
|
HttpServerWraper child = childServers[mockPort]
|
||||||
if (!child) {
|
if (!child) {
|
||||||
|
@ -132,6 +186,7 @@ class HttpMockServer {
|
||||||
it.removeMock(name)
|
it.removeMock(name)
|
||||||
}.flatten() as List<MockEvent>
|
}.flatten() as List<MockEvent>
|
||||||
mockNames.remove(name)
|
mockNames.remove(name)
|
||||||
|
configuration.remove(name)
|
||||||
MockRemoved mockRemoved = new MockRemoved(
|
MockRemoved mockRemoved = new MockRemoved(
|
||||||
mockEvents: createMockEventReports(mockEvents)
|
mockEvents: createMockEventReports(mockEvents)
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import groovy.util.logging.Slf4j
|
||||||
@Slf4j
|
@Slf4j
|
||||||
class Main {
|
class Main {
|
||||||
static void main(String[] args) {
|
static void main(String[] args) {
|
||||||
HttpMockServer httpMockServer = args.length == 1 ? new HttpMockServer(args[0] as int) : new HttpMockServer()
|
HttpMockServer httpMockServer = startMockServer(args)
|
||||||
|
|
||||||
Runtime.runtime.addShutdownHook(new Thread({
|
Runtime.runtime.addShutdownHook(new Thread({
|
||||||
log.info('Http server is stopping...')
|
log.info('Http server is stopping...')
|
||||||
|
@ -17,4 +17,15 @@ class Main {
|
||||||
Thread.sleep(10000)
|
Thread.sleep(10000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static HttpMockServer startMockServer(String... args) {
|
||||||
|
switch (args.length) {
|
||||||
|
case 1:
|
||||||
|
return new HttpMockServer(args[0] as int)
|
||||||
|
case 2:
|
||||||
|
return new HttpMockServer(args[0] as int, new ConfigSlurper().parse(new File(args[1]).toURI().toURL()))
|
||||||
|
default:
|
||||||
|
return new HttpMockServer()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue