JsonPathMessageValidator extends AbstractMessageValidator<JsonPathMessageValidationContext> { @Override public void validateMessage(Message receivedMessage, Message controlMessage, TestContext context, JsonPathMessageValidationContext validationContext) throws ValidationException { if (CollectionUtils.isEmpty(validationContext.getJsonPathExpressions())) { return; } if (receivedMessage.getPayload() == null || !StringUtils.hasText(receivedMessage.getPayload(String.class))) { throw new ValidationException("Unable to validate message elements - receive message payload was empty"); } log.debug("Start JSONPath element validation ..."); String jsonPathExpression; try { JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE); Object receivedJson = parser.parse(receivedMessage.getPayload(String.class)); ReadContext readerContext = JsonPath.parse(receivedJson); for (Map.Entry<String, Object> entry : validationContext.getJsonPathExpressions().entrySet()) { Object expectedValue = entry.getValue(); if (expectedValue instanceof String) { expectedValue = context.replaceDynamicContentInString(String.valueOf(expectedValue)); } jsonPathExpression = context.replaceDynamicContentInString(entry.getKey()); Object jsonPathResult = JsonPathUtils.evaluate(readerContext, jsonPathExpression); ValidationUtils.validateValues(jsonPathResult, expectedValue, jsonPathExpression, context); if (log.isDebugEnabled()) { log.debug("Validating element: " + jsonPathExpression + "='" + expectedValue + "': OK."); } } log.info("JSONPath element validation successful: All values OK"); } catch (ParseException e) { throw new CitrusRuntimeException("Failed to parse JSON text", e); } }  @Override void validateMessage(Message receivedMessage, Message controlMessage, TestContext context, JsonPathMessageValidationContext validationContext); @Override boolean supportsMessageType(String messageType, Message message);  }
@Test public void testValidateMessageElementsWithJsonPathSuccessful() { JsonPathMessageValidationContext validationContext = new JsonPathMessageValidationContext.Builder() .expression("$..element.sub-element", "text-value") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$['root']['element']['sub-element']", "text-value") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$..['sub-element']", "text-value") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$..sub-element", "text-value") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$..sub-element", startsWith("text")) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$..name", hasItem("Penny")) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$..name", containsInAnyOrder("Penny", "Leonard", "Sheldon")) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.nerds", hasSize(2)) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.numbers", "[10, 20, 30, 40]") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.numbers", contains(10L, 20L, 30L, 40L)) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.numbers", hasSize(4)) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.person", "{\"name\":\"Penny\"}") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); }
@Test public void testValidateMessageElementsWithJsonPathFunctionsSuccessful() { JsonPathMessageValidationContext validationContext = new JsonPathMessageValidationContext.Builder() .expression("$..element.keySet()", "[attributeA, sub-element, attributeB]") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.element.keySet()", Arrays.asList("attributeA", "sub-element", "attributeB")) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.element.keySet()", contains("attributeA", "sub-element", "attributeB")) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$['root']['person'].keySet()", "[name]") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$['root']['person'].keySet()", hasSize(1)) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.numbers.size()", 4) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.person.size()", 1) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.person.exists()", true) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.foo.exists()", false) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.nullValue", "") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.nerds.size()", 2L) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.nerds.toString()", "[{\"name\":\"Leonard\"},{\"name\":\"Sheldon\"}]") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); validationContext = new JsonPathMessageValidationContext.Builder() .expression("$..sub-element.size()", 1L) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); }
@Test public void testValidateMessageElementsWithValidationMatcherSuccessful() { Map<String, Object> validationExpressions = new HashMap<>(); validationExpressions.put("$..element.attributeA", "@startsWith('attribute-')@"); validationExpressions.put("$..element.attributeB", "@endsWith('-value')@"); validationExpressions.put("$..element.sub-element", "@equalsIgnoreCase('TEXT-VALUE')@"); validationExpressions.put("$.root.element.sub-element", "@contains('ext-val')@"); validationExpressions.put("$.root.nullValue", "@assertThat(nullValue())@"); JsonPathMessageValidationContext validationContext = new JsonPathMessageValidationContext.Builder() .expressions(validationExpressions) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); }
@Test public void testValidateMessageElementsWithJsonPathFunctionsNotSuccessful() { JsonPathMessageValidationContext validationContext = validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.element.keySet()", "[attributeA, attributeB, attributeC]") .build(); try { validator.validateMessage(message, new DefaultMessage(), context, validationContext); Assert.fail("Missing validation exception"); } catch (ValidationException e) {} validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.element.keySet()", Arrays.asList("attributeA", "attributeB")) .build(); try { validator.validateMessage(message, new DefaultMessage(), context, validationContext); Assert.fail("Missing validation exception"); } catch (ValidationException e) {} validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.numbers.size()", 5) .build(); try { validator.validateMessage(message, new DefaultMessage(), context, validationContext); Assert.fail("Missing validation exception"); } catch (ValidationException e) {} validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.person.size()", 0) .build(); try { validator.validateMessage(message, new DefaultMessage(), context, validationContext); Assert.fail("Missing validation exception"); } catch (ValidationException e) {} validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.nullValue", "10") .build(); try { validator.validateMessage(message, new DefaultMessage(), context, validationContext); Assert.fail("Missing validation exception"); } catch (ValidationException e) {} }
@Test(expectedExceptions = {ValidationException.class}) public void testValidateMessageElementsWithValidationMatcherNotSuccessful() { Map<String, Object> validationExpressions = new HashMap<>(); validationExpressions.put("$..element.attributeA", "@startsWith('attribute-')@"); validationExpressions.put("$..element.attributeB", "@endsWith('-value')@"); validationExpressions.put("$..element.sub-element", "@contains('FAIL')@"); validationExpressions.put("$.root.nullValue", "@assertThat(noNullValue())@"); JsonPathMessageValidationContext validationContext = new JsonPathMessageValidationContext.Builder() .expressions(validationExpressions) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); }
@Test(expectedExceptions = {ValidationException.class}) public void testValidateMessageElementsWithJsonPathNotSuccessful() { JsonPathMessageValidationContext validationContext = new JsonPathMessageValidationContext.Builder() .expression("$..element.sub-element", "false-value") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); }
@Test public void testValidateMessageElementsWithFullPathSuccessful() { JsonPathMessageValidationContext validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.element.sub-element", "text-value") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); }
@Test(expectedExceptions = {ValidationException.class}) public void testValidateMessageElementsWithFullPathNotSuccessful() { JsonPathMessageValidationContext validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.element.sub-element", "false-value") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); }
@Test(expectedExceptions = {CitrusRuntimeException.class}) public void testValidateMessageElementsPathNotFound() { JsonPathMessageValidationContext validationContext = new JsonPathMessageValidationContext.Builder() .expression("$.root.foo", "foo-value") .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); }
@Test public void testValidateMessageElementsWithMixedNotationsSuccessful() { Map<String, Object> validationExpressions = new HashMap<>(); validationExpressions.put("$..element.sub-element", "text-value"); validationExpressions.put("$.root.element.sub-element", "text-value"); JsonPathMessageValidationContext validationContext = new JsonPathMessageValidationContext.Builder() .expressions(validationExpressions) .build(); validator.validateMessage(message, new DefaultMessage(), context, validationContext); }