@Test
  public void testInterceptMessageConstruction() throws Exception {
    MessageConstructionInterceptor interceptor =
        new AbstractMessageConstructionInterceptor() {
          @Override
          public boolean supportsMessageType(String messageType) {
            return MessageType.XML.toString().equalsIgnoreCase(messageType);
          }

          @Override
          protected Message interceptMessage(
              Message message, String messageType, TestContext context) {
            return new DefaultMessage("Intercepted!");
          }

          @Override
          protected String getName() {
            return "MockInterceptor";
          }
        };

    Message in = new DefaultMessage("Hello Citrus!");
    Message intercepted =
        interceptor.interceptMessageConstruction(in, MessageType.XML.toString(), context);
    Assert.assertEquals(intercepted.getPayload(String.class), "Intercepted!");

    intercepted =
        interceptor.interceptMessageConstruction(in, MessageType.PLAINTEXT.toString(), context);
    Assert.assertEquals(intercepted.getPayload(String.class), "Hello Citrus!");
  }
  @Override
  public void doExecute(TestContext context) {
    try {
      Message receivedMessage;
      Consumer consumer = getOrCreateEndpoint(context).createConsumer();

      if (StringUtils.hasText(messageSelector) && consumer instanceof SelectiveConsumer) {
        receivedMessage = ((SelectiveConsumer) consumer).receive(messageSelector, context, timeout);
      } else {
        receivedMessage = consumer.receive(context, timeout);
      }

      if (receivedMessage != null) {
        if (log.isDebugEnabled()) {
          log.debug("Received message: " + receivedMessage.getPayload());
        }

        throw new CitrusRuntimeException(
            "Message timeout validation failed! "
                + "Received message while waiting for timeout on destination");
      }
    } catch (ActionTimeoutException e) {
      log.info("No messages received on destination. Message timeout validation OK!");
      log.info(e.getMessage());
    }
  }
  /**
   * Test for handler routing without Xpath given (implementation takes the value of first node).
   */
  @Test
  public void testRouteMessageWithDefaultXpath() throws Exception {
    XPathPayloadMappingKeyExtractor mappingNameExtractor = new XPathPayloadMappingKeyExtractor();
    endpointAdapter.setMappingKeyExtractor(mappingNameExtractor);

    Message response =
        endpointAdapter.handleMessage(new DefaultMessage("<FooBarTest></FooBarTest>"));

    Assert.assertEquals(response.getPayload(String.class).trim(), "<FooBarTest>OK</FooBarTest>");
  }
Example #4
0
  /**
   * Invokes the endpoint adapter with constructed mail message and headers.
   *
   * @param request
   */
  protected Message invokeEndpointAdapter(Message request) {
    MailMessage mailMessage = (MailMessage) request.getPayload();

    if (splitMultipart) {
      return split(mailMessage.getBody(), request.copyHeaders());
    } else {
      StringResult result = new StringResult();
      marshaller.marshal(mailMessage, result);
      return getEndpointAdapter()
          .handleMessage(new DefaultMessage(result.toString(), request.copyHeaders()));
    }
  }
  @Override
  protected Map<String, Object> buildMessageHeaders(TestContext context) {
    Map<String, Object> headers = super.buildMessageHeaders(context);
    headers.putAll(message.copyHeaders());

    return headers;
  }
  @Override
  public void validateMessagePayload(
      Message receivedMessage,
      Message controlMessage,
      XmlMessageValidationContext validationContext,
      TestContext context)
      throws ValidationException {
    log.info("Start XML message validation");

    try {
      if (validationContext.isSchemaValidationEnabled()) {
        validateXMLSchema(receivedMessage, validationContext);
        validateDTD(validationContext.getDTDResource(), receivedMessage);
      }

      validateNamespaces(validationContext.getControlNamespaces(), receivedMessage);
      validateMessageContent(receivedMessage, controlMessage, validationContext, context);

      if (controlMessage != null) {
        Assert.isTrue(
            controlMessage.getHeaderData().size() <= receivedMessage.getHeaderData().size(),
            "Failed to validate header data XML fragments - found "
                + receivedMessage.getHeaderData().size()
                + " header fragments, expected "
                + controlMessage.getHeaderData().size());

        for (int i = 0; i < controlMessage.getHeaderData().size(); i++) {
          validateXmlHeaderFragment(
              receivedMessage.getHeaderData().get(i),
              controlMessage.getHeaderData().get(i),
              validationContext,
              context);
        }
      }

      log.info("XML message validation successful: All values OK");
    } catch (ClassCastException e) {
      throw new CitrusRuntimeException(e);
    } catch (DOMException e) {
      throw new CitrusRuntimeException(e);
    } catch (LSException e) {
      throw new CitrusRuntimeException(e);
    } catch (IllegalArgumentException e) {
      log.error(
          "Failed to validate:\n" + XMLUtils.prettyPrint(receivedMessage.getPayload(String.class)));
      throw new ValidationException("Validation failed:", e);
    } catch (ValidationException ex) {
      log.error(
          "Failed to validate:\n" + XMLUtils.prettyPrint(receivedMessage.getPayload(String.class)));
      throw ex;
    }
  }
  @Test
  public void testHandleMessage() {
    StaticResponseEndpointAdapter endpointAdapter = new StaticResponseEndpointAdapter();
    Map<String, Object> header = new HashMap<String, Object>();
    header.put("Operation", "UnitTest");

    endpointAdapter.setMessageHeader(header);
    endpointAdapter.setMessagePayload("<TestMessage>Hello User!</TestMessage>");

    Message response =
        endpointAdapter.handleMessage(
            new DefaultMessage("<TestMessage>Hello World!</TestMessage>"));

    Assert.assertEquals(response.getPayload(), "<TestMessage>Hello User!</TestMessage>");
    Assert.assertNotNull(response.getHeader("Operation"));
    Assert.assertEquals(response.getHeader("Operation"), "UnitTest");
  }
  /** Test for handler routing by node content */
  @Test
  public void testRouteMessageByElementTextContent() throws Exception {
    XPathPayloadMappingKeyExtractor mappingNameExtractor = new XPathPayloadMappingKeyExtractor();
    mappingNameExtractor.setXpathExpression("//Test/@name");
    endpointAdapter.setMappingKeyExtractor(mappingNameExtractor);

    Message response =
        endpointAdapter.handleMessage(new DefaultMessage("<Test name=\"FooTest\"></Test>"));

    Assert.assertEquals(
        response.getPayload(String.class).trim(), "<Test name=\"FooTest\">OK</Test>");

    response = endpointAdapter.handleMessage(new DefaultMessage("<Test name=\"BarTest\"></Test>"));

    Assert.assertEquals(
        response.getPayload(String.class).trim(), "<Test name=\"BarTest\">OK</Test>");
  }
Example #9
0
 /**
  * Informs message listeners if present that new outbound message is about to be sent.
  *
  * @param message
  */
 public void onOutboundMessage(Message message) {
   if (messageListeners != null && !messageListeners.isEmpty()) {
     messageListeners.onOutboundMessage(message, this);
   } else {
     if (log.isDebugEnabled()) {
       log.debug("Sent message:" + System.getProperty("line.separator") + message.toString());
     }
   }
 }
Example #10
0
 /**
  * Informs message listeners if present that inbound message was received.
  *
  * @param receivedMessage
  */
 public void onInboundMessage(Message receivedMessage) {
   if (messageListeners != null && !messageListeners.isEmpty()) {
     messageListeners.onInboundMessage(receivedMessage, this);
   } else {
     if (log.isDebugEnabled()) {
       log.debug(
           "Received message:"
               + System.getProperty("line.separator")
               + (receivedMessage != null ? receivedMessage.toString() : ""));
     }
   }
 }
Example #11
0
  @Override
  public boolean accept(String from, String recipient) {
    if (autoAccept) {
      return true;
    }

    StringResult result = new StringResult();
    marshaller.marshal(createAcceptRequest(from, recipient), result);
    Message response = getEndpointAdapter().handleMessage(new DefaultMessage(result.toString()));

    if (response == null || response.getPayload() == null) {
      throw new CitrusRuntimeException(
          "Did not receive accept response. Missing accept response because autoAccept is disabled.");
    }

    AcceptResponse acceptResponse = null;
    if (response.getPayload() instanceof AcceptResponse) {
      acceptResponse = (AcceptResponse) response.getPayload();
    } else if (response.getPayload() instanceof String) {
      acceptResponse = (AcceptResponse) marshaller.unmarshal(response.getPayload(Source.class));
    }

    if (acceptResponse == null) {
      throw new CitrusRuntimeException("Unable to read accept response from payload: " + response);
    }

    return acceptResponse.isAccept();
  }
  @Test
  public void testSendBuilderWithObjectMessageInstance() {
    final Message message = new DefaultMessage(new Integer(10)).setHeader("operation", "foo");
    MockTestDesigner builder =
        new MockTestDesigner(applicationContext) {
          @Override
          public void configure() {
            send(messageEndpoint).message(message);
          }
        };

    builder.configure();

    TestCase test = builder.getTestCase();
    Assert.assertEquals(test.getActionCount(), 1);
    Assert.assertEquals(test.getActions().get(0).getClass(), SendMessageAction.class);

    SendMessageAction action = ((SendMessageAction) test.getActions().get(0));
    Assert.assertEquals(action.getName(), "send");

    Assert.assertEquals(action.getEndpoint(), messageEndpoint);
    Assert.assertEquals(action.getMessageBuilder().getClass(), StaticMessageContentBuilder.class);

    StaticMessageContentBuilder messageBuilder =
        (StaticMessageContentBuilder) action.getMessageBuilder();
    Assert.assertEquals(messageBuilder.getMessage().getPayload(), 10);
    Assert.assertEquals(messageBuilder.getMessageHeaders().size(), 0L);
    Assert.assertEquals(
        messageBuilder.getMessage().copyHeaders().size(), message.copyHeaders().size());
    Assert.assertEquals(
        messageBuilder.getMessage().getHeader(MessageHeaders.ID),
        message.getHeader(MessageHeaders.ID));
    Assert.assertEquals(messageBuilder.getMessage().getHeader("operation"), "foo");

    Message constructed =
        messageBuilder.buildMessageContent(new TestContext(), MessageType.PLAINTEXT.name());
    Assert.assertEquals(constructed.copyHeaders().size(), message.copyHeaders().size());
    Assert.assertEquals(constructed.getHeader("operation"), "foo");
    Assert.assertEquals(
        constructed.getHeader(MessageHeaders.ID), message.getHeader(MessageHeaders.ID));
  }
  /**
   * Validate message payloads by comparing to a control message.
   *
   * @param receivedMessage
   * @param validationContext
   * @param context
   */
  protected void validateMessageContent(
      Message receivedMessage,
      Message controlMessage,
      XmlMessageValidationContext validationContext,
      TestContext context) {
    if (controlMessage == null || controlMessage.getPayload() == null) {
      log.info("Skip message payload validation as no control message was defined");
      return;
    }

    if (!(controlMessage.getPayload() instanceof String)) {
      throw new IllegalArgumentException(
          "DomXmlMessageValidator does only support message payload of type String, "
              + "but was "
              + controlMessage.getPayload().getClass());
    }

    String controlMessagePayload = controlMessage.getPayload(String.class);

    if (receivedMessage.getPayload() == null
        || !StringUtils.hasText(receivedMessage.getPayload(String.class))) {
      Assert.isTrue(
          !StringUtils.hasText(controlMessagePayload),
          "Unable to validate message payload - received message payload was empty, control message payload is not");
      return;
    } else if (!StringUtils.hasText(controlMessagePayload)) {
      return;
    }

    log.info("Start XML tree validation ...");

    Document received = XMLUtils.parseMessagePayload(receivedMessage.getPayload(String.class));
    Document source = XMLUtils.parseMessagePayload(controlMessagePayload);

    XMLUtils.stripWhitespaceNodes(received);
    XMLUtils.stripWhitespaceNodes(source);

    if (log.isDebugEnabled()) {
      log.debug("Received message:\n" + XMLUtils.serialize(received));
      log.debug("Control message:\n" + XMLUtils.serialize(source));
    }

    validateXmlTree(
        received,
        source,
        validationContext,
        namespaceContextBuilder.buildContext(receivedMessage, validationContext.getNamespaces()),
        context);
  }
Example #14
0
  @Override
  public void deliver(String from, String recipient, InputStream data) {
    try {
      MimeMailMessage mimeMailMessage = new MimeMailMessage(new MimeMessage(getSession(), data));
      Message request =
          messageConverter.convertInbound(mimeMailMessage, getEndpointConfiguration());
      Message response = invokeEndpointAdapter(request);

      if (response != null && response.getPayload() != null) {
        MailResponse mailResponse = null;
        if (response.getPayload() instanceof MailResponse) {
          mailResponse = (MailResponse) response.getPayload();
        } else if (response.getPayload() instanceof String) {
          mailResponse = (MailResponse) marshaller.unmarshal(response.getPayload(Source.class));
        }

        if (mailResponse != null && mailResponse.getCode() != MailResponse.OK_CODE) {
          throw new RejectException(mailResponse.getCode(), mailResponse.getMessage());
        }
      }
    } catch (MessagingException e) {
      throw new CitrusRuntimeException(e);
    }
  }
 @Override
 protected Object buildMessagePayload(TestContext context) {
   return message.getPayload();
 }
  /**
   * Validate message with a XML schema.
   *
   * @param receivedMessage
   * @param validationContext
   */
  protected void validateXMLSchema(
      Message receivedMessage, XmlMessageValidationContext validationContext) {
    if (receivedMessage.getPayload() == null
        || !StringUtils.hasText(receivedMessage.getPayload(String.class))) {
      return;
    }

    try {
      Document doc = XMLUtils.parseMessagePayload(receivedMessage.getPayload(String.class));

      if (!StringUtils.hasText(doc.getFirstChild().getNamespaceURI())) {
        return;
      }

      log.info("Starting XML schema validation ...");

      XmlValidator validator = null;
      XsdSchemaRepository schemaRepository = null;
      if (validationContext.getSchema() != null) {
        validator =
            applicationContext
                .getBean(validationContext.getSchema(), XsdSchema.class)
                .createValidator();
      } else if (validationContext.getSchemaRepository() != null) {
        schemaRepository =
            applicationContext.getBean(
                validationContext.getSchemaRepository(), XsdSchemaRepository.class);
      } else if (schemaRepositories.size() == 1) {
        schemaRepository = schemaRepositories.get(0);
      } else if (schemaRepositories.size() > 0) {
        for (XsdSchemaRepository repository : schemaRepositories) {
          if (repository.canValidate(doc)) {
            schemaRepository = repository;
          }
        }

        if (schemaRepository == null) {
          throw new CitrusRuntimeException(
              String.format(
                  "Failed to find proper schema repository in Spring bean context for validating element '%s(%s)'",
                  doc.getFirstChild().getLocalName(), doc.getFirstChild().getNamespaceURI()));
        }
      } else {
        log.warn(
            "Neither schema instance nor schema repository defined - skipping XML schema validation");
        return;
      }

      if (schemaRepository != null) {
        if (!schemaRepository.canValidate(doc)) {
          throw new CitrusRuntimeException(
              String.format(
                  "Unable to find proper XML schema definition for element '%s(%s)' in schema repository '%s'",
                  doc.getFirstChild().getLocalName(),
                  doc.getFirstChild().getNamespaceURI(),
                  schemaRepository.getName()));
        }

        List<Resource> schemas = new ArrayList<>();
        for (XsdSchema xsdSchema : schemaRepository.getSchemas()) {
          if (xsdSchema instanceof XsdSchemaCollection) {
            for (Resource resource : ((XsdSchemaCollection) xsdSchema).getSchemaResources()) {
              schemas.add(resource);
            }
          } else if (xsdSchema instanceof WsdlXsdSchema) {
            for (Resource resource : ((WsdlXsdSchema) xsdSchema).getSchemaResources()) {
              schemas.add(resource);
            }
          } else {
            synchronized (transformerFactory) {
              ByteArrayOutputStream bos = new ByteArrayOutputStream();
              try {
                transformerFactory
                    .newTransformer()
                    .transform(xsdSchema.getSource(), new StreamResult(bos));
              } catch (TransformerException e) {
                throw new CitrusRuntimeException(
                    "Failed to read schema " + xsdSchema.getTargetNamespace(), e);
              }
              schemas.add(new ByteArrayResource(bos.toByteArray()));
            }
          }
        }

        validator =
            XmlValidatorFactory.createValidator(
                schemas.toArray(new Resource[schemas.size()]), WsdlXsdSchema.W3C_XML_SCHEMA_NS_URI);
      }

      SAXParseException[] results = validator.validate(new DOMSource(doc));
      if (results.length == 0) {
        log.info("Schema of received XML validated OK");
      } else {
        log.error(
            "Schema validation failed for message:\n"
                + XMLUtils.prettyPrint(receivedMessage.getPayload(String.class)));

        // Report all parsing errors
        log.debug("Found " + results.length + " schema validation errors");
        StringBuilder errors = new StringBuilder();
        for (SAXParseException e : results) {
          errors.append(e.toString());
          errors.append("\n");
        }
        log.debug(errors.toString());

        throw new ValidationException("Schema validation failed:", results[0]);
      }
    } catch (IOException e) {
      throw new CitrusRuntimeException(e);
    } catch (SAXException e) {
      throw new CitrusRuntimeException(e);
    }
  }
  /**
   * Validate namespaces in message. The method compares namespace declarations in the root element
   * of the received message to expected namespaces. Prefixes are important too, so differing
   * namespace prefixes will fail the validation.
   *
   * @param expectedNamespaces
   * @param receivedMessage
   */
  protected void validateNamespaces(
      Map<String, String> expectedNamespaces, Message receivedMessage) {
    if (CollectionUtils.isEmpty(expectedNamespaces)) {
      return;
    }

    if (receivedMessage.getPayload() == null
        || !StringUtils.hasText(receivedMessage.getPayload(String.class))) {
      throw new ValidationException(
          "Unable to validate message namespaces - receive message payload was empty");
    }

    log.info("Start XML namespace validation");

    Document received = XMLUtils.parseMessagePayload(receivedMessage.getPayload(String.class));

    Map<String, String> foundNamespaces =
        XMLUtils.lookupNamespaces(receivedMessage.getPayload(String.class));

    if (foundNamespaces.size() != expectedNamespaces.size()) {
      throw new ValidationException(
          "Number of namespace declarations not equal for node "
              + XMLUtils.getNodesPathName(received.getFirstChild())
              + " found "
              + foundNamespaces.size()
              + " expected "
              + expectedNamespaces.size());
    }

    for (Entry<String, String> entry : expectedNamespaces.entrySet()) {
      String namespace = entry.getKey();
      String url = entry.getValue();

      if (foundNamespaces.containsKey(namespace)) {
        if (!foundNamespaces.get(namespace).equals(url)) {
          throw new ValidationException(
              "Namespace '"
                  + namespace
                  + "' values not equal: found '"
                  + foundNamespaces.get(namespace)
                  + "' expected '"
                  + url
                  + "' in reference node "
                  + XMLUtils.getNodesPathName(received.getFirstChild()));
        } else {
          log.info(
              "Validating namespace " + namespace + " value as expected " + url + " - value OK");
        }
      } else {
        throw new ValidationException(
            "Missing namespace "
                + namespace
                + "("
                + url
                + ") in node "
                + XMLUtils.getNodesPathName(received.getFirstChild()));
      }
    }

    log.info("XML namespace validation finished successfully: All values OK");
  }