Make api with jaxb
Change-Id: Ic0ac5ce212fac17583699868709b67a701231755
This commit is contained in:
parent
5545b67ebd
commit
82434f46a3
38 changed files with 583 additions and 422 deletions
20
mockserver-api/pom.xml
Normal file
20
mockserver-api/pom.xml
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>http-mock-server</artifactId>
|
||||||
|
<groupId>pl.touk.mockserver</groupId>
|
||||||
|
<version>1.1.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>mockserver-api</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,33 @@
|
||||||
|
package pl.touk.mockserver.api.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class AddMock extends MockServerRequest {
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
private String predicate;
|
||||||
|
|
||||||
|
private String response;
|
||||||
|
|
||||||
|
private Boolean soap;
|
||||||
|
|
||||||
|
private Integer statusCode;
|
||||||
|
|
||||||
|
private Method method;
|
||||||
|
|
||||||
|
private String responseHeaders;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package pl.touk.mockserver.api.request;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlEnum;
|
||||||
|
|
||||||
|
@XmlEnum
|
||||||
|
public enum Method {
|
||||||
|
POST,
|
||||||
|
GET,
|
||||||
|
DELETE,
|
||||||
|
PUT,
|
||||||
|
TRACE,
|
||||||
|
HEAD,
|
||||||
|
OPTIONS,
|
||||||
|
PATCH;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package pl.touk.mockserver.api.request;
|
||||||
|
|
||||||
|
public abstract class MockServerRequest {
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package pl.touk.mockserver.api.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class PeekMock extends MockServerRequest{
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private String name;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package pl.touk.mockserver.api.request;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class RemoveMock extends MockServerRequest {
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private Boolean skipReport;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD) package pl.touk.mockserver.api.request;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
|
@ -0,0 +1,13 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import javax.xml.bind.annotation.XmlValue;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@Data
|
||||||
|
public class ExceptionOccured {
|
||||||
|
@XmlValue
|
||||||
|
private String message;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class MockAdded extends MockServerResponse {
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MockEventReport {
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private MockRequestReport request;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private MockResponseReport response;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@XmlRootElement(name = "mocks")
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class MockListing extends MockServerResponse {
|
||||||
|
@XmlElement(name = "mock")
|
||||||
|
private List<MockReport> mocks;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class MockPeeked extends MockServerResponse {
|
||||||
|
@XmlElement(name = "mockEvent")
|
||||||
|
private List<MockEventReport> mockEvents;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
public class MockRemoved extends MockServerResponse {
|
||||||
|
@XmlElement(name = "mockEvent")
|
||||||
|
private List<MockEventReport> mockEvents;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MockReport {
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private String predicate;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private String response;
|
||||||
|
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private String responseHeaders;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MockRequestReport {
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
@XmlElementWrapper(name = "headers")
|
||||||
|
@XmlElement(name = "param")
|
||||||
|
private List<Parameter> headers;
|
||||||
|
|
||||||
|
@XmlElementWrapper(name = "query")
|
||||||
|
@XmlElement(name = "param")
|
||||||
|
private List<Parameter> queryParams;
|
||||||
|
|
||||||
|
@XmlElementWrapper(name = "path")
|
||||||
|
@XmlElement(name = "elem")
|
||||||
|
private List<String> paths;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
import javax.xml.bind.annotation.XmlElementWrapper;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class MockResponseReport {
|
||||||
|
@XmlElement(required = true)
|
||||||
|
private int statusCode;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
@XmlElementWrapper(name = "headers")
|
||||||
|
@XmlElement(name = "param")
|
||||||
|
private List<Parameter> headers;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
public abstract class MockServerResponse {
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAttribute;
|
||||||
|
import javax.xml.bind.annotation.XmlValue;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Parameter {
|
||||||
|
@XmlAttribute(required = true)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XmlValue
|
||||||
|
private String value;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
@XmlAccessorType(XmlAccessType.FIELD) package pl.touk.mockserver.api.response;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
|
@ -0,0 +1,4 @@
|
||||||
|
AddMock
|
||||||
|
Method
|
||||||
|
PeekMock
|
||||||
|
RemoveMock
|
|
@ -0,0 +1,11 @@
|
||||||
|
ExceptionOccured
|
||||||
|
MockAdded
|
||||||
|
MockEventReport
|
||||||
|
MockListing
|
||||||
|
MockPeeked
|
||||||
|
MockRemoved
|
||||||
|
MockReport
|
||||||
|
MockRequestReport
|
||||||
|
MockResponseReport
|
||||||
|
MockServerResponse
|
||||||
|
Parameter
|
|
@ -25,5 +25,9 @@
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.touk.mockserver</groupId>
|
||||||
|
<artifactId>mockserver-api</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
package pl.touk.mockserver.client
|
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
|
||||||
import groovy.transform.TypeChecked
|
|
||||||
import org.apache.commons.lang3.StringEscapeUtils
|
|
||||||
|
|
||||||
@CompileStatic
|
|
||||||
@TypeChecked
|
|
||||||
class AddMockRequestData {
|
|
||||||
String name
|
|
||||||
String path
|
|
||||||
Integer port
|
|
||||||
String predicate
|
|
||||||
String response
|
|
||||||
Boolean soap
|
|
||||||
Integer statusCode
|
|
||||||
Method method
|
|
||||||
String responseHeaders
|
|
||||||
|
|
||||||
void setPredicate(String predicate) {
|
|
||||||
this.predicate = StringEscapeUtils.escapeXml11(predicate)
|
|
||||||
}
|
|
||||||
|
|
||||||
void setResponse(String response) {
|
|
||||||
this.response = StringEscapeUtils.escapeXml11(response)
|
|
||||||
}
|
|
||||||
|
|
||||||
void setResponseHeaders(String responseHeaders) {
|
|
||||||
this.responseHeaders = StringEscapeUtils.escapeXml11(responseHeaders)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package pl.touk.mockserver.client
|
|
||||||
|
|
||||||
enum Method {
|
|
||||||
POST,
|
|
||||||
GET,
|
|
||||||
DELETE,
|
|
||||||
PUT,
|
|
||||||
TRACE,
|
|
||||||
HEAD,
|
|
||||||
OPTIONS,
|
|
||||||
PATCH
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package pl.touk.mockserver.client
|
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
|
||||||
import groovy.transform.EqualsAndHashCode
|
|
||||||
import groovy.transform.TypeChecked
|
|
||||||
|
|
||||||
@EqualsAndHashCode
|
|
||||||
@CompileStatic
|
|
||||||
@TypeChecked
|
|
||||||
class MockEvent {
|
|
||||||
final MockRequest request
|
|
||||||
final MockResponse response
|
|
||||||
|
|
||||||
MockEvent(MockRequest request, MockResponse response) {
|
|
||||||
this.request = request
|
|
||||||
this.response = response
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package pl.touk.mockserver.client
|
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
|
||||||
import groovy.transform.EqualsAndHashCode
|
|
||||||
import groovy.transform.TypeChecked
|
|
||||||
|
|
||||||
@CompileStatic
|
|
||||||
@TypeChecked
|
|
||||||
@EqualsAndHashCode
|
|
||||||
class MockRequest {
|
|
||||||
final String text
|
|
||||||
final Map<String, String> headers
|
|
||||||
final Map<String, String> query
|
|
||||||
final List<String> path
|
|
||||||
|
|
||||||
MockRequest(String text, Map<String, String> headers, Map<String, String> query, List<String> path) {
|
|
||||||
this.text = text
|
|
||||||
this.headers = headers
|
|
||||||
this.query = query
|
|
||||||
this.path = path
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package pl.touk.mockserver.client
|
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
|
||||||
import groovy.transform.EqualsAndHashCode
|
|
||||||
import groovy.transform.TypeChecked
|
|
||||||
|
|
||||||
@CompileStatic
|
|
||||||
@TypeChecked
|
|
||||||
@EqualsAndHashCode
|
|
||||||
class MockResponse {
|
|
||||||
final int statusCode
|
|
||||||
final String text
|
|
||||||
final Map<String, String> headers
|
|
||||||
|
|
||||||
MockResponse(int statusCode, String text, Map<String, String> headers) {
|
|
||||||
this.statusCode = statusCode
|
|
||||||
this.text = text
|
|
||||||
this.headers = headers
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
package pl.touk.mockserver.client
|
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
|
||||||
import groovy.transform.TypeChecked
|
|
||||||
|
|
||||||
@CompileStatic
|
|
||||||
@TypeChecked
|
|
||||||
class PeekMockRequestData {
|
|
||||||
String name
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package pl.touk.mockserver.client
|
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
|
||||||
import groovy.transform.EqualsAndHashCode
|
|
||||||
import groovy.transform.ToString
|
|
||||||
import groovy.transform.TypeChecked
|
|
||||||
|
|
||||||
@CompileStatic
|
|
||||||
@TypeChecked
|
|
||||||
@EqualsAndHashCode
|
|
||||||
@ToString
|
|
||||||
class RegisteredMock {
|
|
||||||
final String name
|
|
||||||
final String path
|
|
||||||
final int port
|
|
||||||
final String predicate
|
|
||||||
final String response
|
|
||||||
final String responseHeaders
|
|
||||||
|
|
||||||
RegisteredMock(String name, String path, int port, String predicate, String response, String responseHeaders) {
|
|
||||||
this.name = name
|
|
||||||
this.path = path
|
|
||||||
this.port = port
|
|
||||||
this.predicate = predicate
|
|
||||||
this.response = response
|
|
||||||
this.responseHeaders = responseHeaders
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
package pl.touk.mockserver.client
|
package pl.touk.mockserver.client
|
||||||
|
|
||||||
import groovy.util.slurpersupport.GPathResult
|
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse
|
import org.apache.http.client.methods.CloseableHttpResponse
|
||||||
import org.apache.http.client.methods.HttpGet
|
import org.apache.http.client.methods.HttpGet
|
||||||
import org.apache.http.client.methods.HttpPost
|
import org.apache.http.client.methods.HttpPost
|
||||||
|
@ -8,112 +7,70 @@ import org.apache.http.entity.ContentType
|
||||||
import org.apache.http.entity.StringEntity
|
import org.apache.http.entity.StringEntity
|
||||||
import org.apache.http.impl.client.CloseableHttpClient
|
import org.apache.http.impl.client.CloseableHttpClient
|
||||||
import org.apache.http.impl.client.HttpClients
|
import org.apache.http.impl.client.HttpClients
|
||||||
|
import pl.touk.mockserver.api.request.AddMock
|
||||||
|
import pl.touk.mockserver.api.request.MockServerRequest
|
||||||
|
import pl.touk.mockserver.api.request.PeekMock
|
||||||
|
import pl.touk.mockserver.api.request.RemoveMock
|
||||||
|
import pl.touk.mockserver.api.response.*
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext
|
||||||
|
|
||||||
class RemoteMockServer {
|
class RemoteMockServer {
|
||||||
private final String address
|
private final String address
|
||||||
private final CloseableHttpClient client = HttpClients.createDefault()
|
private final CloseableHttpClient client = HttpClients.createDefault()
|
||||||
|
private static final JAXBContext requestContext = JAXBContext.newInstance(AddMock.package.name, AddMock.classLoader)
|
||||||
|
private static
|
||||||
|
final JAXBContext responseContext = JAXBContext.newInstance(MockAdded.package.name, MockAdded.classLoader)
|
||||||
|
|
||||||
RemoteMockServer(String host, int port) {
|
RemoteMockServer(String host, int port) {
|
||||||
address = "http://$host:$port/serverControl"
|
address = "http://$host:$port/serverControl"
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMock(AddMockRequestData addMockRequestData) {
|
void addMock(AddMock addMockData) {
|
||||||
HttpPost addMockPost = new HttpPost(address)
|
HttpPost addMockPost = new HttpPost(address)
|
||||||
addMockPost.entity = buildAddMockRequest(addMockRequestData)
|
addMockPost.entity = buildAddMockRequest(addMockData)
|
||||||
CloseableHttpResponse response = client.execute(addMockPost)
|
CloseableHttpResponse response = client.execute(addMockPost)
|
||||||
GPathResult responseXml = Util.extractXmlResponse(response)
|
Util.extractResponse(response)
|
||||||
if (responseXml.name() != 'mockAdded') {
|
|
||||||
if (responseXml.text() == 'mock already registered') {
|
|
||||||
throw new MockAlreadyExists()
|
|
||||||
|
|
||||||
}
|
|
||||||
throw new InvalidMockDefinition(responseXml.text())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MockEvent> removeMock(String name, boolean skipReport = false) {
|
List<MockEventReport> removeMock(String name, boolean skipReport = false) {
|
||||||
HttpPost removeMockPost = new HttpPost(address)
|
HttpPost removeMockPost = new HttpPost(address)
|
||||||
removeMockPost.entity = buildRemoveMockRequest(new RemoveMockRequestData(name: name, skipReport: skipReport))
|
removeMockPost.entity = buildRemoveMockRequest(new RemoveMock(name: name, skipReport: skipReport))
|
||||||
CloseableHttpResponse response = client.execute(removeMockPost)
|
CloseableHttpResponse response = client.execute(removeMockPost)
|
||||||
GPathResult responseXml = Util.extractXmlResponse(response)
|
MockRemoved mockRemoved = Util.extractResponse(response) as MockRemoved
|
||||||
if (responseXml.name() == 'mockRemoved') {
|
return mockRemoved.mockEvents ?: []
|
||||||
return responseXml.'mockEvent'.collect {
|
|
||||||
new MockEvent(mockRequestFromXml(it.request), mockResponseFromXml(it.response))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new MockDoesNotExist()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MockEvent> peekMock(String name) {
|
List<MockEventReport> peekMock(String name) {
|
||||||
HttpPost removeMockPost = new HttpPost(address)
|
HttpPost removeMockPost = new HttpPost(address)
|
||||||
removeMockPost.entity = buildPeekMockRequest(new PeekMockRequestData(name: name))
|
removeMockPost.entity = buildPeekMockRequest(new PeekMock(name: name))
|
||||||
CloseableHttpResponse response = client.execute(removeMockPost)
|
CloseableHttpResponse response = client.execute(removeMockPost)
|
||||||
GPathResult responseXml = Util.extractXmlResponse(response)
|
MockPeeked mockPeeked = Util.extractResponse(response) as MockPeeked
|
||||||
if (responseXml.name() == 'mockPeeked') {
|
return mockPeeked.mockEvents ?: []
|
||||||
return responseXml.'mockEvent'.collect {
|
|
||||||
new MockEvent(mockRequestFromXml(it.request), mockResponseFromXml(it.response))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new MockDoesNotExist()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MockResponse mockResponseFromXml(GPathResult xml) {
|
private static StringEntity buildRemoveMockRequest(RemoveMock data) {
|
||||||
return new MockResponse(xml.statusCode.text() as int, xml.text.text(), xml.headers.param.collectEntries {
|
return new StringEntity(marshallRequest(data), ContentType.create("text/xml", "UTF-8"))
|
||||||
[(it.@name.text()): it.text()]
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MockRequest mockRequestFromXml(GPathResult xml) {
|
private static String marshallRequest(MockServerRequest data) {
|
||||||
return new MockRequest(
|
StringWriter sw = new StringWriter()
|
||||||
xml.text.text(),
|
requestContext.createMarshaller().marshal(data, sw)
|
||||||
xml.headers.param.collectEntries { [(it.@name.text()): it.text()] },
|
return sw.toString()
|
||||||
xml.query.param.collectEntries { [(it.@name.text()): it.text()] },
|
|
||||||
xml.path.elem*.text()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StringEntity buildRemoveMockRequest(RemoveMockRequestData data) {
|
private static StringEntity buildPeekMockRequest(PeekMock peekMock) {
|
||||||
return new StringEntity("""\
|
return new StringEntity(marshallRequest(peekMock), ContentType.create("text/xml", "UTF-8"))
|
||||||
<removeMock>
|
|
||||||
<name>${data.name}</name>
|
|
||||||
<skipReport>${data.skipReport}</skipReport>
|
|
||||||
</removeMock>
|
|
||||||
""", ContentType.create("text/xml", "UTF-8"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StringEntity buildPeekMockRequest(PeekMockRequestData data) {
|
private static StringEntity buildAddMockRequest(AddMock data) {
|
||||||
return new StringEntity("""\
|
return new StringEntity(marshallRequest(data), ContentType.create("text/xml", "UTF-8"))
|
||||||
<peekMock>
|
|
||||||
<name>${data.name}</name>
|
|
||||||
</peekMock>
|
|
||||||
""", ContentType.create("text/xml", "UTF-8"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StringEntity buildAddMockRequest(AddMockRequestData data) {
|
List<MockReport> listMocks() {
|
||||||
return new StringEntity("""\
|
|
||||||
<addMock>
|
|
||||||
<name>${data.name}</name>
|
|
||||||
<path>${data.path}</path>
|
|
||||||
<port>${data.port}</port>
|
|
||||||
${data.predicate ? "<predicate>${data.predicate}</predicate>" : ''}
|
|
||||||
${data.response ? "<response>${data.response}</response>" : ''}
|
|
||||||
${data.soap != null ? "<soap>${data.soap}</soap>" : ''}
|
|
||||||
${data.statusCode ? "<statusCode>${data.statusCode}</statusCode>" : ''}
|
|
||||||
${data.method ? "<method>${data.method}</method>" : ''}
|
|
||||||
${data.responseHeaders ? "<responseHeaders>${data.responseHeaders}</responseHeaders>" : ''}
|
|
||||||
</addMock>
|
|
||||||
""", ContentType.create("text/xml", "UTF-8"))
|
|
||||||
}
|
|
||||||
|
|
||||||
List<RegisteredMock> listMocks() {
|
|
||||||
HttpGet get = new HttpGet(address)
|
HttpGet get = new HttpGet(address)
|
||||||
CloseableHttpResponse response = client.execute(get)
|
CloseableHttpResponse response = client.execute(get)
|
||||||
GPathResult xml = Util.extractXmlResponse(response)
|
MockListing mockListing = Util.extractResponse(response) as MockListing
|
||||||
if (xml.name() == 'mocks') {
|
return mockListing.mocks
|
||||||
return xml.mock.collect {
|
|
||||||
new RegisteredMock(it.name.text(), it.path.text(), it.port.text() as int, it.predicate.text(), it.response.text(), it.responseHeaders.text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return []
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package pl.touk.mockserver.client
|
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
|
||||||
import groovy.transform.TypeChecked
|
|
||||||
|
|
||||||
@CompileStatic
|
|
||||||
@TypeChecked
|
|
||||||
class RemoveMockRequestData {
|
|
||||||
String name
|
|
||||||
boolean skipReport = false
|
|
||||||
}
|
|
|
@ -7,15 +7,42 @@ import groovy.util.slurpersupport.GPathResult
|
||||||
import org.apache.http.HttpEntity
|
import org.apache.http.HttpEntity
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse
|
import org.apache.http.client.methods.CloseableHttpResponse
|
||||||
import org.apache.http.util.EntityUtils
|
import org.apache.http.util.EntityUtils
|
||||||
|
import pl.touk.mockserver.api.response.ExceptionOccured
|
||||||
|
import pl.touk.mockserver.api.response.MockAdded
|
||||||
|
import pl.touk.mockserver.api.response.MockServerResponse
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext
|
||||||
|
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@TypeChecked
|
@TypeChecked
|
||||||
class Util {
|
class Util {
|
||||||
|
private static
|
||||||
|
final JAXBContext responseContext = JAXBContext.newInstance(MockAdded.package.name, MockAdded.classLoader)
|
||||||
|
|
||||||
static GPathResult extractXmlResponse(CloseableHttpResponse response) {
|
static GPathResult extractXmlResponse(CloseableHttpResponse response) {
|
||||||
|
return new XmlSlurper().parseText(extractStringResponse(response))
|
||||||
|
}
|
||||||
|
static String extractStringResponse(CloseableHttpResponse response) {
|
||||||
HttpEntity entity = response.entity
|
HttpEntity entity = response.entity
|
||||||
GPathResult xml = new XmlSlurper().parseText(EntityUtils.toString(entity, 'UTF-8'))
|
String responseString = EntityUtils.toString(entity, 'UTF-8')
|
||||||
EntityUtils.consumeQuietly(entity)
|
EntityUtils.consumeQuietly(entity)
|
||||||
return xml
|
return responseString
|
||||||
|
}
|
||||||
|
|
||||||
|
static MockServerResponse extractResponse(CloseableHttpResponse response) {
|
||||||
|
String responseString = extractStringResponse(response)
|
||||||
|
if (response.statusLine.statusCode == 200) {
|
||||||
|
return responseContext.createUnmarshaller().unmarshal(new StringReader(responseString)) as MockServerResponse
|
||||||
|
}
|
||||||
|
ExceptionOccured exceptionOccured = responseContext.createUnmarshaller().unmarshal(new StringReader(responseString)) as ExceptionOccured
|
||||||
|
String message = exceptionOccured.message
|
||||||
|
if (message == 'mock already registered') {
|
||||||
|
throw new MockAlreadyExists()
|
||||||
|
}
|
||||||
|
if (message == 'mock not registered') {
|
||||||
|
throw new MockDoesNotExist()
|
||||||
|
}
|
||||||
|
throw new InvalidMockDefinition(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
static String soap(String request) {
|
static String soap(String request) {
|
||||||
|
@ -26,13 +53,11 @@ class Util {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object extractJsonResponse(CloseableHttpResponse response) {
|
static Object extractJsonResponse(CloseableHttpResponse response) {
|
||||||
HttpEntity entity = response.entity
|
return new JsonSlurper().parseText(extractStringResponse(response))
|
||||||
Object json = new JsonSlurper().parseText(EntityUtils.toString(entity, 'UTF-8'))
|
|
||||||
EntityUtils.consumeQuietly(entity)
|
|
||||||
return json
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void consumeResponse(CloseableHttpResponse response) {
|
static void consumeResponse(CloseableHttpResponse response) {
|
||||||
EntityUtils.consumeQuietly(response.entity)
|
EntityUtils.consumeQuietly(response.entity)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,11 @@ import org.apache.http.entity.StringEntity
|
||||||
import org.apache.http.impl.client.CloseableHttpClient
|
import org.apache.http.impl.client.CloseableHttpClient
|
||||||
import org.apache.http.impl.client.HttpClients
|
import org.apache.http.impl.client.HttpClients
|
||||||
import org.apache.http.util.EntityUtils
|
import org.apache.http.util.EntityUtils
|
||||||
|
import pl.touk.mockserver.api.request.AddMock
|
||||||
|
import pl.touk.mockserver.api.request.Method
|
||||||
|
import pl.touk.mockserver.api.response.MockEventReport
|
||||||
|
import pl.touk.mockserver.api.response.MockReport
|
||||||
|
import pl.touk.mockserver.api.response.Parameter
|
||||||
import pl.touk.mockserver.client.*
|
import pl.touk.mockserver.client.*
|
||||||
import pl.touk.mockserver.server.HttpMockServer
|
import pl.touk.mockserver.server.HttpMockServer
|
||||||
import spock.lang.Shared
|
import spock.lang.Shared
|
||||||
|
@ -33,7 +38,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add working rest mock on endpoint"() {
|
def "should add working rest mock on endpoint"() {
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -54,7 +59,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add working rest mock on endpoint with utf"() {
|
def "should add working rest mock on endpoint with utf"() {
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRestUtf',
|
name: 'testRestUtf',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -76,7 +81,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add soap mock on endpoint"() {
|
def "should add soap mock on endpoint"() {
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -102,7 +107,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
then:
|
then:
|
||||||
thrown(MockDoesNotExist)
|
thrown(MockDoesNotExist)
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -120,7 +125,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should not add mock with existing name"() {
|
def "should not add mock with existing name"() {
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -129,7 +134,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
soap: true
|
soap: true
|
||||||
))
|
))
|
||||||
when:
|
when:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: 9998,
|
port: 9998,
|
||||||
|
@ -143,7 +148,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should not add mock with empty name"() {
|
def "should not add mock with empty name"() {
|
||||||
when:
|
when:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: '',
|
name: '',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: 9998,
|
port: 9998,
|
||||||
|
@ -157,7 +162,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock after deleting old mock with the same name"() {
|
def "should add mock after deleting old mock with the same name"() {
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -168,7 +173,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
and:
|
and:
|
||||||
remoteMockServer.removeMock('testSoap') == []
|
remoteMockServer.removeMock('testSoap') == []
|
||||||
and:
|
and:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -180,14 +185,14 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add simultaneously working post and rest mocks with the same predicate and endpoint nad port"() {
|
def "should add simultaneously working post and rest mocks with the same predicate and endpoint nad port"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
predicate: '''{req -> req.xml.name() == 'request'}''',
|
predicate: '''{req -> req.xml.name() == 'request'}''',
|
||||||
response: '''{req -> "<goodResponseRest-${req.xml.name()}/>"}'''
|
response: '''{req -> "<goodResponseRest-${req.xml.name()}/>"}'''
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -215,14 +220,14 @@ class MockServerIntegrationTest extends Specification {
|
||||||
@Unroll
|
@Unroll
|
||||||
def "should dispatch rest mocks when second on #name"() {
|
def "should dispatch rest mocks when second on #name"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest1',
|
name: 'testRest1',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
predicate: '''{req -> req.xml.name() == 'request1'}''',
|
predicate: '''{req -> req.xml.name() == 'request1'}''',
|
||||||
response: '''{req -> "<goodResponseRest1/>"}'''
|
response: '''{req -> "<goodResponseRest1/>"}'''
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: secondPath,
|
path: secondPath,
|
||||||
port: secondPort,
|
port: secondPort,
|
||||||
|
@ -254,7 +259,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
@Unroll
|
@Unroll
|
||||||
def "should dispatch rest mock with response code"() {
|
def "should dispatch rest mock with response code"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest1',
|
name: 'testRest1',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -276,7 +281,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should return response code 404 and error body the same as request body when mocks does not apply"() {
|
def "should return response code 404 and error body the same as request body when mocks does not apply"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest1',
|
name: 'testRest1',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -295,7 +300,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should inform that there was problem during adding mock - invalid port"() {
|
def "should inform that there was problem during adding mock - invalid port"() {
|
||||||
when:
|
when:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testSoap',
|
name: 'testSoap',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: -1,
|
port: -1,
|
||||||
|
@ -309,13 +314,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with get method"() {
|
def "should dispatch rest mock with get method"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -332,13 +337,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with trace method"() {
|
def "should dispatch rest mock with trace method"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -355,13 +360,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with head method"() {
|
def "should dispatch rest mock with head method"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -377,13 +382,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with options method"() {
|
def "should dispatch rest mock with options method"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -399,13 +404,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with put method"() {
|
def "should dispatch rest mock with put method"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -424,13 +429,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with delete method"() {
|
def "should dispatch rest mock with delete method"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -447,13 +452,13 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should dispatch rest mock with patch method"() {
|
def "should dispatch rest mock with patch method"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
response: '''{_ -> "<defaultResponse/>"}'''
|
response: '''{_ -> "<defaultResponse/>"}'''
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'test1',
|
path: 'test1',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -472,7 +477,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock that return headers"() {
|
def "should add mock that return headers"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -492,7 +497,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock that accepts only when certain request headers exists"() {
|
def "should add mock that accepts only when certain request headers exists"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -521,7 +526,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock that accepts only when certain query params exists"() {
|
def "should add mock that accepts only when certain query params exists"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -545,7 +550,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock that accepts only when request has specific body"() {
|
def "should add mock that accepts only when request has specific body"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -570,7 +575,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should add mock which response json to json"() {
|
def "should add mock which response json to json"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -595,7 +600,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should get list mocks"() {
|
def "should get list mocks"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9998,
|
port: 9998,
|
||||||
|
@ -603,27 +608,27 @@ class MockServerIntegrationTest extends Specification {
|
||||||
response: '''{ req -> '<response/>' }''',
|
response: '''{ req -> '<response/>' }''',
|
||||||
responseHeaders: '{ _ -> [a: "b"] }'
|
responseHeaders: '{ _ -> [a: "b"] }'
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest4',
|
name: 'testRest4',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999
|
port: 9999
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest3',
|
name: 'testRest3',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: 9999
|
port: 9999
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest5',
|
name: 'testRest5',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999
|
port: 9999
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest6',
|
name: 'testRest6',
|
||||||
path: 'testEndpoint2',
|
path: 'testEndpoint2',
|
||||||
port: 9999
|
port: 9999
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999
|
port: 9999
|
||||||
|
@ -631,17 +636,17 @@ class MockServerIntegrationTest extends Specification {
|
||||||
remoteMockServer.removeMock('testRest5')
|
remoteMockServer.removeMock('testRest5')
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.listMocks() == [
|
remoteMockServer.listMocks() == [
|
||||||
new RegisteredMock('testRest', 'testEndpoint', 9999, '{ _ -> true }', '''{ _ -> '' }''', '{ _ -> [:] }'),
|
new MockReport(name: 'testRest', path: 'testEndpoint', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }'),
|
||||||
new RegisteredMock('testRest2', 'testEndpoint', 9998, '''{ req -> req.xml.name() == 'request1'}''', '''{ req -> '<response/>' }''', '{ _ -> [a: "b"] }'),
|
new MockReport(name: 'testRest2', path: 'testEndpoint', port: 9998, predicate: '''{ req -> req.xml.name() == 'request1'}''', response: '''{ req -> '<response/>' }''', responseHeaders: '{ _ -> [a: "b"] }'),
|
||||||
new RegisteredMock('testRest3', 'testEndpoint2', 9999, '{ _ -> true }', '''{ _ -> '' }''', '{ _ -> [:] }'),
|
new MockReport(name: 'testRest3', path: 'testEndpoint2', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }'),
|
||||||
new RegisteredMock('testRest4', 'testEndpoint', 9999, '{ _ -> true }', '''{ _ -> '' }''', '{ _ -> [:] }'),
|
new MockReport(name: 'testRest4', path: 'testEndpoint', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }'),
|
||||||
new RegisteredMock('testRest6', 'testEndpoint2', 9999, '{ _ -> true }', '''{ _ -> '' }''', '{ _ -> [:] }')
|
new MockReport(name: 'testRest6', path: 'testEndpoint2', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }')
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
def "should add mock accepts path certain path params"() {
|
def "should add mock accepts path certain path params"() {
|
||||||
given:
|
given:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -664,7 +669,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
|
|
||||||
def "should get mock report when deleting mock"() {
|
def "should get mock report when deleting mock"() {
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -674,7 +679,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
responseHeaders: '''{req -> ['aaa':'14']}''',
|
responseHeaders: '''{req -> ['aaa':'14']}''',
|
||||||
soap: false
|
soap: false
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -706,40 +711,40 @@ class MockServerIntegrationTest extends Specification {
|
||||||
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
|
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
|
||||||
restPostResponse3.name() == 'goodResponseRest'
|
restPostResponse3.name() == 'goodResponseRest'
|
||||||
when:
|
when:
|
||||||
List<MockEvent> mockEvents1 = remoteMockServer.removeMock('testRest')
|
List<MockEventReport> mockEvents1 = remoteMockServer.removeMock('testRest')
|
||||||
then:
|
then:
|
||||||
mockEvents1.size() == 2
|
mockEvents1.size() == 2
|
||||||
mockEvents1[0].request.text == '<request/>'
|
mockEvents1[0].request.text == '<request/>'
|
||||||
!mockEvents1[0].request.headers?.keySet()?.empty
|
!mockEvents1[0].request.headers?.empty
|
||||||
mockEvents1[0].request.query == [:]
|
mockEvents1[0].request.queryParams == []
|
||||||
mockEvents1[0].request.path == ['testEndpoint']
|
mockEvents1[0].request.paths == ['testEndpoint']
|
||||||
!mockEvents1[0].response.headers?.keySet()?.empty
|
!mockEvents1[0].response.headers?.empty
|
||||||
mockEvents1[0].response.text == '<goodResponseRest-request/>'
|
mockEvents1[0].response.text == '<goodResponseRest-request/>'
|
||||||
mockEvents1[0].response.statusCode == 201
|
mockEvents1[0].response.statusCode == 201
|
||||||
|
|
||||||
mockEvents1[1].request.text == '<request15/>'
|
mockEvents1[1].request.text == '<request15/>'
|
||||||
!mockEvents1[1].request.headers?.keySet()?.empty
|
!mockEvents1[1].request.headers?.empty
|
||||||
mockEvents1[1].request.query == [:]
|
mockEvents1[1].request.queryParams == []
|
||||||
mockEvents1[1].request.path == ['testEndpoint', 'hello']
|
mockEvents1[1].request.paths == ['testEndpoint', 'hello']
|
||||||
!mockEvents1[1].response.headers?.keySet()?.empty
|
!mockEvents1[1].response.headers?.empty
|
||||||
mockEvents1[1].response.text == '<goodResponseRest-request15/>'
|
mockEvents1[1].response.text == '<goodResponseRest-request15/>'
|
||||||
mockEvents1[1].response.statusCode == 201
|
mockEvents1[1].response.statusCode == 201
|
||||||
when:
|
when:
|
||||||
List<MockEvent> mockEvents2 = remoteMockServer.removeMock('testRest2')
|
List<MockEventReport> mockEvents2 = remoteMockServer.removeMock('testRest2')
|
||||||
then:
|
then:
|
||||||
mockEvents2.size() == 1
|
mockEvents2.size() == 1
|
||||||
mockEvents2[0].request.text == '<reqXYZ/>'
|
mockEvents2[0].request.text == '<reqXYZ/>'
|
||||||
!mockEvents2[0].request.headers?.keySet()?.empty
|
!mockEvents2[0].request.headers?.empty
|
||||||
mockEvents2[0].request.query == [id: '123']
|
mockEvents2[0].request.queryParams == [new Parameter(name: 'id', value: '123')]
|
||||||
mockEvents2[0].request.path == ['testEndpoint']
|
mockEvents2[0].request.paths == ['testEndpoint']
|
||||||
mockEvents2[0].response.headers.aaa == '15'
|
mockEvents2[0].response.headers.find { it.name == 'aaa' }?.value == '15'
|
||||||
mockEvents2[0].response.text == '<goodResponseRest/>'
|
mockEvents2[0].response.text == '<goodResponseRest/>'
|
||||||
mockEvents2[0].response.statusCode == 202
|
mockEvents2[0].response.statusCode == 202
|
||||||
}
|
}
|
||||||
|
|
||||||
def "should get mock report when peeking mock"() {
|
def "should get mock report when peeking mock"() {
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -749,7 +754,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
responseHeaders: '''{req -> ['aaa':'14']}''',
|
responseHeaders: '''{req -> ['aaa':'14']}''',
|
||||||
soap: false
|
soap: false
|
||||||
))
|
))
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest2',
|
name: 'testRest2',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
@ -781,33 +786,33 @@ class MockServerIntegrationTest extends Specification {
|
||||||
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
|
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
|
||||||
restPostResponse3.name() == 'goodResponseRest'
|
restPostResponse3.name() == 'goodResponseRest'
|
||||||
when:
|
when:
|
||||||
List<MockEvent> mockEvents1 = remoteMockServer.peekMock('testRest')
|
List<MockEventReport> mockEvents1 = remoteMockServer.peekMock('testRest')
|
||||||
then:
|
then:
|
||||||
mockEvents1.size() == 2
|
mockEvents1.size() == 2
|
||||||
mockEvents1[0].request.text == '<request/>'
|
mockEvents1[0].request.text == '<request/>'
|
||||||
!mockEvents1[0].request.headers?.keySet()?.empty
|
!mockEvents1[0].request.headers?.empty
|
||||||
mockEvents1[0].request.query == [:]
|
mockEvents1[0].request.queryParams == []
|
||||||
mockEvents1[0].request.path == ['testEndpoint']
|
mockEvents1[0].request.paths == ['testEndpoint']
|
||||||
!mockEvents1[0].response.headers?.keySet()?.empty
|
!mockEvents1[0].response.headers?.empty
|
||||||
mockEvents1[0].response.text == '<goodResponseRest-request/>'
|
mockEvents1[0].response.text == '<goodResponseRest-request/>'
|
||||||
mockEvents1[0].response.statusCode == 201
|
mockEvents1[0].response.statusCode == 201
|
||||||
|
|
||||||
mockEvents1[1].request.text == '<request15/>'
|
mockEvents1[1].request.text == '<request15/>'
|
||||||
!mockEvents1[1].request.headers?.keySet()?.empty
|
!mockEvents1[1].request.headers?.empty
|
||||||
mockEvents1[1].request.query == [:]
|
mockEvents1[1].request.queryParams == []
|
||||||
mockEvents1[1].request.path == ['testEndpoint', 'hello']
|
mockEvents1[1].request.paths == ['testEndpoint', 'hello']
|
||||||
!mockEvents1[1].response.headers?.keySet()?.empty
|
!mockEvents1[1].response.headers?.empty
|
||||||
mockEvents1[1].response.text == '<goodResponseRest-request15/>'
|
mockEvents1[1].response.text == '<goodResponseRest-request15/>'
|
||||||
mockEvents1[1].response.statusCode == 201
|
mockEvents1[1].response.statusCode == 201
|
||||||
when:
|
when:
|
||||||
List<MockEvent> mockEvents2 = remoteMockServer.peekMock('testRest2')
|
List<MockEventReport> mockEvents2 = remoteMockServer.peekMock('testRest2')
|
||||||
then:
|
then:
|
||||||
mockEvents2.size() == 1
|
mockEvents2.size() == 1
|
||||||
mockEvents2[0].request.text == '<reqXYZ/>'
|
mockEvents2[0].request.text == '<reqXYZ/>'
|
||||||
!mockEvents2[0].request.headers?.keySet()?.empty
|
!mockEvents2[0].request.headers?.empty
|
||||||
mockEvents2[0].request.query == [id: '123']
|
mockEvents2[0].request.queryParams == [new Parameter(name: 'id', value: '123')]
|
||||||
mockEvents2[0].request.path == ['testEndpoint']
|
mockEvents2[0].request.paths == ['testEndpoint']
|
||||||
mockEvents2[0].response.headers.aaa == '15'
|
mockEvents2[0].response.headers.find {it.name == 'aaa'}?.value == '15'
|
||||||
mockEvents2[0].response.text == '<goodResponseRest/>'
|
mockEvents2[0].response.text == '<goodResponseRest/>'
|
||||||
mockEvents2[0].response.statusCode == 202
|
mockEvents2[0].response.statusCode == 202
|
||||||
}
|
}
|
||||||
|
@ -815,7 +820,7 @@ class MockServerIntegrationTest extends Specification {
|
||||||
@Unroll
|
@Unroll
|
||||||
def "should return mock report with #mockEvents events when deleting mock with flag skip mock = #skipReport"() {
|
def "should return mock report with #mockEvents events when deleting mock with flag skip mock = #skipReport"() {
|
||||||
expect:
|
expect:
|
||||||
remoteMockServer.addMock(new AddMockRequestData(
|
remoteMockServer.addMock(new AddMock(
|
||||||
name: 'testRest',
|
name: 'testRest',
|
||||||
path: 'testEndpoint',
|
path: 'testEndpoint',
|
||||||
port: 9999,
|
port: 9999,
|
||||||
|
|
|
@ -1,34 +1,40 @@
|
||||||
package pl.touk.mockserver.tests
|
package pl.touk.mockserver.tests
|
||||||
|
|
||||||
import groovy.util.slurpersupport.GPathResult
|
|
||||||
import org.apache.http.client.HttpClient
|
import org.apache.http.client.HttpClient
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse
|
import org.apache.http.client.methods.CloseableHttpResponse
|
||||||
import org.apache.http.client.methods.HttpPost
|
import org.apache.http.client.methods.HttpPost
|
||||||
import org.apache.http.entity.ContentType
|
import org.apache.http.entity.ContentType
|
||||||
import org.apache.http.entity.StringEntity
|
import org.apache.http.entity.StringEntity
|
||||||
import org.apache.http.impl.client.HttpClients
|
import org.apache.http.impl.client.HttpClients
|
||||||
import pl.touk.mockserver.client.AddMockRequestData
|
import pl.touk.mockserver.api.request.AddMock
|
||||||
import pl.touk.mockserver.client.RemoteMockServer
|
import pl.touk.mockserver.client.RemoteMockServer
|
||||||
import pl.touk.mockserver.client.Util
|
import pl.touk.mockserver.client.Util
|
||||||
import pl.touk.mockserver.server.HttpMockServer
|
import pl.touk.mockserver.server.HttpMockServer
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
import spock.lang.Timeout
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class ServerMockPT extends Specification {
|
class ServerMockPT extends Specification {
|
||||||
|
|
||||||
|
|
||||||
|
@Timeout(value = 60)
|
||||||
def "should handle many request simultaneously"() {
|
def "should handle many request simultaneously"() {
|
||||||
given:
|
given:
|
||||||
|
HttpClient client = HttpClients.createDefault()
|
||||||
HttpMockServer httpMockServer = new HttpMockServer()
|
HttpMockServer httpMockServer = new HttpMockServer()
|
||||||
RemoteMockServer controlServerClient = new RemoteMockServer("localhost", 9999)
|
RemoteMockServer controlServerClient = new RemoteMockServer("localhost", 9999)
|
||||||
HttpClient client = HttpClients.createDefault()
|
|
||||||
int requestAmount = 1000
|
int requestAmount = 1000
|
||||||
GPathResult[] responses = new GPathResult[requestAmount]
|
String[] responses = new String[requestAmount]
|
||||||
Thread[] threads = new Thread[requestAmount]
|
ExecutorService executorService = Executors.newFixedThreadPool(20)
|
||||||
for (int i = 0; i < requestAmount; ++i) {
|
for (int i = 0; i < requestAmount; ++i) {
|
||||||
int current = i
|
int current = i
|
||||||
threads[i] = new Thread({
|
executorService.submit {
|
||||||
int endpointNumber = current % 10
|
int endpointNumber = current % 10
|
||||||
int port = 9000 + (current % 7)
|
int port = 9000 + (current % 7)
|
||||||
controlServerClient.addMock(new AddMockRequestData(
|
controlServerClient.addMock(new AddMock(
|
||||||
name: "testRest$current",
|
name: "testRest$current",
|
||||||
path: "testEndpoint$endpointNumber",
|
path: "testEndpoint$endpointNumber",
|
||||||
port: port,
|
port: port,
|
||||||
|
@ -38,15 +44,14 @@ class ServerMockPT extends Specification {
|
||||||
HttpPost restPost = new HttpPost("http://localhost:$port/testEndpoint$endpointNumber")
|
HttpPost restPost = new HttpPost("http://localhost:$port/testEndpoint$endpointNumber")
|
||||||
restPost.entity = new StringEntity("<request$current/>", ContentType.create("text/xml", "UTF-8"))
|
restPost.entity = new StringEntity("<request$current/>", ContentType.create("text/xml", "UTF-8"))
|
||||||
CloseableHttpResponse response = client.execute(restPost)
|
CloseableHttpResponse response = client.execute(restPost)
|
||||||
responses[current] = Util.extractXmlResponse(response)
|
responses[current] = Util.extractStringResponse(response)
|
||||||
assert controlServerClient.removeMock("testRest$current").size() == 1
|
assert controlServerClient.removeMock("testRest$current", false).size() == 1
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
when:
|
when:
|
||||||
threads*.start()
|
executorService.awaitTermination(60, TimeUnit.SECONDS)
|
||||||
Thread.sleep(60000)
|
|
||||||
then:
|
then:
|
||||||
responses.eachWithIndex { res, i -> assert res.name() == "goodResponse$i" }
|
responses.eachWithIndex { res, i -> assert new XmlSlurper().parseText(res).name() == "goodResponse$i" as String }
|
||||||
cleanup:
|
cleanup:
|
||||||
httpMockServer.stop()
|
httpMockServer.stop()
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.touk.mockserver</groupId>
|
||||||
|
<artifactId>mockserver-api</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -2,9 +2,13 @@ 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 groovy.util.slurpersupport.GPathResult
|
import pl.touk.mockserver.api.request.AddMock
|
||||||
import groovy.xml.MarkupBuilder
|
import pl.touk.mockserver.api.request.MockServerRequest
|
||||||
|
import pl.touk.mockserver.api.request.PeekMock
|
||||||
|
import pl.touk.mockserver.api.request.RemoveMock
|
||||||
|
import pl.touk.mockserver.api.response.*
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext
|
||||||
import java.util.concurrent.CopyOnWriteArrayList
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
import java.util.concurrent.CopyOnWriteArraySet
|
import java.util.concurrent.CopyOnWriteArraySet
|
||||||
|
|
||||||
|
@ -17,6 +21,9 @@ class HttpMockServer {
|
||||||
private final List<HttpServerWraper> childServers = new CopyOnWriteArrayList<>()
|
private final List<HttpServerWraper> childServers = new CopyOnWriteArrayList<>()
|
||||||
private final Set<String> mockNames = new CopyOnWriteArraySet<>()
|
private final Set<String> mockNames = new CopyOnWriteArraySet<>()
|
||||||
|
|
||||||
|
private static
|
||||||
|
final JAXBContext requestJaxbContext = JAXBContext.newInstance(AddMock.package.name, AddMock.classLoader)
|
||||||
|
|
||||||
HttpMockServer(int port = 9999) {
|
HttpMockServer(int port = 9999) {
|
||||||
httpServerWraper = new HttpServerWraper(port)
|
httpServerWraper = new HttpServerWraper(port)
|
||||||
|
|
||||||
|
@ -26,12 +33,12 @@ class HttpMockServer {
|
||||||
if (ex.requestMethod == 'GET') {
|
if (ex.requestMethod == 'GET') {
|
||||||
listMocks(ex)
|
listMocks(ex)
|
||||||
} else if (ex.requestMethod == 'POST') {
|
} else if (ex.requestMethod == 'POST') {
|
||||||
GPathResult request = new XmlSlurper().parse(ex.requestBody)
|
MockServerRequest request = requestJaxbContext.createUnmarshaller().unmarshal(ex.requestBody) as MockServerRequest
|
||||||
if (request.name() == 'addMock') {
|
if (request instanceof AddMock) {
|
||||||
addMock(request, ex)
|
addMock(request, ex)
|
||||||
} else if (request.name() == 'removeMock') {
|
} else if (request instanceof RemoveMock) {
|
||||||
removeMock(request, ex)
|
removeMock(request, ex)
|
||||||
} else if (request.name() == 'peekMock') {
|
} else if (request instanceof PeekMock) {
|
||||||
peekMock(request, ex)
|
peekMock(request, ex)
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException('Unknown request')
|
throw new RuntimeException('Unknown request')
|
||||||
|
@ -46,29 +53,26 @@ class HttpMockServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
void listMocks(HttpExchange ex) {
|
void listMocks(HttpExchange ex) {
|
||||||
StringWriter sw = new StringWriter()
|
MockListing mockListing = new MockListing(
|
||||||
MarkupBuilder builder = new MarkupBuilder(sw)
|
mocks: listMocks().collect {
|
||||||
builder.mocks {
|
new MockReport(
|
||||||
listMocks().each {
|
name: it.name,
|
||||||
Mock mock ->
|
path: it.path,
|
||||||
builder.mock {
|
port: it.port,
|
||||||
name mock.name
|
predicate: it.predicateClosureText,
|
||||||
path mock.path
|
response: it.responseClosureText,
|
||||||
port mock.port
|
responseHeaders: it.responseHeadersClosureText
|
||||||
predicate mock.predicateClosureText
|
)
|
||||||
response mock.responseClosureText
|
}
|
||||||
responseHeaders mock.responseHeadersClosureText
|
)
|
||||||
}
|
createResponse(ex, mockListing, 200)
|
||||||
}
|
|
||||||
}
|
|
||||||
createResponse(ex, sw.toString(), 200)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Mock> listMocks() {
|
Set<Mock> listMocks() {
|
||||||
return childServers.collect { it.mocks }.flatten() as TreeSet
|
return childServers.collect { it.mocks }.flatten() as TreeSet<Mock>
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMock(GPathResult request, HttpExchange ex) {
|
private void addMock(AddMock request, HttpExchange ex) {
|
||||||
String name = request.name
|
String name = request.name
|
||||||
if (name in mockNames) {
|
if (name in mockNames) {
|
||||||
throw new RuntimeException('mock already registered')
|
throw new RuntimeException('mock already registered')
|
||||||
|
@ -77,13 +81,13 @@ class HttpMockServer {
|
||||||
HttpServerWraper child = getOrCreateChildServer(mock.port)
|
HttpServerWraper child = getOrCreateChildServer(mock.port)
|
||||||
child.addMock(mock)
|
child.addMock(mock)
|
||||||
mockNames << name
|
mockNames << name
|
||||||
createResponse(ex, '<mockAdded/>', 200)
|
createResponse(ex, new MockAdded(), 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Mock mockFromRequest(GPathResult request) {
|
private static Mock mockFromRequest(AddMock request) {
|
||||||
String name = request.name
|
String name = request.name
|
||||||
String mockPath = request.path
|
String mockPath = request.path
|
||||||
int mockPort = Integer.valueOf(request.port as String)
|
int mockPort = request.port
|
||||||
Mock mock = new Mock(name, mockPath, mockPort)
|
Mock mock = new Mock(name, mockPath, mockPort)
|
||||||
mock.predicate = request.predicate
|
mock.predicate = request.predicate
|
||||||
mock.response = request.response
|
mock.response = request.response
|
||||||
|
@ -103,85 +107,62 @@ class HttpMockServer {
|
||||||
return child
|
return child
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeMock(GPathResult request, HttpExchange ex) {
|
private void removeMock(RemoveMock request, HttpExchange ex) {
|
||||||
String name = request.name
|
String name = request.name
|
||||||
boolean skipReport = Boolean.parseBoolean(request.skipReport?.toString() ?: 'false')
|
boolean skipReport = request.skipReport ?: false
|
||||||
if (!(name in mockNames)) {
|
if (!(name in mockNames)) {
|
||||||
throw new RuntimeException('mock not registered')
|
throw new RuntimeException('mock not registered')
|
||||||
}
|
}
|
||||||
log.info("Removing mock $name")
|
log.info("Removing mock $name")
|
||||||
List<MockEvent> mockEvents = skipReport ? [] : childServers.collect { it.removeMock(name) }.flatten()
|
List<MockEvent> mockEvents = skipReport ? [] : childServers.collect {
|
||||||
|
it.removeMock(name)
|
||||||
|
}.flatten() as List<MockEvent>
|
||||||
mockNames.remove(name)
|
mockNames.remove(name)
|
||||||
createResponse(ex, createMockRemovedResponse(mockEvents), 200)
|
MockRemoved mockRemoved = new MockRemoved(
|
||||||
|
mockEvents: createMockEventReports(mockEvents)
|
||||||
|
)
|
||||||
|
createResponse(ex, mockRemoved, 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
private void peekMock(GPathResult request, HttpExchange ex) {
|
private static List<MockEventReport> createMockEventReports(List<MockEvent> mockEvents) {
|
||||||
|
return mockEvents.collect {
|
||||||
|
new MockEventReport(
|
||||||
|
request: new MockRequestReport(
|
||||||
|
text: it.request.text,
|
||||||
|
headers: it.request.headers.collect {
|
||||||
|
new Parameter(name: it.key, value: it.value)
|
||||||
|
},
|
||||||
|
queryParams: it.request.query.collect {
|
||||||
|
new Parameter(name: it.key, value: it.value)
|
||||||
|
},
|
||||||
|
paths: it.request.path
|
||||||
|
),
|
||||||
|
response: new MockResponseReport(
|
||||||
|
statusCode: it.response.statusCode,
|
||||||
|
text: it.response.text,
|
||||||
|
headers: it.response.headers.collect {
|
||||||
|
new Parameter(name: it.key, value: it.value)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void peekMock(PeekMock request, HttpExchange ex) {
|
||||||
String name = request.name
|
String name = request.name
|
||||||
if (!(name in mockNames)) {
|
if (!(name in mockNames)) {
|
||||||
throw new RuntimeException('mock not registered')
|
throw new RuntimeException('mock not registered')
|
||||||
}
|
}
|
||||||
log.trace("Peeking mock $name")
|
log.trace("Peeking mock $name")
|
||||||
List<MockEvent> mockEvents = childServers.collect { it.peekMock(name) }.flatten()
|
List<MockEvent> mockEvents = childServers.collect { it.peekMock(name) }.flatten() as List<MockEvent>
|
||||||
createResponse(ex, createMockPeekedResponse(mockEvents), 200)
|
MockPeeked mockPeeked = new MockPeeked(
|
||||||
}
|
mockEvents: createMockEventReports(mockEvents)
|
||||||
|
)
|
||||||
private static String createMockRemovedResponse(List<MockEvent> mockEvents) {
|
createResponse(ex, mockPeeked, 200)
|
||||||
StringWriter sw = new StringWriter()
|
|
||||||
MarkupBuilder builder = new MarkupBuilder(sw)
|
|
||||||
builder.mockRemoved {
|
|
||||||
mockEventsToXml(mockEvents, builder)
|
|
||||||
}
|
|
||||||
return sw.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String createMockPeekedResponse(List<MockEvent> mockEvents) {
|
|
||||||
StringWriter sw = new StringWriter()
|
|
||||||
MarkupBuilder builder = new MarkupBuilder(sw)
|
|
||||||
builder.mockPeeked {
|
|
||||||
mockEventsToXml(mockEvents, builder)
|
|
||||||
}
|
|
||||||
return sw.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void mockEventsToXml(List<MockEvent> events, MarkupBuilder builder) {
|
|
||||||
events.each { MockEvent event ->
|
|
||||||
builder.mockEvent {
|
|
||||||
builder.request {
|
|
||||||
text event.request.text
|
|
||||||
headers {
|
|
||||||
event.request.headers.each {
|
|
||||||
builder.param(name: it.key, it.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
query {
|
|
||||||
event.request.query.each {
|
|
||||||
builder.param(name: it.key, it.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path {
|
|
||||||
event.request.path.each {
|
|
||||||
builder.elem it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
builder.response {
|
|
||||||
text event.response.text
|
|
||||||
headers {
|
|
||||||
event.response.headers.each {
|
|
||||||
builder.param(name: it.key, it.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
statusCode event.response.statusCode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void createErrorResponse(HttpExchange ex, Exception e) {
|
private static void createErrorResponse(HttpExchange ex, Exception e) {
|
||||||
StringWriter sw = new StringWriter()
|
createResponse(ex, new ExceptionOccured(message: e.message), 400)
|
||||||
MarkupBuilder builder = new MarkupBuilder(sw)
|
|
||||||
builder.exceptionOccured e.message
|
|
||||||
createResponse(ex, sw.toString(), 400)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop() {
|
void stop() {
|
||||||
|
|
|
@ -1,14 +1,32 @@
|
||||||
package pl.touk.mockserver.server
|
package pl.touk.mockserver.server
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange
|
import com.sun.net.httpserver.HttpExchange
|
||||||
|
import pl.touk.mockserver.api.response.MockAdded
|
||||||
|
|
||||||
|
import javax.xml.bind.JAXBContext
|
||||||
|
|
||||||
class Util {
|
class Util {
|
||||||
static void createResponse(HttpExchange ex, String response, int statusCode) {
|
|
||||||
byte[] responseBytes = response ? response.getBytes('UTF-8') : new byte[0]
|
private static
|
||||||
|
final JAXBContext responseJaxbContext = JAXBContext.newInstance(MockAdded.package.name, MockAdded.classLoader)
|
||||||
|
|
||||||
|
static void createResponse(HttpExchange ex, Object response, int statusCode) {
|
||||||
|
String responseString = marshall(response)
|
||||||
|
createResponse(ex, responseString, statusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createResponse(HttpExchange ex, String responseString, int statusCode) {
|
||||||
|
byte[] responseBytes = responseString ? responseString.getBytes('UTF-8') : new byte[0]
|
||||||
ex.sendResponseHeaders(statusCode, responseBytes.length ?: -1)
|
ex.sendResponseHeaders(statusCode, responseBytes.length ?: -1)
|
||||||
if (response) {
|
if (responseString) {
|
||||||
ex.responseBody << responseBytes
|
ex.responseBody << responseBytes
|
||||||
ex.responseBody.close()
|
ex.responseBody.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String marshall(Object response) {
|
||||||
|
StringWriter sw = new StringWriter()
|
||||||
|
responseJaxbContext.createMarshaller().marshal(response, sw)
|
||||||
|
return sw.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
12
pom.xml
12
pom.xml
|
@ -10,6 +10,7 @@
|
||||||
<module>mockserver-client</module>
|
<module>mockserver-client</module>
|
||||||
<module>mockserver</module>
|
<module>mockserver</module>
|
||||||
<module>mockserver-tests</module>
|
<module>mockserver-tests</module>
|
||||||
|
<module>mockserver-api</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
<commons-lang3.version>3.3.2</commons-lang3.version>
|
<commons-lang3.version>3.3.2</commons-lang3.version>
|
||||||
<slf4j-api.version>1.7.7</slf4j-api.version>
|
<slf4j-api.version>1.7.7</slf4j-api.version>
|
||||||
<logback-classic.version>1.0.13</logback-classic.version>
|
<logback-classic.version>1.0.13</logback-classic.version>
|
||||||
|
<lombok.version>1.16.6</lombok.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
|
@ -63,6 +65,16 @@
|
||||||
<artifactId>logback-classic</artifactId>
|
<artifactId>logback-classic</artifactId>
|
||||||
<version>${logback-classic.version}</version>
|
<version>${logback-classic.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.touk.mockserver</groupId>
|
||||||
|
<artifactId>mockserver-api</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue