Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

import org.citrusframework.CitrusSettings;

import static java.util.Objects.nonNull;

public class MessagePayloadUtils {

private static final boolean prettyPrint = CitrusSettings.isPrettyPrintEnabled();
Expand Down Expand Up @@ -55,7 +57,7 @@ public static String prettyPrint(String payload) {
* @return
*/
public static boolean isXml(String payload) {
return payload.trim().startsWith("<");
return nonNull(payload) && payload.trim().startsWith("<");
}

/**
Expand All @@ -64,7 +66,7 @@ public static boolean isXml(String payload) {
* @return
*/
public static boolean isJson(String payload) {
return payload.trim().startsWith("{") || payload.trim().startsWith("[");
return nonNull(payload) && (payload.trim().startsWith("{") || payload.trim().startsWith("["));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@

package org.citrusframework.actions;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.citrusframework.context.TestContext;
import org.citrusframework.endpoint.Endpoint;
import org.citrusframework.exceptions.CitrusRuntimeException;
Expand All @@ -36,14 +26,14 @@
import org.citrusframework.message.MessagePayloadUtils;
import org.citrusframework.message.MessageProcessor;
import org.citrusframework.message.MessageSelectorBuilder;
import org.citrusframework.message.MessageType;
import org.citrusframework.message.WithPayloadBuilder;
import org.citrusframework.message.builder.DefaultPayloadBuilder;
import org.citrusframework.message.builder.MessageBuilderSupport;
import org.citrusframework.message.builder.ReceiveMessageBuilderSupport;
import org.citrusframework.messaging.Consumer;
import org.citrusframework.messaging.SelectiveConsumer;
import org.citrusframework.spi.ReferenceResolverAware;
import org.citrusframework.util.StringUtils;
import org.citrusframework.validation.DefaultMessageHeaderValidator;
import org.citrusframework.validation.HeaderValidator;
import org.citrusframework.validation.MessageValidator;
Expand All @@ -60,6 +50,20 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
import static org.citrusframework.util.StringUtils.hasText;

/**
* This action receives messages from a service destination. Action uses a {@link org.citrusframework.endpoint.Endpoint}
* to receive the message, this means that this action is independent of any message transport.
Expand All @@ -70,6 +74,12 @@
* @since 2008
*/
public class ReceiveMessageAction extends AbstractTestAction {

private static final List<String> XML_LIKE_MESSAGE_TYPES = List.of(
MessageType.XML.name(),
MessageType.XHTML.name()
);

/** Build message selector with name value pairs */
private final Map<String, Object> messageSelectorMap;

Expand Down Expand Up @@ -109,9 +119,11 @@ public class ReceiveMessageAction extends AbstractTestAction {
/** List of processors that handle the control message builder */
private final List<MessageProcessor> controlMessageProcessors;

/** The expected message type to arrive in this receive action - this information is needed to find a proper
* message validator for this message */
private final String messageType;
/**
* The expected message type to arrive in this receive action.
* This information is needed to find a proper message validator for this message
* */
private String messageType;

/** Logger */
private static final Logger logger = LoggerFactory.getLogger(ReceiveMessageAction.class);
Expand Down Expand Up @@ -150,7 +162,7 @@ public void doExecute(TestContext context) {
String selector = MessageSelectorBuilder.build(messageSelector, messageSelectorMap, context);

//receive message either selected or plain with message receiver
if (StringUtils.hasText(selector)) {
if (hasText(selector)) {
receivedMessage = receiveSelected(context, selector);
} else {
receivedMessage = receive(context);
Expand Down Expand Up @@ -217,18 +229,24 @@ protected void validateMessage(Message message, TestContext context) {
}

Message controlMessage = createControlMessage(context, messageType);
if (StringUtils.hasText(controlMessage.getName())) {
if (hasText(controlMessage.getName())) {
context.getMessageStore().storeMessage(controlMessage.getName(), message);
} else {
context.getMessageStore().storeMessage(context.getMessageStore().constructMessageName(this, getOrCreateEndpoint(context)), message);
}

if (validationProcessor != null) {
if (nonNull(validationProcessor)) {
validationProcessor.validate(message, context);
} else {
logger.debug("Control message:\n{}", controlMessage.print(context));

if (!validators.isEmpty()) {
if (hasText(controlMessage.getPayload(String.class))) {
assumeMessageType(controlMessage);
} else {
assumeMessageType(message);
}

if (nonNull(validators) && !validators.isEmpty()) {
for (MessageValidator<? extends ValidationContext> messageValidator : validators) {
messageValidator.validateMessage(message, controlMessage, context, validationContexts);
}
Expand All @@ -255,6 +273,27 @@ protected void validateMessage(Message message, TestContext context) {
}
}

private void assumeMessageType(Message message) {
var payload = message.getPayload(String.class);
if (hasText(payload)) {
payload = payload.trim();

if (payload.startsWith("<")
&& (isNull(getMessageType()) || !XML_LIKE_MESSAGE_TYPES.contains(getMessageType()))) {
logger.warn("Detected payload starting with '<', but non-XML message type '{}' configured! Assuming message type {}",
getMessageType(), MessageType.XML);

setMessageType(MessageType.XML);
} else if ((payload.startsWith("{") || payload.startsWith("["))
&& (isNull(getMessageType()) || !getMessageType().equals(MessageType.JSON.name()))) {
logger.warn("Detected payload starting with '{}', but non-JSON message type '{}' configured! Assuming message type {}",
payload.charAt(0), getMessageType(), MessageType.JSON);

setMessageType(MessageType.JSON);
}
}
}

/**
* Create control message that is expected. Apply global and local message processors and data dictionaries.
* @param context
Expand Down Expand Up @@ -296,7 +335,7 @@ public boolean isDisabled(TestContext context) {
public Endpoint getOrCreateEndpoint(TestContext context) {
if (endpoint != null) {
return endpoint;
} else if (StringUtils.hasText(endpointUri)) {
} else if (hasText(endpointUri)) {
return context.getEndpointFactory().create(endpointUri, context);
} else {
throw new CitrusRuntimeException("Neither endpoint nor endpoint uri is set properly!");
Expand Down Expand Up @@ -351,6 +390,10 @@ public String getMessageType() {
return messageType;
}

private void setMessageType(MessageType messageType) {
this.messageType = messageType.name();
}

/**
* Gets the messageSelectorMap.
* @return the messageSelectorMap
Expand Down
Loading
Loading