IBM MQ test drafts
This commit is contained in:
parent
ef4562ab74
commit
ce54e336ba
@ -0,0 +1,516 @@
|
||||
package cz.moneta.test.harness.support.messaging;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import cz.moneta.test.harness.endpoints.imq.ImqFirstVisionEndpoint;
|
||||
import cz.moneta.test.harness.endpoints.imq.ImqFirstVisionQueue;
|
||||
import cz.moneta.test.harness.exception.HarnessException;
|
||||
import cz.moneta.test.harness.messaging.MessageContentType;
|
||||
import cz.moneta.test.harness.messaging.MqMessageFormat;
|
||||
import cz.moneta.test.harness.messaging.ReceivedMessage;
|
||||
import cz.moneta.test.harness.messaging.exception.MessagingTimeoutException;
|
||||
import cz.moneta.test.harness.support.util.FileReader;
|
||||
import cz.moneta.test.harness.support.util.Template;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Fluent builder for IBM MQ requests.
|
||||
* <p>
|
||||
* Usage:
|
||||
* <pre>{@code
|
||||
* ImqRequest.toQueue(endpoint, queue)
|
||||
* .asJson()
|
||||
* .withPayload("{\"field\": \"value\"}")
|
||||
* .send();
|
||||
*
|
||||
* ImqRequest.fromQueue(endpoint, queue)
|
||||
* .receiveWhere(msg -> msg.extract("field").equals("value"))
|
||||
* .withTimeout(10, TimeUnit.SECONDS)
|
||||
* .andAssertFieldValue("result", "OK");
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public final class ImqRequest {
|
||||
|
||||
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
|
||||
|
||||
private ImqRequest() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start building a message to send to a queue.
|
||||
*/
|
||||
public static QueuePhase toQueue(ImqFirstVisionEndpoint endpoint, ImqFirstVisionQueue queue) {
|
||||
return new QueueBuilder(endpoint, queue, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start building a message to receive from a queue.
|
||||
*/
|
||||
public static ReceivePhase fromQueue(ImqFirstVisionEndpoint endpoint, ImqFirstVisionQueue queue) {
|
||||
return new QueueBuilder(endpoint, queue, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start building a message to send to a queue by physical name.
|
||||
*/
|
||||
public static QueuePhase toQueue(ImqFirstVisionEndpoint endpoint, String queueName) {
|
||||
return new QueueBuilder(endpoint, null, queueName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start building a message to receive from a queue by physical name.
|
||||
*/
|
||||
public static ReceivePhase fromQueue(ImqFirstVisionEndpoint endpoint, String queueName) {
|
||||
return new QueueBuilder(endpoint, null, queueName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phase after specifying queue - can send or receive.
|
||||
*/
|
||||
public interface QueuePhase extends PayloadPhase, ReceivePhase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Phase for building message payload.
|
||||
*/
|
||||
public interface PayloadPhase {
|
||||
/**
|
||||
* Set message format to JSON (default).
|
||||
*/
|
||||
PayloadPhase asJson();
|
||||
|
||||
/**
|
||||
* Set message format to XML.
|
||||
*/
|
||||
PayloadPhase asXml();
|
||||
|
||||
/**
|
||||
* Set message format to EBCDIC (IBM-870).
|
||||
*/
|
||||
PayloadPhase asEbcdic();
|
||||
|
||||
/**
|
||||
* Set message format to UTF-8 (CCSID 1208).
|
||||
*/
|
||||
PayloadPhase asUtf8();
|
||||
|
||||
/**
|
||||
* Set message payload as JSON string.
|
||||
*/
|
||||
PayloadPhase withPayload(String payload);
|
||||
|
||||
/**
|
||||
* Load payload from resource file.
|
||||
*/
|
||||
PayloadPhase withPayloadFromFile(String path);
|
||||
|
||||
/**
|
||||
* Render payload from template.
|
||||
*/
|
||||
PayloadPhase withPayloadFromTemplate(Template template);
|
||||
|
||||
/**
|
||||
* Add field to JSON payload at root level.
|
||||
*/
|
||||
PayloadPhase addField(String fieldName, Object value);
|
||||
|
||||
/**
|
||||
* Add field to JSON payload at specified path.
|
||||
*/
|
||||
PayloadPhase addField(String path, String fieldName, Object value);
|
||||
|
||||
/**
|
||||
* Append value to JSON array at specified path.
|
||||
*/
|
||||
PayloadPhase appendToArray(String path, Object value);
|
||||
|
||||
/**
|
||||
* Send the message.
|
||||
*/
|
||||
void send();
|
||||
}
|
||||
|
||||
/**
|
||||
* Phase for receiving messages.
|
||||
*/
|
||||
public interface ReceivePhase {
|
||||
/**
|
||||
* Set JMS message selector.
|
||||
*/
|
||||
ReceivePhase withSelector(String selector);
|
||||
|
||||
/**
|
||||
* Start receiving message matching predicate.
|
||||
*/
|
||||
AwaitingPhase receiveWhere(Predicate<ReceivedMessage> filter);
|
||||
|
||||
/**
|
||||
* Browse messages from queue (non-destructive).
|
||||
*/
|
||||
List<ReceivedMessage> browse(int maxMessages);
|
||||
|
||||
/**
|
||||
* Browse messages from queue with selector (non-destructive).
|
||||
*/
|
||||
List<ReceivedMessage> browse(String selector, int maxMessages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Phase after specifying filter - await message with timeout.
|
||||
*/
|
||||
public interface AwaitingPhase {
|
||||
/**
|
||||
* Set timeout and get message response for assertions.
|
||||
*/
|
||||
MessageResponse withTimeout(long duration, java.util.concurrent.TimeUnit unit);
|
||||
|
||||
/**
|
||||
* Set timeout duration and get message response for assertions.
|
||||
*/
|
||||
MessageResponse withTimeout(Duration timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Response with fluent assertions.
|
||||
*/
|
||||
public interface MessageResponse extends cz.moneta.test.harness.support.messaging.MessageResponse {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for queue operations.
|
||||
*/
|
||||
private static class QueueBuilder implements QueuePhase, AwaitingPhase {
|
||||
|
||||
private final ImqFirstVisionEndpoint endpoint;
|
||||
private final ImqFirstVisionQueue logicalQueue;
|
||||
private final String physicalQueue;
|
||||
private String selector;
|
||||
private MqMessageFormat format = MqMessageFormat.JSON;
|
||||
private String payload;
|
||||
private Map<String, Object> fields = new HashMap<>();
|
||||
private List<Map.Entry<String, Object>> arrayAppends = new ArrayList<>();
|
||||
private Predicate<ReceivedMessage> filter;
|
||||
private Duration timeout;
|
||||
|
||||
public QueueBuilder(ImqFirstVisionEndpoint endpoint, ImqFirstVisionQueue logicalQueue, String physicalQueue) {
|
||||
this.endpoint = endpoint;
|
||||
this.logicalQueue = logicalQueue;
|
||||
this.physicalQueue = physicalQueue;
|
||||
}
|
||||
|
||||
private String getQueueName() {
|
||||
if (logicalQueue != null) {
|
||||
return endpoint.resolveQueue(logicalQueue);
|
||||
}
|
||||
return physicalQueue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase asJson() {
|
||||
this.format = MqMessageFormat.JSON;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase asXml() {
|
||||
this.format = MqMessageFormat.XML;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase asEbcdic() {
|
||||
this.format = MqMessageFormat.EBCDIC_870;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase asUtf8() {
|
||||
this.format = MqMessageFormat.UTF8_1208;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase withPayload(String payload) {
|
||||
this.payload = payload;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase withPayloadFromFile(String path) {
|
||||
this.payload = FileReader.readFileFromResources(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase withPayloadFromTemplate(Template template) {
|
||||
this.payload = template.render();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase addField(String fieldName, Object value) {
|
||||
return addField("", fieldName, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase addField(String path, String fieldName, Object value) {
|
||||
String key = StringUtils.isNotBlank(path) && StringUtils.isNotBlank(fieldName) ? path + "." + fieldName : fieldName;
|
||||
this.fields.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayloadPhase appendToArray(String path, Object value) {
|
||||
this.arrayAppends.add(Map.entry(path, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send() {
|
||||
String finalPayload = buildPayload();
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
|
||||
if (logicalQueue != null) {
|
||||
properties.put("LogicalQueue", logicalQueue.name());
|
||||
}
|
||||
if (selector != null && !selector.isBlank()) {
|
||||
properties.put("Selector", selector);
|
||||
}
|
||||
|
||||
endpoint.send(getQueueName(), finalPayload, format, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReceivePhase withSelector(String selector) {
|
||||
this.selector = selector;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AwaitingPhase receiveWhere(Predicate<ReceivedMessage> filter) {
|
||||
this.filter = filter;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReceivedMessage> browse(int maxMessages) {
|
||||
return browse(selector, maxMessages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReceivedMessage> browse(String sel, int maxMessages) {
|
||||
return endpoint.browse(getQueueName(), sel, format, maxMessages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageResponse withTimeout(long duration, java.util.concurrent.TimeUnit unit) {
|
||||
return withTimeout(Duration.of(duration, java.time.temporal.ChronoUnit.MILLIS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageResponse withTimeout(Duration timeout) {
|
||||
this.timeout = timeout;
|
||||
|
||||
if (filter == null) {
|
||||
throw new IllegalStateException("Must specify receiveWhere filter before withTimeout");
|
||||
}
|
||||
|
||||
ReceivedMessage message = receiveMessage();
|
||||
return new ResponseImpl(message);
|
||||
}
|
||||
|
||||
private ReceivedMessage receiveMessage() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
long timeoutMs = timeout.toMillis();
|
||||
|
||||
while (System.currentTimeMillis() - startTime < timeoutMs) {
|
||||
try {
|
||||
ReceivedMessage message = endpoint.receive(getQueueName(), selector, format, Duration.ofSeconds(1));
|
||||
if (filter.test(message)) {
|
||||
return message;
|
||||
}
|
||||
} catch (MessagingTimeoutException e) {
|
||||
// Continue polling
|
||||
}
|
||||
}
|
||||
|
||||
throw new MessagingTimeoutException(
|
||||
"No message matching filter found on queue '" + getQueueName() +
|
||||
"' within " + timeout.toMillis() + "ms");
|
||||
}
|
||||
|
||||
private String buildPayload() {
|
||||
if (payload == null) {
|
||||
return "{}";
|
||||
}
|
||||
|
||||
if (fields.isEmpty() && arrayAppends.isEmpty()) {
|
||||
return payload;
|
||||
}
|
||||
|
||||
try {
|
||||
Map<String, Object> json = JSON_MAPPER.readValue(payload, Map.class);
|
||||
|
||||
for (Map.Entry<String, Object> entry : fields.entrySet()) {
|
||||
setField(json, entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Object> entry : arrayAppends) {
|
||||
appendToArray(json, entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
return JSON_MAPPER.writeValueAsString(json);
|
||||
} catch (Exception e) {
|
||||
throw new HarnessException("Failed to build payload", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setField(Map<String, Object> json, String path, Object value) {
|
||||
if (StringUtils.isBlank(path)) {
|
||||
json.put(path, value);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] parts = path.split("\\.");
|
||||
Map<String, Object> current = json;
|
||||
|
||||
for (int i = 0; i < parts.length - 1; i++) {
|
||||
String part = parts[i];
|
||||
if (!current.containsKey(part)) {
|
||||
current.put(part, new HashMap<String, Object>());
|
||||
}
|
||||
current = (Map<String, Object>) current.get(part);
|
||||
}
|
||||
|
||||
current.put(parts[parts.length - 1], value);
|
||||
}
|
||||
|
||||
private void appendToArray(Map<String, Object> json, String path, Object value) {
|
||||
String[] parts = path.split("\\.");
|
||||
Map<String, Object> current = json;
|
||||
|
||||
for (int i = 0; i < parts.length - 1; i++) {
|
||||
String part = parts[i];
|
||||
if (!current.containsKey(part)) {
|
||||
current.put(part, new ArrayList<Map<String, Object>>());
|
||||
}
|
||||
current = (Map<String, Object>) current.get(part);
|
||||
}
|
||||
|
||||
List<Map<String, Object>> array = (List<Map<String, Object>>) current.get(parts[parts.length - 1]);
|
||||
if (array == null) {
|
||||
array = new ArrayList<>();
|
||||
current.put(parts[parts.length - 1], array);
|
||||
}
|
||||
array.add((Map<String, Object>) value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Response implementation with assertions.
|
||||
*/
|
||||
private static class ResponseImpl implements MessageResponse {
|
||||
|
||||
private final ReceivedMessage message;
|
||||
|
||||
public ResponseImpl(ReceivedMessage message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageResponse andAssertFieldValue(String path, String value) {
|
||||
String actual = message.extract(path);
|
||||
if (!Objects.equals(value, actual)) {
|
||||
throw new AssertionError(String.format("Expected field '%s' to be '%s' but was '%s'", path, value, actual));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageResponse andAssertPresent(String path) {
|
||||
JsonPathValue extracted = new JsonPathValue(message.extract(path));
|
||||
if (extracted.asText() == null && !isPresentInJson(path)) {
|
||||
throw new AssertionError(String.format("Expected field '%s' to be present", path));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageResponse andAssertNotPresent(String path) {
|
||||
if (isPresentInJson(path)) {
|
||||
throw new AssertionError(String.format("Expected field '%s' to be absent", path));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageResponse andAssertHeaderValue(String headerName, String value) {
|
||||
String actual = message.getHeader(headerName);
|
||||
if (!Objects.equals(value, actual)) {
|
||||
throw new AssertionError(String.format("Expected header '%s' to be '%s' but was '%s'", headerName, value, actual));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageResponse andAssertBodyContains(String substring) {
|
||||
if (!message.getBody().contains(substring)) {
|
||||
throw new AssertionError(String.format("Body does not contain '%s'", substring));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonPathValue extract(String path) {
|
||||
return new JsonPathValue(message.extract(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T mapTo(Class<T> type) {
|
||||
return message.mapTo(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public cz.moneta.test.harness.support.messaging.ReceivedMessage getMessage() {
|
||||
return cz.moneta.test.harness.support.messaging.ReceivedMessage.fromMessagingReceivedMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBody() {
|
||||
return message.getBody();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
return message.getHeader(name);
|
||||
}
|
||||
|
||||
private boolean isPresentInJson(String path) {
|
||||
try {
|
||||
String body = message.getBody();
|
||||
if (message.getContentType() != MessageContentType.JSON) {
|
||||
return false;
|
||||
}
|
||||
JsonNode node = JSON_MAPPER.readTree(body);
|
||||
JsonNode target = extractNode(path, node);
|
||||
return target != null && !target.isMissingNode();
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private JsonNode extractNode(String path, JsonNode node) {
|
||||
return Arrays.stream(path.split("\\."))
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.reduce(node,
|
||||
(n, p) -> n.isContainerNode() ? n.get(p) : n,
|
||||
(n1, n2) -> n1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package cz.moneta.test.harness.support.messaging;
|
||||
|
||||
/**
|
||||
* Wrapper for extracted JSON path value.
|
||||
*/
|
||||
public class JsonPathValue {
|
||||
|
||||
private final String value;
|
||||
|
||||
public JsonPathValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value as String.
|
||||
*/
|
||||
public String asText() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value as Boolean.
|
||||
*/
|
||||
public Boolean asBoolean() {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return Boolean.parseBoolean(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value as Integer.
|
||||
*/
|
||||
public Integer asInteger() {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Cannot parse '" + value + "' as Integer", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value as Long.
|
||||
*/
|
||||
public Long asLong() {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(value);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException("Cannot parse '" + value + "' as Long", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying value.
|
||||
*/
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package cz.moneta.test.harness.support.messaging;
|
||||
|
||||
/**
|
||||
* Content type of a received message.
|
||||
*/
|
||||
public enum MessageContentType {
|
||||
/**
|
||||
* JSON content - body is a JSON string, can use dot-path or bracket notation for extraction
|
||||
*/
|
||||
JSON,
|
||||
/**
|
||||
* XML content - body is an XML string, can use XPath for extraction
|
||||
*/
|
||||
XML,
|
||||
/**
|
||||
* Raw text content - body is plain text without structured format
|
||||
*/
|
||||
RAW_TEXT
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package cz.moneta.test.harness.support.messaging;
|
||||
|
||||
/**
|
||||
* Response from a messaging operation (send/receive).
|
||||
* Provides fluent assertion API for received messages.
|
||||
*/
|
||||
public interface MessageResponse {
|
||||
|
||||
/**
|
||||
* Asserts that a field has the expected value.
|
||||
*
|
||||
* @param path the field path (JSON dot-path for JSON, XPath for XML)
|
||||
* @param value the expected value
|
||||
* @return this for method chaining
|
||||
*/
|
||||
MessageResponse andAssertFieldValue(String path, String value);
|
||||
|
||||
/**
|
||||
* Asserts that a field is present in the message.
|
||||
*
|
||||
* @param path the field path
|
||||
* @return this for method chaining
|
||||
*/
|
||||
MessageResponse andAssertPresent(String path);
|
||||
|
||||
/**
|
||||
* Asserts that a field is NOT present in the message.
|
||||
*
|
||||
* @param path the field path
|
||||
* @return this for method chaining
|
||||
*/
|
||||
MessageResponse andAssertNotPresent(String path);
|
||||
|
||||
/**
|
||||
* Asserts that a header has the expected value.
|
||||
*
|
||||
* @param headerName the header name
|
||||
* @param value the expected value
|
||||
* @return this for method chaining
|
||||
*/
|
||||
MessageResponse andAssertHeaderValue(String headerName, String value);
|
||||
|
||||
/**
|
||||
* Asserts that the body contains the given substring.
|
||||
* Useful for raw text or EBCDIC/UTF-8 encoded messages.
|
||||
*
|
||||
* @param substring the expected substring
|
||||
* @return this for method chaining
|
||||
*/
|
||||
MessageResponse andAssertBodyContains(String substring);
|
||||
|
||||
/**
|
||||
* Extracts a value from the message.
|
||||
*
|
||||
* @param path the path expression
|
||||
* @return JsonPathValue for further assertion
|
||||
*/
|
||||
JsonPathValue extract(String path);
|
||||
|
||||
/**
|
||||
* Deserializes the message body into a Java object.
|
||||
*
|
||||
* @param type the target class
|
||||
* @param <T> the target type
|
||||
* @return the deserialized object
|
||||
*/
|
||||
<T> T mapTo(Class<T> type);
|
||||
|
||||
/**
|
||||
* Returns the received message.
|
||||
*
|
||||
* @return the message
|
||||
*/
|
||||
ReceivedMessage getMessage();
|
||||
|
||||
/**
|
||||
* Returns the message body.
|
||||
*
|
||||
* @return the body
|
||||
*/
|
||||
String getBody();
|
||||
|
||||
/**
|
||||
* Returns a header value.
|
||||
*
|
||||
* @param name the header name
|
||||
* @return the header value or null
|
||||
*/
|
||||
String getHeader(String name);
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package cz.moneta.test.harness.support.messaging;
|
||||
|
||||
/**
|
||||
* Message format for IBM MQ messages.
|
||||
*/
|
||||
public enum MqMessageFormat {
|
||||
/**
|
||||
* JSON format - JMS TextMessage with plain JSON string (UTF-8 default)
|
||||
*/
|
||||
JSON,
|
||||
/**
|
||||
* XML format - JMS TextMessage with XML string (UTF-8 default)
|
||||
*/
|
||||
XML,
|
||||
/**
|
||||
* EBCDIC format - JMS BytesMessage with EBCDIC IBM-870 encoding (CZ/SK mainframe)
|
||||
*/
|
||||
EBCDIC_870,
|
||||
/**
|
||||
* UTF-8 format - JMS BytesMessage with UTF-8 IBM CCSID 1208 encoding
|
||||
*/
|
||||
UTF8_1208
|
||||
}
|
||||
@ -0,0 +1,304 @@
|
||||
package cz.moneta.test.harness.support.messaging;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/**
|
||||
* Represents a received message from a messaging system (IBM MQ or Kafka).
|
||||
* <p>
|
||||
* Provides unified API for accessing message content regardless of source system.
|
||||
* Body is always normalized to a String, with content type detection for proper extraction.
|
||||
* </p>
|
||||
*/
|
||||
public class ReceivedMessage {
|
||||
|
||||
private static final ObjectMapper JSON_MAPPER = new ObjectMapper();
|
||||
private static final XmlMapper XML_MAPPER = new XmlMapper();
|
||||
|
||||
private final String body;
|
||||
private final MessageContentType contentType;
|
||||
private final Map<String, String> headers;
|
||||
private final long timestamp;
|
||||
private final String source;
|
||||
private final String key;
|
||||
|
||||
private ReceivedMessage(Builder builder) {
|
||||
this.body = builder.body;
|
||||
this.contentType = builder.contentType;
|
||||
this.headers = builder.headers != null ? Collections.unmodifiableMap(new HashMap<>(builder.headers)) : Collections.emptyMap();
|
||||
this.timestamp = builder.timestamp;
|
||||
this.source = builder.source;
|
||||
this.key = builder.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new builder for ReceivedMessage.
|
||||
*/
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a value from the message body using JSON dot-path or bracket notation.
|
||||
* <p>
|
||||
* Supports paths like:
|
||||
* <ul>
|
||||
* <li>{@code "field"} - top-level field</li>
|
||||
* <li>{@code "parent.child"} - nested field</li>
|
||||
* <li>{@code "items[0]"} - array element</li>
|
||||
* <li>{@code "items[0].name"} - nested field in array element</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param path the JSON path expression
|
||||
* @return the extracted value as JsonNode
|
||||
*/
|
||||
public JsonNode extractJson(String path) {
|
||||
if (contentType != MessageContentType.JSON) {
|
||||
throw new IllegalStateException("JSON extraction is only supported for JSON content type, got: " + contentType);
|
||||
}
|
||||
try {
|
||||
JsonNode rootNode = JSON_MAPPER.readTree(body);
|
||||
return extractNode(path, rootNode);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to parse JSON body: " + body, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a value from XML message body using XPath expression.
|
||||
*
|
||||
* @param xpath the XPath expression
|
||||
* @return the extracted value as String
|
||||
*/
|
||||
public String extractXml(String xpath) {
|
||||
if (contentType != MessageContentType.XML) {
|
||||
throw new IllegalStateException("XML extraction is only supported for XML content type, got: " + contentType);
|
||||
}
|
||||
try {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
|
||||
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
|
||||
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
Document doc = builder.parse(new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8)));
|
||||
XPath xPath = XPathFactory.newInstance().newXPath();
|
||||
return xPath.evaluate(xpath, doc);
|
||||
} catch (XPathExpressionException e) {
|
||||
throw new RuntimeException("Failed to evaluate XPath: " + xpath, e);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to parse XML body: " + body, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a value from the message body. Auto-detects content type and uses appropriate extraction method.
|
||||
*
|
||||
* @param expression the path expression (JSON path for JSON, XPath for XML)
|
||||
* @return the extracted value as String
|
||||
*/
|
||||
public String extract(String expression) {
|
||||
return switch (contentType) {
|
||||
case JSON -> extractJson(expression).asText();
|
||||
case XML -> extractXml(expression);
|
||||
case RAW_TEXT -> body;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message body as a String.
|
||||
*
|
||||
* @return the body content
|
||||
*/
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message content type.
|
||||
*
|
||||
* @return the content type
|
||||
*/
|
||||
public MessageContentType getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a header value by name.
|
||||
*
|
||||
* @param name the header name
|
||||
* @return the header value, or null if not present
|
||||
*/
|
||||
public String getHeader(String name) {
|
||||
return headers.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all headers.
|
||||
*
|
||||
* @return unmodifiable map of headers
|
||||
*/
|
||||
public Map<String, String> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message timestamp.
|
||||
*
|
||||
* @return timestamp in milliseconds
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source (topic name for Kafka, queue name for IBM MQ).
|
||||
*
|
||||
* @return the source name
|
||||
*/
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message key (Kafka only, null for IBM MQ).
|
||||
*
|
||||
* @return the message key or null
|
||||
*/
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the message body into a Java object.
|
||||
* <p>
|
||||
* For JSON content: uses Jackson ObjectMapper.readValue
|
||||
* For XML content: uses Jackson XmlMapper
|
||||
* </p>
|
||||
*
|
||||
* @param type the target class
|
||||
* @param <T> the target type
|
||||
* @return the deserialized object
|
||||
*/
|
||||
public <T> T mapTo(Class<T> type) {
|
||||
try {
|
||||
if (contentType == MessageContentType.XML) {
|
||||
return XML_MAPPER.readValue(body, type);
|
||||
} else {
|
||||
return JSON_MAPPER.readValue(body, type);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Failed to deserialize message body to " + type.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for ReceivedMessage.
|
||||
*/
|
||||
public static class Builder {
|
||||
private String body;
|
||||
private MessageContentType contentType = MessageContentType.JSON;
|
||||
private Map<String, String> headers;
|
||||
private long timestamp = System.currentTimeMillis();
|
||||
private String source;
|
||||
private String key;
|
||||
|
||||
public Builder body(String body) {
|
||||
this.body = body;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder contentType(MessageContentType contentType) {
|
||||
this.contentType = contentType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder headers(Map<String, String> headers) {
|
||||
this.headers = headers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder timestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder source(String source) {
|
||||
this.source = source;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder key(String key) {
|
||||
this.key = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReceivedMessage build() {
|
||||
return new ReceivedMessage(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a node from JSON using dot/bracket notation.
|
||||
*/
|
||||
private static JsonNode extractNode(String path, JsonNode rootNode) {
|
||||
Pattern arrayPattern = Pattern.compile("(.*?)\\[([0-9]+)\\]");
|
||||
return Arrays.stream(path.split("\\."))
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.reduce(rootNode,
|
||||
(node, part) -> {
|
||||
Matcher matcher = arrayPattern.matcher(part);
|
||||
if (matcher.find()) {
|
||||
return node.path(matcher.group(1)).path(Integer.parseInt(matcher.group(2)));
|
||||
} else {
|
||||
return node.path(part);
|
||||
}
|
||||
},
|
||||
(n1, n2) -> n1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a cz.moneta.test.harness.messaging.ReceivedMessage to this class.
|
||||
*
|
||||
* @param other the message to convert
|
||||
* @return converted message
|
||||
*/
|
||||
public static ReceivedMessage fromMessagingReceivedMessage(
|
||||
cz.moneta.test.harness.messaging.ReceivedMessage other) {
|
||||
if (other == null) {
|
||||
return null;
|
||||
}
|
||||
cz.moneta.test.harness.support.messaging.MessageContentType contentType =
|
||||
switch (other.getContentType()) {
|
||||
case JSON -> cz.moneta.test.harness.support.messaging.MessageContentType.JSON;
|
||||
case XML -> cz.moneta.test.harness.support.messaging.MessageContentType.XML;
|
||||
case RAW_TEXT -> cz.moneta.test.harness.support.messaging.MessageContentType.RAW_TEXT;
|
||||
};
|
||||
return builder()
|
||||
.body(other.getBody())
|
||||
.contentType(contentType)
|
||||
.headers(other.getHeaders())
|
||||
.timestamp(other.getTimestamp())
|
||||
.source(other.getSource())
|
||||
.key(other.getKey())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,7 @@
|
||||
<artifactId>tests</artifactId>
|
||||
<version>2.29-SNAPSHOT</version>
|
||||
<properties>
|
||||
<harness.version>7.55.820</harness.version>
|
||||
<harness.version>7.55-SNAPSHOT</harness.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<junit.platform.version>1.5.1</junit.platform.version>
|
||||
</properties>
|
||||
@ -15,6 +15,7 @@
|
||||
<groupId>cz.moneta.test</groupId>
|
||||
<artifactId>harness</artifactId>
|
||||
<version>${harness.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
|
||||
@ -23,6 +23,7 @@ import cz.moneta.test.dsl.greenscreen.GreenScreen;
|
||||
import cz.moneta.test.dsl.hypos.Hypos;
|
||||
import cz.moneta.test.dsl.ib.Ib;
|
||||
import cz.moneta.test.dsl.ilods.Ilods;
|
||||
import cz.moneta.test.dsl.imq.ImqFirstVision;
|
||||
import cz.moneta.test.dsl.kasanova.Kasanova;
|
||||
import cz.moneta.test.dsl.mobile.smartbanking.home.Sb;
|
||||
import cz.moneta.test.dsl.monetaapiportal.MonetaApiPortal;
|
||||
@ -282,6 +283,10 @@ public class Harness extends BaseStoreAccessor {
|
||||
return new Cashman(this);
|
||||
}
|
||||
|
||||
public ImqFirstVision withImqFirstVision() {
|
||||
return new ImqFirstVision(this);
|
||||
}
|
||||
|
||||
private void initGenerators() {
|
||||
addGenerator(RC, new RcGenerator());
|
||||
addGenerator(FIRST_NAME, new FirstNameGenerator());
|
||||
|
||||
187
tests/src/main/java/cz/moneta/test/dsl/imq/ImqFirstVision.java
Normal file
187
tests/src/main/java/cz/moneta/test/dsl/imq/ImqFirstVision.java
Normal file
@ -0,0 +1,187 @@
|
||||
package cz.moneta.test.dsl.imq;
|
||||
|
||||
import cz.moneta.test.dsl.Harness;
|
||||
import cz.moneta.test.harness.endpoints.imq.ImqFirstVisionEndpoint;
|
||||
import cz.moneta.test.harness.endpoints.imq.ImqFirstVisionQueue;
|
||||
import cz.moneta.test.harness.messaging.ReceivedMessage;
|
||||
import cz.moneta.test.harness.messaging.exception.MessagingTimeoutException;
|
||||
import cz.moneta.test.harness.support.messaging.ImqRequest;
|
||||
import cz.moneta.test.harness.messaging.MqMessageFormat;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* IBM MQ First Vision DSL.
|
||||
* <p>
|
||||
* Usage example:
|
||||
* <pre>{@code
|
||||
* harness.withImqFirstVision()
|
||||
* .toQueue(ImqFirstVisionQueue.PAYMENT_NOTIFICATIONS)
|
||||
* .withPayload("{\"paymentId\": \"PAY-123\"}")
|
||||
* .send();
|
||||
*
|
||||
* harness.withImqFirstVision()
|
||||
* .fromQueue(ImqFirstVisionQueue.PAYMENT_NOTIFICATIONS)
|
||||
* .receiveWhere(msg -> msg.extract("paymentId").equals("PAY-123"))
|
||||
* .withTimeout(10, TimeUnit.SECONDS)
|
||||
* .andAssertFieldValue("result", "OK");
|
||||
* }</pre>
|
||||
* </p>
|
||||
*/
|
||||
public class ImqFirstVision {
|
||||
|
||||
private final Harness harness;
|
||||
|
||||
public ImqFirstVision(Harness harness) {
|
||||
this.harness = harness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start building a message to send to a queue.
|
||||
*/
|
||||
public ImqRequest.QueuePhase toQueue(ImqFirstVisionQueue queue) {
|
||||
ImqFirstVisionEndpoint endpoint = harness.getEndpoint(ImqFirstVisionEndpoint.class);
|
||||
return ImqRequest.toQueue(endpoint, queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start building a message to receive from a queue.
|
||||
*/
|
||||
public ImqRequest.ReceivePhase fromQueue(ImqFirstVisionQueue queue) {
|
||||
ImqFirstVisionEndpoint endpoint = harness.getEndpoint(ImqFirstVisionEndpoint.class);
|
||||
return ImqRequest.fromQueue(endpoint, queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a JSON message to a queue.
|
||||
*/
|
||||
public void sendToQueue(ImqFirstVisionQueue queue, String payload) {
|
||||
sendToQueue(queue, payload, MqMessageFormat.JSON, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a queue with specified format.
|
||||
*/
|
||||
public void sendToQueue(ImqFirstVisionQueue queue, String payload, MqMessageFormat format) {
|
||||
sendToQueue(queue, payload, format, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a queue with specified format and properties.
|
||||
*/
|
||||
public void sendToQueue(ImqFirstVisionQueue queue, String payload, MqMessageFormat format,
|
||||
Map<String, String> properties) {
|
||||
ImqFirstVisionEndpoint endpoint = harness.getEndpoint(ImqFirstVisionEndpoint.class);
|
||||
endpoint.send(queue, payload, format, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a JSON message to a queue by physical name.
|
||||
*/
|
||||
public void sendToQueue(String queueName, String payload) {
|
||||
sendToQueue(queueName, payload, MqMessageFormat.JSON, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a queue by physical name with specified format.
|
||||
*/
|
||||
public void sendToQueue(String queueName, String payload, MqMessageFormat format) {
|
||||
sendToQueue(queueName, payload, format, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message to a queue by physical name with specified format and properties.
|
||||
*/
|
||||
public void sendToQueue(String queueName, String payload, MqMessageFormat format,
|
||||
Map<String, String> properties) {
|
||||
ImqFirstVisionEndpoint endpoint = harness.getEndpoint(ImqFirstVisionEndpoint.class);
|
||||
endpoint.send(queueName, payload, format, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a message from a queue with timeout.
|
||||
*/
|
||||
public ReceivedMessage receiveFromQueue(ImqFirstVisionQueue queue, Duration timeout) {
|
||||
return receiveFromQueue(queue, null, MqMessageFormat.JSON, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a message from a queue with selector and timeout.
|
||||
*/
|
||||
public ReceivedMessage receiveFromQueue(ImqFirstVisionQueue queue, String selector, Duration timeout) {
|
||||
return receiveFromQueue(queue, selector, MqMessageFormat.JSON, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a message from a queue with format and timeout.
|
||||
*/
|
||||
public ReceivedMessage receiveFromQueue(ImqFirstVisionQueue queue, MqMessageFormat format, Duration timeout) {
|
||||
return receiveFromQueue(queue, null, format, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a message from a queue with selector, format and timeout.
|
||||
*/
|
||||
public ReceivedMessage receiveFromQueue(ImqFirstVisionQueue queue, String selector,
|
||||
MqMessageFormat format, Duration timeout) {
|
||||
ImqFirstVisionEndpoint endpoint = harness.getEndpoint(ImqFirstVisionEndpoint.class);
|
||||
return endpoint.receive(queue, selector, format, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a message matching predicate from a queue.
|
||||
*/
|
||||
public ReceivedMessage receiveFromQueue(ImqFirstVisionQueue queue, Predicate<ReceivedMessage> filter,
|
||||
Duration timeout) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
long timeoutMs = timeout.toMillis();
|
||||
|
||||
while (System.currentTimeMillis() - startTime < timeoutMs) {
|
||||
try {
|
||||
ReceivedMessage message = receiveFromQueue(queue, MqMessageFormat.JSON, Duration.ofSeconds(1));
|
||||
if (filter.test(message)) {
|
||||
return message;
|
||||
}
|
||||
} catch (MessagingTimeoutException e) {
|
||||
// Continue polling
|
||||
}
|
||||
}
|
||||
|
||||
throw new MessagingTimeoutException(
|
||||
"No message matching filter found on queue '" + queue.getConfigKey() +
|
||||
"' within " + timeout.toMillis() + "ms");
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse messages from a queue (non-destructive).
|
||||
*/
|
||||
public List<ReceivedMessage> browseQueue(ImqFirstVisionQueue queue, int maxMessages) {
|
||||
return browseQueue(queue, null, MqMessageFormat.JSON, maxMessages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse messages from a queue with selector (non-destructive).
|
||||
*/
|
||||
public List<ReceivedMessage> browseQueue(ImqFirstVisionQueue queue, String selector, int maxMessages) {
|
||||
return browseQueue(queue, selector, MqMessageFormat.JSON, maxMessages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse messages from a queue with format and max count (non-destructive).
|
||||
*/
|
||||
public List<ReceivedMessage> browseQueue(ImqFirstVisionQueue queue, MqMessageFormat format, int maxMessages) {
|
||||
return browseQueue(queue, null, format, maxMessages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse messages from a queue with selector, format and max count (non-destructive).
|
||||
*/
|
||||
public List<ReceivedMessage> browseQueue(ImqFirstVisionQueue queue, String selector,
|
||||
MqMessageFormat format, int maxMessages) {
|
||||
ImqFirstVisionEndpoint endpoint = harness.getEndpoint(ImqFirstVisionEndpoint.class);
|
||||
return endpoint.browse(queue, selector, format, maxMessages);
|
||||
}
|
||||
}
|
||||
@ -76,4 +76,21 @@ endpoints.szr-mock-api.url=https://api-szr.ppe.moneta-containers.net
|
||||
endpoints.forte.url=https://forteppe.ux.mbid.cz/portal/home/
|
||||
|
||||
#Exevido
|
||||
endpoints.exevido.url=https://exevido.ppe.moneta-containers.net/#/auth/login
|
||||
endpoints.exevido.url=https://exevido.ppe.moneta-containers.net/#/auth/login
|
||||
|
||||
#IBM MQ First Vision
|
||||
endpoints.imq-first-vision.connection-name-list=mq9multipe5x(1414),mq9multipe6x(1414)
|
||||
endpoints.imq-first-vision.channel=CLIENT.CHANNEL
|
||||
endpoints.imq-first-vision.queue-manager=MVSW2PPE
|
||||
endpoints.imq-first-vision.ssl-cipher-suite=TLS_RSA_WITH_AES_256_CBC_SHA256
|
||||
|
||||
#IBM MQ queues
|
||||
endpoints.imq-first-vision.payment-notifications.queue=MVSW2PPE.DELIVERY.NOTIFICATION
|
||||
endpoints.imq-first-vision.payment-request.queue=MVSW2PPE.DELIVERY.REQUEST
|
||||
endpoints.imq-first-vision.mf-requests.queue=MVSW2PPE.MF.REQUESTS
|
||||
endpoints.imq-first-vision.mf-responses.queue=MVSW2PPE.MF.RESPONSES
|
||||
endpoints.imq-first-vision.mf-ebcdic.queue=MVSW2PPE.MF.EBCDIC
|
||||
endpoints.imq-first-vision.mf-utf8.queue=MVSW2PPE.MF.UTF8
|
||||
|
||||
#Vault path for IBM MQ credentials
|
||||
vault.imq-first-vision.secrets.path=/kv/autotesty/ppe/imq-first-vision
|
||||
@ -97,4 +97,21 @@ endpoints.szr-mock-api.url=https://api-szr.tst.moneta-containers.net
|
||||
endpoints.exevido.url=https://exevido.tst.moneta-containers.net/#/auth/login
|
||||
|
||||
#Cashman
|
||||
endpoints.cashman.url=https://cashmantst.mbid.cz/
|
||||
endpoints.cashman.url=https://cashmantst.mbid.cz/
|
||||
|
||||
#IBM MQ First Vision
|
||||
endpoints.imq-first-vision.connection-name-list=mq9multitst5x(1414),mq9multitst6x(1414)
|
||||
endpoints.imq-first-vision.channel=CLIENT.CHANNEL
|
||||
endpoints.imq-first-vision.queue-manager=MVSW2TST3
|
||||
endpoints.imq-first-vision.ssl-cipher-suite=TLS_RSA_WITH_AES_256_CBC_SHA256
|
||||
|
||||
#IBM MQ queues
|
||||
endpoints.imq-first-vision.payment-notifications.queue=MVSW2TST3.DELIVERY.NOTIFICATION
|
||||
endpoints.imq-first-vision.payment-request.queue=MVSW2TST3.DELIVERY.REQUEST
|
||||
endpoints.imq-first-vision.mf-requests.queue=MVSW2TST3.MF.REQUESTS
|
||||
endpoints.imq-first-vision.mf-responses.queue=MVSW2TST3.MF.RESPONSES
|
||||
endpoints.imq-first-vision.mf-ebcdic.queue=MVSW2TST3.MF.EBCDIC
|
||||
endpoints.imq-first-vision.mf-utf8.queue=MVSW2TST3.MF.UTF8
|
||||
|
||||
#Vault path for IBM MQ credentials
|
||||
vault.imq-first-vision.secrets.path=/kv/autotesty/tst1/imq-first-vision
|
||||
Loading…
x
Reference in New Issue
Block a user