1616
1717package org .springframework .cloud .contract .verifier .wiremock ;
1818
19- import java .io .IOException ;
2019import java .util .ArrayList ;
20+ import java .util .Collection ;
2121import java .util .Iterator ;
2222import java .util .List ;
2323import java .util .Map ;
24- import java .util .stream .StreamSupport ;
25-
26- import com .fasterxml .jackson .core .JsonParser ;
27- import com .fasterxml .jackson .core .JsonPointer ;
28- import com .fasterxml .jackson .core .util .DefaultIndenter ;
29- import com .fasterxml .jackson .core .util .DefaultPrettyPrinter ;
30- import com .fasterxml .jackson .core .util .Separators ;
31- import com .fasterxml .jackson .databind .JsonNode ;
32- import com .fasterxml .jackson .databind .ObjectMapper ;
33- import com .fasterxml .jackson .databind .node .ArrayNode ;
34- import com .fasterxml .jackson .databind .node .IntNode ;
35- import com .fasterxml .jackson .databind .node .ObjectNode ;
36- import com .fasterxml .jackson .databind .node .TextNode ;
24+ import java .util .Set ;
25+
3726import repackaged .nl .flotsam .xeger .Xeger ;
27+ import tools .jackson .core .JsonPointer ;
28+ import tools .jackson .core .util .DefaultIndenter ;
29+ import tools .jackson .core .util .DefaultPrettyPrinter ;
30+ import tools .jackson .databind .JsonNode ;
31+ import tools .jackson .databind .json .JsonMapper ;
32+ import tools .jackson .databind .node .ArrayNode ;
33+ import tools .jackson .databind .node .IntNode ;
34+ import tools .jackson .databind .node .ObjectNode ;
35+ import tools .jackson .databind .node .StringNode ;
3836
3937import static org .apache .commons .text .StringEscapeUtils .escapeJava ;
38+ import static tools .jackson .core .json .JsonReadFeature .ALLOW_JAVA_COMMENTS ;
39+ import static tools .jackson .core .json .JsonReadFeature .ALLOW_SINGLE_QUOTES ;
40+ import static tools .jackson .core .json .JsonReadFeature .ALLOW_UNQUOTED_PROPERTY_NAMES ;
41+ import static tools .jackson .core .json .JsonReadFeature .ALLOW_YAML_COMMENTS ;
4042
4143/**
4244 * Converts WireMock stubs into the DSL format.
@@ -69,14 +71,13 @@ public class WireMockToDslConverter {
6971
7072 private static final JsonPointer RESPONSE_HEADERS_POINTER = JsonPointer .compile ("/response/headers" );
7173
72- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper ();
73-
74- static {
75- OBJECT_MAPPER .configure (JsonParser .Feature .ALLOW_COMMENTS , true );
76- OBJECT_MAPPER .configure (JsonParser .Feature .ALLOW_YAML_COMMENTS , true );
77- OBJECT_MAPPER .configure (JsonParser .Feature .ALLOW_UNQUOTED_FIELD_NAMES , true );
78- OBJECT_MAPPER .configure (JsonParser .Feature .ALLOW_SINGLE_QUOTES , true );
79- }
74+ private static final JsonMapper OBJECT_MAPPER = JsonMapper
75+ .builder ()
76+ .configure (ALLOW_JAVA_COMMENTS , true )
77+ .configure (ALLOW_YAML_COMMENTS , true )
78+ .configure (ALLOW_UNQUOTED_PROPERTY_NAMES , true )
79+ .configure (ALLOW_SINGLE_QUOTES , true )
80+ .build ();
8081
8182 /**
8283 * Returns the string content of the contract.
@@ -100,7 +101,7 @@ private JsonNode parseStubDefinition(String wireMockStringStub) {
100101 try {
101102 return OBJECT_MAPPER .reader ().readTree (wireMockStringStub );
102103 }
103- catch (IOException e ) {
104+ catch (Exception e ) {
104105 throw new RuntimeException ("WireMock string stub could not be read" , e );
105106 }
106107 }
@@ -169,13 +170,19 @@ private String buildRequestHeaders(JsonNode wireMockStub) {
169170
170171 if (requestHeadersNode .isObject ()) {
171172 requestHeadersBuilder .append ("headers {\n " );
172- ObjectNode requestHeadersObjectNode = requestHeadersNode .deepCopy ();
173- Iterator <Map .Entry <String , JsonNode >> fields = requestHeadersObjectNode .fields ();
174- fields .forEachRemaining (c -> {
173+ JsonNode requestHeadersObjectNode = requestHeadersNode .deepCopy ();
174+ Set <Map .Entry <String , JsonNode >> fields = requestHeadersObjectNode .properties ();
175+ fields .forEach (c -> {
175176 requestHeadersBuilder .append ("header('" ).append (c .getKey ()).append ("'," );
176- Map .Entry <String , JsonNode > headerValue = c .getValue ().deepCopy ().fields ().next ();
177- String header = buildHeader (headerValue .getKey (), headerValue .getValue ().asText ());
178- requestHeadersBuilder .append (header ).append (")" ).append ("\n " );
177+ ObjectNode headersNode = (ObjectNode ) c .getValue ().deepCopy ();
178+ Iterator <Map .Entry <String , JsonNode >> headersNodeIterator = headersNode .properties ()
179+ .iterator ();
180+ if (headersNodeIterator .hasNext ()) {
181+ Map .Entry <String , JsonNode > headerValue = headersNodeIterator .next ();
182+ String header = buildHeader (headerValue .getKey (), headerValue .getValue ()
183+ .asString ());
184+ requestHeadersBuilder .append (header ).append (")" ).append ("\n " );
185+ }
179186 });
180187 requestHeadersBuilder .append ("}" );
181188 }
@@ -184,45 +191,48 @@ private String buildRequestHeaders(JsonNode wireMockStub) {
184191
185192 private String buildHeader (String method , String value ) {
186193 switch (method ) {
187- case "equalTo" :
188- return "'" + value + "'" ;
189- case "contains" :
190- String regex = "^.*" + value + ".*$" ;
191- return "c(regex('" + escapeJava (regex ) + "'))" ;
192- default :
193- return "c(regex('" + escapeJava (value ) + "'))" ;
194+ case "equalTo" :
195+ return "'" + value + "'" ;
196+ case "contains" :
197+ String regex = "^.*" + value + ".*$" ;
198+ return "c(regex('" + escapeJava (regex ) + "'))" ;
199+ default :
200+ return "c(regex('" + escapeJava (value ) + "'))" ;
194201 }
195202 }
196203
197204 private String buildRequestBody (JsonNode wireMockStub ) {
198205 final StringBuilder requestBody = new StringBuilder ();
199206 JsonNode requestBodyNode = wireMockStub .at (REQUEST_BODY_POINTER );
200207 if (requestBodyNode .isArray ()) {
201- ArrayNode requestBodyArrayNode = requestBodyNode .deepCopy ();
202- Iterator <JsonNode > elements = requestBodyArrayNode .elements ();
203- Iterable <JsonNode > iterableFields = () -> elements ;
208+ ArrayNode requestBodyArrayNode = (ArrayNode ) requestBodyNode .deepCopy ();
209+ Collection <JsonNode > elements = requestBodyArrayNode .elements ();
204210 List <Map .Entry <String , JsonNode >> requestBodyObjectNodes = new ArrayList <>();
205- StreamSupport .stream (iterableFields .spliterator (), false )
206- .filter (f -> f instanceof ObjectNode )
207- .map (f -> (ObjectNode ) f )
208- .map (ObjectNode ::fields )
209- .forEachOrdered (i -> i .forEachRemaining (requestBodyObjectNodes ::add ));
211+
212+ elements .stream ()
213+ .filter (f -> f instanceof ObjectNode )
214+ .map (f -> (ObjectNode ) f )
215+ .map (ObjectNode ::properties )
216+ .forEachOrdered (requestBodyObjectNodes ::addAll );
210217 requestBodyObjectNodes .stream ()
211- .filter (b -> b .getKey ().equals ("equalTo" ))
212- .findFirst ()
213- .ifPresent (b -> requestBody .append ("body ('" ).append (b .getValue ().asText ()).append ("')" ));
218+ .filter (b -> b .getKey ().equals ("equalTo" ))
219+ .findFirst ()
220+ .ifPresent (b -> requestBody .append ("body ('" )
221+ .append (b .getValue ().asString ()).append ("')" ));
214222 requestBodyObjectNodes .stream ()
215- .filter (b -> b .getKey ().equals ("equalToJson" ))
216- .findFirst ()
217- .ifPresent (b -> requestBody .append ("body ('" ).append (b .getValue ().asText ()).append ("')" ));
223+ .filter (b -> b .getKey ().equals ("equalToJson" ))
224+ .findFirst ()
225+ .ifPresent (b -> requestBody .append ("body ('" )
226+ .append (b .getValue ().asString ()).append ("')" ));
218227 requestBodyObjectNodes .stream ()
219- .filter (b -> b .getKey ().equals ("matches" ))
220- .findFirst ()
221- .ifPresent (b -> requestBody .append ("body $(consumer(regex('" )
222- .append (escapeJava (b .getValue ().asText ()))
223- .append ("')), producer('" )
224- .append (new Xeger (escapeJava (b .getValue ().asText ())).generate ())
225- .append ("'))" ));
228+ .filter (b -> b .getKey ().equals ("matches" ))
229+ .findFirst ()
230+ .ifPresent (b -> requestBody .append ("body $(consumer(regex('" )
231+ .append (escapeJava (b .getValue ().asString ()))
232+ .append ("')), producer('" )
233+ .append (new Xeger (escapeJava (b .getValue ()
234+ .asString ())).generate ())
235+ .append ("'))" ));
226236 }
227237 return requestBody .toString ();
228238 }
@@ -243,8 +253,8 @@ private String buildResponseBody(JsonNode wireMockStub) {
243253 if (responseBodyNode .isInt ()) {
244254 responseBody += "body( " + escapeJava (buildPrettyPrintResponseBody ((IntNode ) responseBodyNode )) + ")\n " ;
245255 }
246- if (responseBodyNode .isTextual ()) {
247- responseBody += "body( \" " + escapeJava (buildPrettyPrintResponseBody ((TextNode ) responseBodyNode ))
256+ if (responseBodyNode .isString ()) {
257+ responseBody += "body( \" " + escapeJava (buildPrettyPrintResponseBody ((StringNode ) responseBodyNode ))
248258 + "\" )\n " ;
249259 }
250260 return responseBody ;
@@ -254,17 +264,22 @@ private String buildPrettyPrintResponseBody(IntNode node) {
254264 return node .asText ();
255265 }
256266
257- private String buildPrettyPrintResponseBody (TextNode node ) {
267+ private String buildPrettyPrintResponseBody (StringNode node ) {
258268 try {
259- String textNode = node .asText ();
260- Object intermediateObjectForPrettyPrinting = OBJECT_MAPPER .reader ().readValue (textNode , Object .class );
269+ String stringNode = node .asText ();
270+ Object intermediateObjectForPrettyPrinting =
271+ OBJECT_MAPPER .readerFor (Object .class ).readValue (stringNode );
272+
261273 DefaultIndenter customIndenter = new DefaultIndenter (" " , "\n " );
262274 return OBJECT_MAPPER
263- .writer (new PrivatePrettyPrinter ().withArrayIndenter (customIndenter ).withObjectIndenter (customIndenter ))
264- .writeValueAsString (intermediateObjectForPrettyPrinting );
275+ .writer ()
276+ .with (new DefaultPrettyPrinter ()
277+ .withArrayIndenter (customIndenter )
278+ .withObjectIndenter (customIndenter ))
279+ .writeValueAsString (intermediateObjectForPrettyPrinting );
265280 }
266- catch (IOException e ) {
267- throw new RuntimeException ("WireMock response body could not be pretty printed" );
281+ catch (Exception e ) {
282+ throw new RuntimeException ("WireMock response body could not be pretty printed" , e );
268283 }
269284 }
270285
@@ -274,33 +289,17 @@ private String buildResponseHeaders(JsonNode wireMockStub) {
274289
275290 if (requestHeadersNode .isObject ()) {
276291 responseHeadersBuilder .append ("headers {\n " );
277- ObjectNode responseHeadersObjectNode = requestHeadersNode .deepCopy ();
278- Iterator <Map .Entry <String , JsonNode >> fields = responseHeadersObjectNode .fields ();
279- fields .forEachRemaining (c -> responseHeadersBuilder .append ("header('" )
280- .append (c .getKey ())
281- .append ("'," )
282- .append ("'" )
283- .append (c .getValue ().asText ())
284- .append ("')\n " ));
292+ JsonNode responseHeadersObjectNode = requestHeadersNode .deepCopy ();
293+ Set <Map .Entry <String , JsonNode >> fields = responseHeadersObjectNode .properties ();
294+ fields .forEach (c -> responseHeadersBuilder .append ("header('" )
295+ .append (c .getKey ())
296+ .append ("'," )
297+ .append ("'" )
298+ .append (c .getValue ().asString ())
299+ .append ("')\n " ));
285300 responseHeadersBuilder .append ("}" );
286301 }
287302 return responseHeadersBuilder .toString ();
288303 }
289304
290- private static class PrivatePrettyPrinter extends DefaultPrettyPrinter {
291-
292- @ Override
293- public DefaultPrettyPrinter createInstance () {
294- return new PrivatePrettyPrinter ();
295- }
296-
297- @ Override
298- public DefaultPrettyPrinter withSeparators (Separators separators ) {
299- _separators = separators ;
300- _objectFieldValueSeparatorWithSpaces = separators .getObjectFieldValueSeparator () + " " ;
301- return this ;
302- }
303-
304- }
305-
306305}
0 commit comments