diff --git a/mockserver-api/pom.xml b/mockserver-api/pom.xml
new file mode 100644
index 0000000..a7c59b9
--- /dev/null
+++ b/mockserver-api/pom.xml
@@ -0,0 +1,20 @@
+
+
+
+ http-mock-server
+ pl.touk.mockserver
+ 1.1.1-SNAPSHOT
+
+ 4.0.0
+
+ mockserver-api
+
+
+
+ org.projectlombok
+ lombok
+
+
+
\ No newline at end of file
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/request/AddMock.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/AddMock.java
new file mode 100644
index 0000000..80ad580
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/AddMock.java
@@ -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;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/request/Method.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/Method.java
new file mode 100644
index 0000000..9e471a1
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/Method.java
@@ -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;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/request/MockServerRequest.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/MockServerRequest.java
new file mode 100644
index 0000000..91c1ba9
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/MockServerRequest.java
@@ -0,0 +1,4 @@
+package pl.touk.mockserver.api.request;
+
+public abstract class MockServerRequest {
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/request/PeekMock.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/PeekMock.java
new file mode 100644
index 0000000..d4f14ca
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/PeekMock.java
@@ -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;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/request/RemoveMock.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/RemoveMock.java
new file mode 100644
index 0000000..49c8b0b
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/RemoveMock.java
@@ -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;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/request/package-info.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/package-info.java
new file mode 100644
index 0000000..6ccf1df
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/request/package-info.java
@@ -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;
\ No newline at end of file
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/ExceptionOccured.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/ExceptionOccured.java
new file mode 100644
index 0000000..a10382b
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/ExceptionOccured.java
@@ -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;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockAdded.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockAdded.java
new file mode 100644
index 0000000..8dc13a9
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockAdded.java
@@ -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 {
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockEventReport.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockEventReport.java
new file mode 100644
index 0000000..faa2497
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockEventReport.java
@@ -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;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockListing.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockListing.java
new file mode 100644
index 0000000..77f5e24
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockListing.java
@@ -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 mocks;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockPeeked.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockPeeked.java
new file mode 100644
index 0000000..a23daae
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockPeeked.java
@@ -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 mockEvents;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockRemoved.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockRemoved.java
new file mode 100644
index 0000000..008d318
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockRemoved.java
@@ -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 mockEvents;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockReport.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockReport.java
new file mode 100644
index 0000000..4ea7449
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockReport.java
@@ -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;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockRequestReport.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockRequestReport.java
new file mode 100644
index 0000000..194b27d
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockRequestReport.java
@@ -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 headers;
+
+ @XmlElementWrapper(name = "query")
+ @XmlElement(name = "param")
+ private List queryParams;
+
+ @XmlElementWrapper(name = "path")
+ @XmlElement(name = "elem")
+ private List paths;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockResponseReport.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockResponseReport.java
new file mode 100644
index 0000000..56ac5d5
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockResponseReport.java
@@ -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 headers;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockServerResponse.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockServerResponse.java
new file mode 100644
index 0000000..bf7e0ae
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/MockServerResponse.java
@@ -0,0 +1,4 @@
+package pl.touk.mockserver.api.response;
+
+public abstract class MockServerResponse {
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/Parameter.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/Parameter.java
new file mode 100644
index 0000000..6a9c0c3
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/Parameter.java
@@ -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;
+}
diff --git a/mockserver-api/src/main/java/pl/touk/mockserver/api/response/package-info.java b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/package-info.java
new file mode 100644
index 0000000..d317cb9
--- /dev/null
+++ b/mockserver-api/src/main/java/pl/touk/mockserver/api/response/package-info.java
@@ -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;
\ No newline at end of file
diff --git a/mockserver-api/src/main/resource/pl/touk/mockserver/api/request/jaxb.index b/mockserver-api/src/main/resource/pl/touk/mockserver/api/request/jaxb.index
new file mode 100644
index 0000000..233becc
--- /dev/null
+++ b/mockserver-api/src/main/resource/pl/touk/mockserver/api/request/jaxb.index
@@ -0,0 +1,4 @@
+AddMock
+Method
+PeekMock
+RemoveMock
\ No newline at end of file
diff --git a/mockserver-api/src/main/resource/pl/touk/mockserver/api/response/jaxb.index b/mockserver-api/src/main/resource/pl/touk/mockserver/api/response/jaxb.index
new file mode 100644
index 0000000..86bdb57
--- /dev/null
+++ b/mockserver-api/src/main/resource/pl/touk/mockserver/api/response/jaxb.index
@@ -0,0 +1,11 @@
+ExceptionOccured
+MockAdded
+MockEventReport
+MockListing
+MockPeeked
+MockRemoved
+MockReport
+MockRequestReport
+MockResponseReport
+MockServerResponse
+Parameter
\ No newline at end of file
diff --git a/mockserver-client/pom.xml b/mockserver-client/pom.xml
index dc604e9..5041602 100644
--- a/mockserver-client/pom.xml
+++ b/mockserver-client/pom.xml
@@ -25,5 +25,9 @@
org.apache.commons
commons-lang3
+
+ pl.touk.mockserver
+ mockserver-api
+
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy
deleted file mode 100644
index 6da9a6e..0000000
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/AddMockRequestData.groovy
+++ /dev/null
@@ -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)
- }
-}
-
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/Method.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/Method.groovy
deleted file mode 100644
index 82aefea..0000000
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/Method.groovy
+++ /dev/null
@@ -1,12 +0,0 @@
-package pl.touk.mockserver.client
-
-enum Method {
- POST,
- GET,
- DELETE,
- PUT,
- TRACE,
- HEAD,
- OPTIONS,
- PATCH
-}
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/MockEvent.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/MockEvent.groovy
deleted file mode 100644
index 8c61ab3..0000000
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/MockEvent.groovy
+++ /dev/null
@@ -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
- }
-}
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/MockRequest.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/MockRequest.groovy
deleted file mode 100644
index c73c11d..0000000
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/MockRequest.groovy
+++ /dev/null
@@ -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 headers
- final Map query
- final List path
-
- MockRequest(String text, Map headers, Map query, List path) {
- this.text = text
- this.headers = headers
- this.query = query
- this.path = path
- }
-}
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/MockResponse.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/MockResponse.groovy
deleted file mode 100644
index 07212fb..0000000
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/MockResponse.groovy
+++ /dev/null
@@ -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 headers
-
- MockResponse(int statusCode, String text, Map headers) {
- this.statusCode = statusCode
- this.text = text
- this.headers = headers
- }
-}
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/PeekMockRequestData.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/PeekMockRequestData.groovy
deleted file mode 100644
index 3d0e546..0000000
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/PeekMockRequestData.groovy
+++ /dev/null
@@ -1,10 +0,0 @@
-package pl.touk.mockserver.client
-
-import groovy.transform.CompileStatic
-import groovy.transform.TypeChecked
-
-@CompileStatic
-@TypeChecked
-class PeekMockRequestData {
- String name
-}
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RegisteredMock.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RegisteredMock.groovy
deleted file mode 100644
index f755592..0000000
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RegisteredMock.groovy
+++ /dev/null
@@ -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
- }
-}
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RemoteMockServer.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RemoteMockServer.groovy
index 6afce3d..14664e0 100644
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RemoteMockServer.groovy
+++ b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RemoteMockServer.groovy
@@ -1,6 +1,5 @@
package pl.touk.mockserver.client
-import groovy.util.slurpersupport.GPathResult
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpGet
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.impl.client.CloseableHttpClient
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 {
private final String address
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) {
address = "http://$host:$port/serverControl"
}
- void addMock(AddMockRequestData addMockRequestData) {
+ void addMock(AddMock addMockData) {
HttpPost addMockPost = new HttpPost(address)
- addMockPost.entity = buildAddMockRequest(addMockRequestData)
+ addMockPost.entity = buildAddMockRequest(addMockData)
CloseableHttpResponse response = client.execute(addMockPost)
- GPathResult responseXml = Util.extractXmlResponse(response)
- if (responseXml.name() != 'mockAdded') {
- if (responseXml.text() == 'mock already registered') {
- throw new MockAlreadyExists()
-
- }
- throw new InvalidMockDefinition(responseXml.text())
- }
+ Util.extractResponse(response)
}
- List removeMock(String name, boolean skipReport = false) {
+ List removeMock(String name, boolean skipReport = false) {
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)
- GPathResult responseXml = Util.extractXmlResponse(response)
- if (responseXml.name() == 'mockRemoved') {
- return responseXml.'mockEvent'.collect {
- new MockEvent(mockRequestFromXml(it.request), mockResponseFromXml(it.response))
- }
- }
- throw new MockDoesNotExist()
+ MockRemoved mockRemoved = Util.extractResponse(response) as MockRemoved
+ return mockRemoved.mockEvents ?: []
}
- List peekMock(String name) {
+ List peekMock(String name) {
HttpPost removeMockPost = new HttpPost(address)
- removeMockPost.entity = buildPeekMockRequest(new PeekMockRequestData(name: name))
+ removeMockPost.entity = buildPeekMockRequest(new PeekMock(name: name))
CloseableHttpResponse response = client.execute(removeMockPost)
- GPathResult responseXml = Util.extractXmlResponse(response)
- if (responseXml.name() == 'mockPeeked') {
- return responseXml.'mockEvent'.collect {
- new MockEvent(mockRequestFromXml(it.request), mockResponseFromXml(it.response))
- }
- }
- throw new MockDoesNotExist()
+ MockPeeked mockPeeked = Util.extractResponse(response) as MockPeeked
+ return mockPeeked.mockEvents ?: []
}
- private static MockResponse mockResponseFromXml(GPathResult xml) {
- return new MockResponse(xml.statusCode.text() as int, xml.text.text(), xml.headers.param.collectEntries {
- [(it.@name.text()): it.text()]
- })
+ private static StringEntity buildRemoveMockRequest(RemoveMock data) {
+ return new StringEntity(marshallRequest(data), ContentType.create("text/xml", "UTF-8"))
}
- private static MockRequest mockRequestFromXml(GPathResult xml) {
- return new MockRequest(
- xml.text.text(),
- xml.headers.param.collectEntries { [(it.@name.text()): it.text()] },
- xml.query.param.collectEntries { [(it.@name.text()): it.text()] },
- xml.path.elem*.text()
- )
+ private static String marshallRequest(MockServerRequest data) {
+ StringWriter sw = new StringWriter()
+ requestContext.createMarshaller().marshal(data, sw)
+ return sw.toString()
}
- private static StringEntity buildRemoveMockRequest(RemoveMockRequestData data) {
- return new StringEntity("""\
-
- ${data.name}
- ${data.skipReport}
-
- """, ContentType.create("text/xml", "UTF-8"))
+ private static StringEntity buildPeekMockRequest(PeekMock peekMock) {
+ return new StringEntity(marshallRequest(peekMock), ContentType.create("text/xml", "UTF-8"))
}
- private static StringEntity buildPeekMockRequest(PeekMockRequestData data) {
- return new StringEntity("""\
-
- ${data.name}
-
- """, ContentType.create("text/xml", "UTF-8"))
+ private static StringEntity buildAddMockRequest(AddMock data) {
+ return new StringEntity(marshallRequest(data), ContentType.create("text/xml", "UTF-8"))
}
- private static StringEntity buildAddMockRequest(AddMockRequestData data) {
- return new StringEntity("""\
-
- ${data.name}
- ${data.path}
- ${data.port}
- ${data.predicate ? "${data.predicate}" : ''}
- ${data.response ? "${data.response}" : ''}
- ${data.soap != null ? "${data.soap}" : ''}
- ${data.statusCode ? "${data.statusCode}" : ''}
- ${data.method ? "${data.method}" : ''}
- ${data.responseHeaders ? "${data.responseHeaders}" : ''}
-
- """, ContentType.create("text/xml", "UTF-8"))
- }
-
- List listMocks() {
+ List listMocks() {
HttpGet get = new HttpGet(address)
CloseableHttpResponse response = client.execute(get)
- GPathResult xml = Util.extractXmlResponse(response)
- if (xml.name() == '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 []
+ MockListing mockListing = Util.extractResponse(response) as MockListing
+ return mockListing.mocks
}
}
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RemoveMockRequestData.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RemoveMockRequestData.groovy
deleted file mode 100644
index 1d37545..0000000
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/RemoveMockRequestData.groovy
+++ /dev/null
@@ -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
-}
diff --git a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/Util.groovy b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/Util.groovy
index 8cffc3b..446ebf0 100644
--- a/mockserver-client/src/main/groovy/pl/touk/mockserver/client/Util.groovy
+++ b/mockserver-client/src/main/groovy/pl/touk/mockserver/client/Util.groovy
@@ -7,15 +7,42 @@ import groovy.util.slurpersupport.GPathResult
import org.apache.http.HttpEntity
import org.apache.http.client.methods.CloseableHttpResponse
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
@TypeChecked
class Util {
+ private static
+ final JAXBContext responseContext = JAXBContext.newInstance(MockAdded.package.name, MockAdded.classLoader)
+
static GPathResult extractXmlResponse(CloseableHttpResponse response) {
+ return new XmlSlurper().parseText(extractStringResponse(response))
+ }
+ static String extractStringResponse(CloseableHttpResponse response) {
HttpEntity entity = response.entity
- GPathResult xml = new XmlSlurper().parseText(EntityUtils.toString(entity, 'UTF-8'))
+ String responseString = EntityUtils.toString(entity, 'UTF-8')
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) {
@@ -26,13 +53,11 @@ class Util {
}
static Object extractJsonResponse(CloseableHttpResponse response) {
- HttpEntity entity = response.entity
- Object json = new JsonSlurper().parseText(EntityUtils.toString(entity, 'UTF-8'))
- EntityUtils.consumeQuietly(entity)
- return json
+ return new JsonSlurper().parseText(extractStringResponse(response))
}
static void consumeResponse(CloseableHttpResponse response) {
EntityUtils.consumeQuietly(response.entity)
}
+
}
diff --git a/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/MockServerIntegrationTest.groovy b/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/MockServerIntegrationTest.groovy
index 7790522..1fba403 100644
--- a/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/MockServerIntegrationTest.groovy
+++ b/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/MockServerIntegrationTest.groovy
@@ -7,6 +7,11 @@ import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
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.server.HttpMockServer
import spock.lang.Shared
@@ -33,7 +38,7 @@ class MockServerIntegrationTest extends Specification {
def "should add working rest mock on endpoint"() {
expect:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
@@ -54,7 +59,7 @@ class MockServerIntegrationTest extends Specification {
def "should add working rest mock on endpoint with utf"() {
expect:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRestUtf',
path: 'testEndpoint',
port: 9999,
@@ -76,7 +81,7 @@ class MockServerIntegrationTest extends Specification {
def "should add soap mock on endpoint"() {
expect:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testSoap',
path: 'testEndpoint',
port: 9999,
@@ -102,7 +107,7 @@ class MockServerIntegrationTest extends Specification {
then:
thrown(MockDoesNotExist)
expect:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testSoap',
path: 'testEndpoint',
port: 9999,
@@ -120,7 +125,7 @@ class MockServerIntegrationTest extends Specification {
def "should not add mock with existing name"() {
expect:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testSoap',
path: 'testEndpoint',
port: 9999,
@@ -129,7 +134,7 @@ class MockServerIntegrationTest extends Specification {
soap: true
))
when:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testSoap',
path: 'testEndpoint2',
port: 9998,
@@ -143,7 +148,7 @@ class MockServerIntegrationTest extends Specification {
def "should not add mock with empty name"() {
when:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: '',
path: 'testEndpoint2',
port: 9998,
@@ -157,7 +162,7 @@ class MockServerIntegrationTest extends Specification {
def "should add mock after deleting old mock with the same name"() {
expect:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testSoap',
path: 'testEndpoint',
port: 9999,
@@ -168,7 +173,7 @@ class MockServerIntegrationTest extends Specification {
and:
remoteMockServer.removeMock('testSoap') == []
and:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testSoap',
path: 'testEndpoint',
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"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
predicate: '''{req -> req.xml.name() == 'request'}''',
response: '''{req -> ""}'''
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testSoap',
path: 'testEndpoint',
port: 9999,
@@ -215,14 +220,14 @@ class MockServerIntegrationTest extends Specification {
@Unroll
def "should dispatch rest mocks when second on #name"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest1',
path: 'test1',
port: 9999,
predicate: '''{req -> req.xml.name() == 'request1'}''',
response: '''{req -> ""}'''
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: secondPath,
port: secondPort,
@@ -254,7 +259,7 @@ class MockServerIntegrationTest extends Specification {
@Unroll
def "should dispatch rest mock with response code"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest1',
path: 'test1',
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"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest1',
path: 'test1',
port: 9999,
@@ -295,7 +300,7 @@ class MockServerIntegrationTest extends Specification {
def "should inform that there was problem during adding mock - invalid port"() {
when:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testSoap',
path: 'testEndpoint2',
port: -1,
@@ -309,13 +314,13 @@ class MockServerIntegrationTest extends Specification {
def "should dispatch rest mock with get method"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
response: '''{_ -> ""}'''
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'testEndpoint',
port: 9999,
@@ -332,13 +337,13 @@ class MockServerIntegrationTest extends Specification {
def "should dispatch rest mock with trace method"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
response: '''{_ -> ""}'''
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'testEndpoint',
port: 9999,
@@ -355,13 +360,13 @@ class MockServerIntegrationTest extends Specification {
def "should dispatch rest mock with head method"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
response: '''{_ -> ""}'''
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'testEndpoint',
port: 9999,
@@ -377,13 +382,13 @@ class MockServerIntegrationTest extends Specification {
def "should dispatch rest mock with options method"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
response: '''{_ -> ""}'''
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'testEndpoint',
port: 9999,
@@ -399,13 +404,13 @@ class MockServerIntegrationTest extends Specification {
def "should dispatch rest mock with put method"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'test1',
port: 9999,
response: '''{_ -> ""}'''
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'test1',
port: 9999,
@@ -424,13 +429,13 @@ class MockServerIntegrationTest extends Specification {
def "should dispatch rest mock with delete method"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'test1',
port: 9999,
response: '''{_ -> ""}'''
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'test1',
port: 9999,
@@ -447,13 +452,13 @@ class MockServerIntegrationTest extends Specification {
def "should dispatch rest mock with patch method"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'test1',
port: 9999,
response: '''{_ -> ""}'''
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'test1',
port: 9999,
@@ -472,7 +477,7 @@ class MockServerIntegrationTest extends Specification {
def "should add mock that return headers"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
@@ -492,7 +497,7 @@ class MockServerIntegrationTest extends Specification {
def "should add mock that accepts only when certain request headers exists"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
@@ -521,7 +526,7 @@ class MockServerIntegrationTest extends Specification {
def "should add mock that accepts only when certain query params exists"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
@@ -545,7 +550,7 @@ class MockServerIntegrationTest extends Specification {
def "should add mock that accepts only when request has specific body"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
@@ -570,7 +575,7 @@ class MockServerIntegrationTest extends Specification {
def "should add mock which response json to json"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
@@ -595,7 +600,7 @@ class MockServerIntegrationTest extends Specification {
def "should get list mocks"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'testEndpoint',
port: 9998,
@@ -603,27 +608,27 @@ class MockServerIntegrationTest extends Specification {
response: '''{ req -> '' }''',
responseHeaders: '{ _ -> [a: "b"] }'
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest4',
path: 'testEndpoint',
port: 9999
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest3',
path: 'testEndpoint2',
port: 9999
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest5',
path: 'testEndpoint',
port: 9999
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest6',
path: 'testEndpoint2',
port: 9999
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999
@@ -631,17 +636,17 @@ class MockServerIntegrationTest extends Specification {
remoteMockServer.removeMock('testRest5')
expect:
remoteMockServer.listMocks() == [
- new RegisteredMock('testRest', 'testEndpoint', 9999, '{ _ -> true }', '''{ _ -> '' }''', '{ _ -> [:] }'),
- new RegisteredMock('testRest2', 'testEndpoint', 9998, '''{ req -> req.xml.name() == 'request1'}''', '''{ req -> '' }''', '{ _ -> [a: "b"] }'),
- new RegisteredMock('testRest3', 'testEndpoint2', 9999, '{ _ -> true }', '''{ _ -> '' }''', '{ _ -> [:] }'),
- new RegisteredMock('testRest4', 'testEndpoint', 9999, '{ _ -> true }', '''{ _ -> '' }''', '{ _ -> [:] }'),
- new RegisteredMock('testRest6', 'testEndpoint2', 9999, '{ _ -> true }', '''{ _ -> '' }''', '{ _ -> [:] }')
+ new MockReport(name: 'testRest', path: 'testEndpoint', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }'),
+ new MockReport(name: 'testRest2', path: 'testEndpoint', port: 9998, predicate: '''{ req -> req.xml.name() == 'request1'}''', response: '''{ req -> '' }''', responseHeaders: '{ _ -> [a: "b"] }'),
+ new MockReport(name: 'testRest3', path: 'testEndpoint2', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }'),
+ new MockReport(name: 'testRest4', path: 'testEndpoint', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }'),
+ new MockReport(name: 'testRest6', path: 'testEndpoint2', port: 9999, predicate: '{ _ -> true }', response: '''{ _ -> '' }''', responseHeaders: '{ _ -> [:] }')
]
}
def "should add mock accepts path certain path params"() {
given:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
@@ -664,7 +669,7 @@ class MockServerIntegrationTest extends Specification {
def "should get mock report when deleting mock"() {
expect:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
@@ -674,7 +679,7 @@ class MockServerIntegrationTest extends Specification {
responseHeaders: '''{req -> ['aaa':'14']}''',
soap: false
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'testEndpoint',
port: 9999,
@@ -706,40 +711,40 @@ class MockServerIntegrationTest extends Specification {
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
restPostResponse3.name() == 'goodResponseRest'
when:
- List mockEvents1 = remoteMockServer.removeMock('testRest')
+ List mockEvents1 = remoteMockServer.removeMock('testRest')
then:
mockEvents1.size() == 2
mockEvents1[0].request.text == ''
- !mockEvents1[0].request.headers?.keySet()?.empty
- mockEvents1[0].request.query == [:]
- mockEvents1[0].request.path == ['testEndpoint']
- !mockEvents1[0].response.headers?.keySet()?.empty
+ !mockEvents1[0].request.headers?.empty
+ mockEvents1[0].request.queryParams == []
+ mockEvents1[0].request.paths == ['testEndpoint']
+ !mockEvents1[0].response.headers?.empty
mockEvents1[0].response.text == ''
mockEvents1[0].response.statusCode == 201
mockEvents1[1].request.text == ''
- !mockEvents1[1].request.headers?.keySet()?.empty
- mockEvents1[1].request.query == [:]
- mockEvents1[1].request.path == ['testEndpoint', 'hello']
- !mockEvents1[1].response.headers?.keySet()?.empty
+ !mockEvents1[1].request.headers?.empty
+ mockEvents1[1].request.queryParams == []
+ mockEvents1[1].request.paths == ['testEndpoint', 'hello']
+ !mockEvents1[1].response.headers?.empty
mockEvents1[1].response.text == ''
mockEvents1[1].response.statusCode == 201
when:
- List mockEvents2 = remoteMockServer.removeMock('testRest2')
+ List mockEvents2 = remoteMockServer.removeMock('testRest2')
then:
mockEvents2.size() == 1
mockEvents2[0].request.text == ''
- !mockEvents2[0].request.headers?.keySet()?.empty
- mockEvents2[0].request.query == [id: '123']
- mockEvents2[0].request.path == ['testEndpoint']
- mockEvents2[0].response.headers.aaa == '15'
+ !mockEvents2[0].request.headers?.empty
+ mockEvents2[0].request.queryParams == [new Parameter(name: 'id', value: '123')]
+ mockEvents2[0].request.paths == ['testEndpoint']
+ mockEvents2[0].response.headers.find { it.name == 'aaa' }?.value == '15'
mockEvents2[0].response.text == ''
mockEvents2[0].response.statusCode == 202
}
def "should get mock report when peeking mock"() {
expect:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
@@ -749,7 +754,7 @@ class MockServerIntegrationTest extends Specification {
responseHeaders: '''{req -> ['aaa':'14']}''',
soap: false
))
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest2',
path: 'testEndpoint',
port: 9999,
@@ -781,33 +786,33 @@ class MockServerIntegrationTest extends Specification {
GPathResult restPostResponse3 = Util.extractXmlResponse(response3)
restPostResponse3.name() == 'goodResponseRest'
when:
- List mockEvents1 = remoteMockServer.peekMock('testRest')
+ List mockEvents1 = remoteMockServer.peekMock('testRest')
then:
mockEvents1.size() == 2
mockEvents1[0].request.text == ''
- !mockEvents1[0].request.headers?.keySet()?.empty
- mockEvents1[0].request.query == [:]
- mockEvents1[0].request.path == ['testEndpoint']
- !mockEvents1[0].response.headers?.keySet()?.empty
+ !mockEvents1[0].request.headers?.empty
+ mockEvents1[0].request.queryParams == []
+ mockEvents1[0].request.paths == ['testEndpoint']
+ !mockEvents1[0].response.headers?.empty
mockEvents1[0].response.text == ''
mockEvents1[0].response.statusCode == 201
mockEvents1[1].request.text == ''
- !mockEvents1[1].request.headers?.keySet()?.empty
- mockEvents1[1].request.query == [:]
- mockEvents1[1].request.path == ['testEndpoint', 'hello']
- !mockEvents1[1].response.headers?.keySet()?.empty
+ !mockEvents1[1].request.headers?.empty
+ mockEvents1[1].request.queryParams == []
+ mockEvents1[1].request.paths == ['testEndpoint', 'hello']
+ !mockEvents1[1].response.headers?.empty
mockEvents1[1].response.text == ''
mockEvents1[1].response.statusCode == 201
when:
- List mockEvents2 = remoteMockServer.peekMock('testRest2')
+ List mockEvents2 = remoteMockServer.peekMock('testRest2')
then:
mockEvents2.size() == 1
mockEvents2[0].request.text == ''
- !mockEvents2[0].request.headers?.keySet()?.empty
- mockEvents2[0].request.query == [id: '123']
- mockEvents2[0].request.path == ['testEndpoint']
- mockEvents2[0].response.headers.aaa == '15'
+ !mockEvents2[0].request.headers?.empty
+ mockEvents2[0].request.queryParams == [new Parameter(name: 'id', value: '123')]
+ mockEvents2[0].request.paths == ['testEndpoint']
+ mockEvents2[0].response.headers.find {it.name == 'aaa'}?.value == '15'
mockEvents2[0].response.text == ''
mockEvents2[0].response.statusCode == 202
}
@@ -815,7 +820,7 @@ class MockServerIntegrationTest extends Specification {
@Unroll
def "should return mock report with #mockEvents events when deleting mock with flag skip mock = #skipReport"() {
expect:
- remoteMockServer.addMock(new AddMockRequestData(
+ remoteMockServer.addMock(new AddMock(
name: 'testRest',
path: 'testEndpoint',
port: 9999,
diff --git a/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/ServerMockPT.groovy b/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/ServerMockPT.groovy
index 2ee891c..4ab9e3e 100644
--- a/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/ServerMockPT.groovy
+++ b/mockserver-tests/src/test/groovy/pl/touk/mockserver/tests/ServerMockPT.groovy
@@ -1,34 +1,40 @@
package pl.touk.mockserver.tests
-import groovy.util.slurpersupport.GPathResult
import org.apache.http.client.HttpClient
import org.apache.http.client.methods.CloseableHttpResponse
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.ContentType
import org.apache.http.entity.StringEntity
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.Util
import pl.touk.mockserver.server.HttpMockServer
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 {
+
+ @Timeout(value = 60)
def "should handle many request simultaneously"() {
given:
+ HttpClient client = HttpClients.createDefault()
HttpMockServer httpMockServer = new HttpMockServer()
RemoteMockServer controlServerClient = new RemoteMockServer("localhost", 9999)
- HttpClient client = HttpClients.createDefault()
int requestAmount = 1000
- GPathResult[] responses = new GPathResult[requestAmount]
- Thread[] threads = new Thread[requestAmount]
+ String[] responses = new String[requestAmount]
+ ExecutorService executorService = Executors.newFixedThreadPool(20)
for (int i = 0; i < requestAmount; ++i) {
int current = i
- threads[i] = new Thread({
+ executorService.submit {
int endpointNumber = current % 10
int port = 9000 + (current % 7)
- controlServerClient.addMock(new AddMockRequestData(
+ controlServerClient.addMock(new AddMock(
name: "testRest$current",
path: "testEndpoint$endpointNumber",
port: port,
@@ -38,15 +44,14 @@ class ServerMockPT extends Specification {
HttpPost restPost = new HttpPost("http://localhost:$port/testEndpoint$endpointNumber")
restPost.entity = new StringEntity("", ContentType.create("text/xml", "UTF-8"))
CloseableHttpResponse response = client.execute(restPost)
- responses[current] = Util.extractXmlResponse(response)
- assert controlServerClient.removeMock("testRest$current").size() == 1
- })
+ responses[current] = Util.extractStringResponse(response)
+ assert controlServerClient.removeMock("testRest$current", false).size() == 1
+ }
}
when:
- threads*.start()
- Thread.sleep(60000)
+ executorService.awaitTermination(60, TimeUnit.SECONDS)
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:
httpMockServer.stop()
}
diff --git a/mockserver/pom.xml b/mockserver/pom.xml
index b6ddbb7..6223937 100644
--- a/mockserver/pom.xml
+++ b/mockserver/pom.xml
@@ -26,6 +26,10 @@
org.apache.commons
commons-lang3
+
+ pl.touk.mockserver
+ mockserver-api
+
diff --git a/mockserver/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy b/mockserver/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy
index eae893d..322ec64 100644
--- a/mockserver/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy
+++ b/mockserver/src/main/groovy/pl/touk/mockserver/server/HttpMockServer.groovy
@@ -2,9 +2,13 @@ package pl.touk.mockserver.server
import com.sun.net.httpserver.HttpExchange
import groovy.util.logging.Slf4j
-import groovy.util.slurpersupport.GPathResult
-import groovy.xml.MarkupBuilder
+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
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.CopyOnWriteArraySet
@@ -17,6 +21,9 @@ class HttpMockServer {
private final List childServers = new CopyOnWriteArrayList<>()
private final Set mockNames = new CopyOnWriteArraySet<>()
+ private static
+ final JAXBContext requestJaxbContext = JAXBContext.newInstance(AddMock.package.name, AddMock.classLoader)
+
HttpMockServer(int port = 9999) {
httpServerWraper = new HttpServerWraper(port)
@@ -26,12 +33,12 @@ class HttpMockServer {
if (ex.requestMethod == 'GET') {
listMocks(ex)
} else if (ex.requestMethod == 'POST') {
- GPathResult request = new XmlSlurper().parse(ex.requestBody)
- if (request.name() == 'addMock') {
+ MockServerRequest request = requestJaxbContext.createUnmarshaller().unmarshal(ex.requestBody) as MockServerRequest
+ if (request instanceof AddMock) {
addMock(request, ex)
- } else if (request.name() == 'removeMock') {
+ } else if (request instanceof RemoveMock) {
removeMock(request, ex)
- } else if (request.name() == 'peekMock') {
+ } else if (request instanceof PeekMock) {
peekMock(request, ex)
} else {
throw new RuntimeException('Unknown request')
@@ -46,29 +53,26 @@ class HttpMockServer {
}
void listMocks(HttpExchange ex) {
- StringWriter sw = new StringWriter()
- MarkupBuilder builder = new MarkupBuilder(sw)
- builder.mocks {
- listMocks().each {
- Mock mock ->
- builder.mock {
- name mock.name
- path mock.path
- port mock.port
- predicate mock.predicateClosureText
- response mock.responseClosureText
- responseHeaders mock.responseHeadersClosureText
- }
- }
- }
- createResponse(ex, sw.toString(), 200)
+ MockListing mockListing = new MockListing(
+ mocks: listMocks().collect {
+ new MockReport(
+ name: it.name,
+ path: it.path,
+ port: it.port,
+ predicate: it.predicateClosureText,
+ response: it.responseClosureText,
+ responseHeaders: it.responseHeadersClosureText
+ )
+ }
+ )
+ createResponse(ex, mockListing, 200)
}
Set listMocks() {
- return childServers.collect { it.mocks }.flatten() as TreeSet
+ return childServers.collect { it.mocks }.flatten() as TreeSet
}
- private void addMock(GPathResult request, HttpExchange ex) {
+ private void addMock(AddMock request, HttpExchange ex) {
String name = request.name
if (name in mockNames) {
throw new RuntimeException('mock already registered')
@@ -77,13 +81,13 @@ class HttpMockServer {
HttpServerWraper child = getOrCreateChildServer(mock.port)
child.addMock(mock)
mockNames << name
- createResponse(ex, '', 200)
+ createResponse(ex, new MockAdded(), 200)
}
- private static Mock mockFromRequest(GPathResult request) {
+ private static Mock mockFromRequest(AddMock request) {
String name = request.name
String mockPath = request.path
- int mockPort = Integer.valueOf(request.port as String)
+ int mockPort = request.port
Mock mock = new Mock(name, mockPath, mockPort)
mock.predicate = request.predicate
mock.response = request.response
@@ -103,85 +107,62 @@ class HttpMockServer {
return child
}
- private void removeMock(GPathResult request, HttpExchange ex) {
+ private void removeMock(RemoveMock request, HttpExchange ex) {
String name = request.name
- boolean skipReport = Boolean.parseBoolean(request.skipReport?.toString() ?: 'false')
+ boolean skipReport = request.skipReport ?: false
if (!(name in mockNames)) {
throw new RuntimeException('mock not registered')
}
log.info("Removing mock $name")
- List mockEvents = skipReport ? [] : childServers.collect { it.removeMock(name) }.flatten()
+ List mockEvents = skipReport ? [] : childServers.collect {
+ it.removeMock(name)
+ }.flatten() as List
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 createMockEventReports(List 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
if (!(name in mockNames)) {
throw new RuntimeException('mock not registered')
}
log.trace("Peeking mock $name")
- List mockEvents = childServers.collect { it.peekMock(name) }.flatten()
- createResponse(ex, createMockPeekedResponse(mockEvents), 200)
- }
-
- private static String createMockRemovedResponse(List mockEvents) {
- StringWriter sw = new StringWriter()
- MarkupBuilder builder = new MarkupBuilder(sw)
- builder.mockRemoved {
- mockEventsToXml(mockEvents, builder)
- }
- return sw.toString()
- }
-
- private static String createMockPeekedResponse(List mockEvents) {
- StringWriter sw = new StringWriter()
- MarkupBuilder builder = new MarkupBuilder(sw)
- builder.mockPeeked {
- mockEventsToXml(mockEvents, builder)
- }
- return sw.toString()
- }
-
- private static void mockEventsToXml(List 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
- }
- }
- }
+ List mockEvents = childServers.collect { it.peekMock(name) }.flatten() as List
+ MockPeeked mockPeeked = new MockPeeked(
+ mockEvents: createMockEventReports(mockEvents)
+ )
+ createResponse(ex, mockPeeked, 200)
}
private static void createErrorResponse(HttpExchange ex, Exception e) {
- StringWriter sw = new StringWriter()
- MarkupBuilder builder = new MarkupBuilder(sw)
- builder.exceptionOccured e.message
- createResponse(ex, sw.toString(), 400)
+ createResponse(ex, new ExceptionOccured(message: e.message), 400)
}
void stop() {
diff --git a/mockserver/src/main/groovy/pl/touk/mockserver/server/Util.groovy b/mockserver/src/main/groovy/pl/touk/mockserver/server/Util.groovy
index 93ab7a5..3864afa 100644
--- a/mockserver/src/main/groovy/pl/touk/mockserver/server/Util.groovy
+++ b/mockserver/src/main/groovy/pl/touk/mockserver/server/Util.groovy
@@ -1,14 +1,32 @@
package pl.touk.mockserver.server
import com.sun.net.httpserver.HttpExchange
+import pl.touk.mockserver.api.response.MockAdded
+
+import javax.xml.bind.JAXBContext
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)
- if (response) {
+ if (responseString) {
ex.responseBody << responseBytes
ex.responseBody.close()
}
}
+
+ private static String marshall(Object response) {
+ StringWriter sw = new StringWriter()
+ responseJaxbContext.createMarshaller().marshal(response, sw)
+ return sw.toString()
+ }
}
diff --git a/pom.xml b/pom.xml
index 7bb19e5..223871d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,6 +10,7 @@
mockserver-client
mockserver
mockserver-tests
+ mockserver-api
@@ -22,6 +23,7 @@
3.3.2
1.7.7
1.0.13
+ 1.16.6
@@ -63,6 +65,16 @@
logback-classic
${logback-classic.version}
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ pl.touk.mockserver
+ mockserver-api
+ ${project.version}
+